diff --git a/api/funkwhale_api/music/migrations/0020_importbatch_status.py b/api/funkwhale_api/music/migrations/0020_importbatch_status.py
new file mode 100644
index 0000000000000000000000000000000000000000..265d1ba5d5312d086f25d0861039b3a94a5df4e5
--- /dev/null
+++ b/api/funkwhale_api/music/migrations/0020_importbatch_status.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.0.2 on 2018-02-20 19:12
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('music', '0019_populate_mimetypes'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='importbatch',
+            name='status',
+            field=models.CharField(choices=[('pending', 'Pending'), ('finished', 'Finished'), ('errored', 'Errored'), ('skipped', 'Skipped')], default='pending', max_length=30),
+        ),
+    ]
diff --git a/api/funkwhale_api/music/migrations/0021_populate_batch_status.py b/api/funkwhale_api/music/migrations/0021_populate_batch_status.py
new file mode 100644
index 0000000000000000000000000000000000000000..061d649b06115d4871b6c6eb7ae57b25c27661e8
--- /dev/null
+++ b/api/funkwhale_api/music/migrations/0021_populate_batch_status.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+import os
+
+from django.db import migrations, models
+
+
+def populate_status(apps, schema_editor):
+    from funkwhale_api.music.utils import compute_status
+    ImportBatch = apps.get_model("music", "ImportBatch")
+
+    for ib in ImportBatch.objects.prefetch_related('jobs'):
+        ib.status = compute_status(ib.jobs.all())
+        ib.save(update_fields=['status'])
+
+
+def rewind(apps, schema_editor):
+    pass
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('music', '0020_importbatch_status'),
+    ]
+
+    operations = [
+        migrations.RunPython(populate_status, rewind),
+    ]
diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index 3ebd07419e6d0fc35608fd4e63f7c2b990e83657..3c6f601652d260ab9dc7328e353ddf662ce80b50 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -10,8 +10,11 @@ from django.conf import settings
 from django.db import models
 from django.core.files.base import ContentFile
 from django.core.files import File
+from django.db.models.signals import post_save
+from django.dispatch import receiver
 from django.urls import reverse
 from django.utils import timezone
+
 from taggit.managers import TaggableManager
 from versatileimagefield.fields import VersatileImageField
 
@@ -400,6 +403,14 @@ class TrackFile(models.Model):
             self.mimetype = utils.guess_mimetype(self.audio_file)
         return super().save(**kwargs)
 
+
+IMPORT_STATUS_CHOICES = (
+    ('pending', 'Pending'),
+    ('finished', 'Finished'),
+    ('errored', 'Errored'),
+    ('skipped', 'Skipped'),
+)
+
 class ImportBatch(models.Model):
     IMPORT_BATCH_SOURCES = [
         ('api', 'api'),
@@ -412,22 +423,24 @@ class ImportBatch(models.Model):
         'users.User',
         related_name='imports',
         on_delete=models.CASCADE)
-
+    status = models.CharField(
+        choices=IMPORT_STATUS_CHOICES, default='pending', max_length=30)
+    import_request = models.ForeignKey(
+        'requests.ImportRequest',
+        related_name='import_batches',
+        null=True,
+        blank=True,
+        on_delete=models.CASCADE)
     class Meta:
         ordering = ['-creation_date']
 
     def __str__(self):
         return str(self.pk)
 
-    @property
-    def status(self):
-        pending = any([job.status == 'pending' for job in self.jobs.all()])
-        errored = any([job.status == 'errored' for job in self.jobs.all()])
-        if pending:
-            return 'pending'
-        if errored:
-            return 'errored'
-        return 'finished'
+    def update_status(self):
+        self.status = utils.compute_status(self.jobs.all())
+        self.save(update_fields=['status'])
+
 
 class ImportJob(models.Model):
     batch = models.ForeignKey(
@@ -440,13 +453,9 @@ class ImportJob(models.Model):
         on_delete=models.CASCADE)
     source = models.CharField(max_length=500)
     mbid = models.UUIDField(editable=False, null=True, blank=True)
-    STATUS_CHOICES = (
-        ('pending', 'Pending'),
-        ('finished', 'Finished'),
-        ('errored', 'Errored'),
-        ('skipped', 'Skipped'),
-    )
-    status = models.CharField(choices=STATUS_CHOICES, default='pending', max_length=30)
+
+    status = models.CharField(
+        choices=IMPORT_STATUS_CHOICES, default='pending', max_length=30)
     audio_file = models.FileField(
         upload_to='imports/%Y/%m/%d', max_length=255, null=True, blank=True)
 
diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py
index 0e4318e563ee5341e0d8b9d0aa32291eea867e7a..a75cf5de8508efaa5df587eb17b01a2e87f1214f 100644
--- a/api/funkwhale_api/music/utils.py
+++ b/api/funkwhale_api/music/utils.py
@@ -43,3 +43,13 @@ def get_query(query_string, search_fields):
 def guess_mimetype(f):
     b = min(100000, f.size)
     return magic.from_buffer(f.read(b), mime=True)
+
+
+def compute_status(jobs):
+    errored = any([job.status == 'errored' for job in jobs])
+    if errored:
+        return 'errored'
+    pending = any([job.status == 'pending' for job in jobs])
+    if pending:
+        return 'pending'
+    return 'finished'
diff --git a/api/tests/music/test_models.py b/api/tests/music/test_models.py
index 2eb1f276332fc32bcd01e947fac72c3774cfaea8..9f52ba8874e50c10ea0216cacc8363ab767d6396 100644
--- a/api/tests/music/test_models.py
+++ b/api/tests/music/test_models.py
@@ -52,6 +52,20 @@ def test_import_job_is_bound_to_track_file(factories, mocker):
     job.refresh_from_db()
     assert job.track_file.track == track
 
+
+@pytest.mark.parametrize('status', ['pending', 'errored', 'finished'])
+def test_saving_job_updates_batch_status(status,factories, mocker):
+    batch = factories['music.ImportBatch']()
+
+    assert batch.status == 'pending'
+
+    job = factories['music.ImportJob'](batch=batch, status=status)
+
+    batch.refresh_from_db()
+
+    assert batch.status == status
+
+
 @pytest.mark.parametrize('extention,mimetype', [
     ('ogg', 'audio/ogg'),
     ('mp3', 'audio/mpeg'),