diff --git a/AKModel/locale/de_DE/LC_MESSAGES/django.po b/AKModel/locale/de_DE/LC_MESSAGES/django.po
index 0b7afd2a2a67ec35f361cb7c263b825600052831..30f6450705afb096ce15c50b156fc88a4b255615 100644
--- a/AKModel/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKModel/locale/de_DE/LC_MESSAGES/django.po
@@ -466,6 +466,38 @@ msgstr ""
 msgid "Events"
 msgstr "Events"
 
+#: AKModel/models.py:430
+#, python-brace-format
+msgid "AK {ak_name} is not assigned any timeslot by the solver"
+msgstr "Dem AK {ak_name} wurde vom Solver kein Zeitslot zugewiesen"
+
+#: AKModel/models.py:440
+#, python-brace-format
+msgid ""
+"Duration of AK {ak_name} assigned by solver ({solver_duration} hours) is "
+"less than the duration required by the slot ({slot_duration} hours)"
+msgstr ""
+"Die dem AK {ak_name} vom Solver zugewiesene Dauer ({solver_duration} Stunden) ist "
+"kürzer als die aktuell vorgesehene Dauer des Slots ({slot_duration} Stunden)"
+
+#: AKModel/models.py:454
+#, python-brace-format
+msgid ""
+"Fixed AK {ak_name} assigned by solver to room {solver_room} is fixed to room "
+"{slot_room}"
+msgstr ""
+"Dem fix geplanten AK {ak_name} wurde vom Solver Raum {solver_room} zugewiesen, "
+"dabei ist der AK bereits fix in Raum {slot_room} eingeplant."
+
+#: AKModel/models.py:465
+#, python-brace-format
+msgid ""
+"Fixed AK {ak_name} assigned by solver to start at {solver_start} is fixed to "
+"start at {slot_start}"
+msgstr ""
+"Dem fix geplanten AK {ak_name} wurde vom Solver die Startzeit {solver_start} zugewiesen, "
+"dabei ist der AK bereits für {slot_start} eingeplant."
+
 #: AKModel/models.py:180
 msgid "Nickname"
 msgstr "Spitzname"
@@ -981,7 +1013,7 @@ msgstr "Primäre Kategorien"
 msgid "Categories that should be assigned to this slot primarily"
 msgstr "Kategorieren, die diesem Slot primär zugewiesen werden sollen"
 
-#: AKModel/site.py:14
+#: AKModel/site.py:13 AKModel/site.py:14
 msgid "Administration"
 msgstr "Verwaltung"
 
@@ -1326,6 +1358,15 @@ msgstr ""
 msgid "AK Schedule JSON Import"
 msgstr "AK-Plan JSON-Import"
 
+#: AKModel/views/manage.py:265
+#, python-brace-format
+msgid "Successfully imported {n} slot(s)"
+msgstr "Erfolgreich {n} Slot(s) importiert"
+
+#: AKModel/views/manage.py:271
+msgid "Importing an AK schedule failed! Reason: "
+msgstr "AK-Plan importieren fehlgeschlagen! Grund: "
+
 #: AKModel/views/room.py:37
 #, python-format
 msgid "Created Room '%(room)s'"
diff --git a/AKModel/models.py b/AKModel/models.py
index 35bc22352bea2cd4e409e8eddf14b29f2cdb2d87..25c6b9c587152e8a3ca057b6daf014f4fbb01a9a 100644
--- a/AKModel/models.py
+++ b/AKModel/models.py
@@ -8,7 +8,7 @@ from typing import Iterable, Generator
 
 from django.core.validators import RegexValidator
 from django.apps import apps
-from django.db import models
+from django.db import models, transaction
 from django.db.models import Count
 from django.urls import reverse_lazy
 from django.utils import timezone
@@ -413,7 +413,8 @@ class Event(models.Model):
         else:
             yield from self.uniform_time_slots(slots_in_an_hour=slots_in_an_hour)
 
-    def schedule_from_json(self, schedule: str) -> None:
+    @transaction.atomic
+    def schedule_from_json(self, schedule: str) -> int:
         """Load AK schedule from a json string.
 
         :param schedule: A string that can be decoded to json, describing
@@ -431,18 +432,63 @@ class Event(models.Model):
             for timeslot in block
         }
 
+        slots_updated = 0
         for scheduled_slot in schedule["scheduled_aks"]:
+            scheduled_slot["timeslot_ids"] = list(map(int, scheduled_slot["timeslot_ids"]))
             slot = AKSlot.objects.get(id=int(scheduled_slot["ak_id"]))
-            slot.room = Room.objects.get(id=int(scheduled_slot["room_id"]))
 
-            scheduled_slot["timeslot_ids"] = list(map(int, scheduled_slot["timeslot_ids"]))
+            if not scheduled_slot["timeslot_ids"]:
+                raise ValueError(
+                    _("AK {ak_name} is not assigned any timeslot by the solver").format(ak_name=slot.ak.name)
+                )
 
             start_timeslot = timeslot_dict[min(scheduled_slot["timeslot_ids"])].avail
             end_timeslot = timeslot_dict[max(scheduled_slot["timeslot_ids"])].avail
+            solver_duration = (end_timeslot.end - start_timeslot.start).total_seconds() / 3600.0
+
+            if solver_duration + 2e-4 < slot.duration:
+                raise ValueError(
+                    _(
+                        "Duration of AK {ak_name} assigned by solver ({solver_duration} hours) "
+                        "is less than the duration required by the slot ({slot_duration} hours)"
+                    ).format(
+                        ak_name=slot.ak.name,
+                        solver_duration=solver_duration,
+                        slot_duration=slot.duration,
+                    )
+                )
+
+            if slot.fixed:
+                solver_room = Room.objects.get(id=int(scheduled_slot["room_id"]))
+                if slot.room != solver_room:
+                    raise ValueError(
+                        _(
+                            "Fixed AK {ak_name} assigned by solver to room {solver_room} "
+                            "is fixed to room {slot_room}"
+                        ).format(
+                            ak_name=slot.ak.name,
+                            solver_room=solver_room.name,
+                            slot_room=slot.room.name,
+                        )
+                    )
+                if slot.start != start_timeslot.start:
+                    raise ValueError(
+                        _(
+                            "Fixed AK {ak_name} assigned by solver to start at {solver_start} "
+                            "is fixed to start at {slot_start}"
+                        ).format(
+                            ak_name=slot.ak.name,
+                            solver_start=start_timeslot.start,
+                            slot_start=slot.start,
+                        )
+                    )
+            else:
+                slot.room = Room.objects.get(id=int(scheduled_slot["room_id"]))
+                slot.start = start_timeslot.start
+                slot.save()
+                slots_updated += 1
 
-            slot.start = start_timeslot.start
-            slot.duration = (end_timeslot.end - start_timeslot.start).total_seconds() / 3600.0
-            slot.save()
+        return slots_updated
 
 class AKOwner(models.Model):
     """ An AKOwner describes the person organizing/holding an AK.
diff --git a/AKModel/views/manage.py b/AKModel/views/manage.py
index 1bad9534efd6fe81fa70ebf30fbdf84aad476967..3acb05fd29a6e91cd17f45e9ed43d889a67da22c 100644
--- a/AKModel/views/manage.py
+++ b/AKModel/views/manage.py
@@ -257,6 +257,18 @@ class AKScheduleJSONImportView(EventSlugMixin, IntermediateAdminView):
     title = _("AK Schedule JSON Import")
 
     def form_valid(self, form):
-        self.event.schedule_from_json(form.data["json_data"])
+        try:
+            number_of_slots_changed = self.event.schedule_from_json(form.data["json_data"])
+            messages.add_message(
+                self.request,
+                messages.SUCCESS,
+                _("Successfully imported {n} slot(s)").format(n=number_of_slots_changed)
+            )
+        except ValueError as ex:
+            messages.add_message(
+                self.request,
+                messages.ERROR,
+                _("Importing an AK schedule failed! Reason: ") + str(ex),
+            )
 
         return redirect("admin:event_status", self.event.slug)
diff --git a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
index e66d8d55bcda42f3271b2400d6b98cf84f64ee1d..1e391c1fa08573165d8d02636ffd40027437b583 100644
--- a/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKScheduling/locale/de_DE/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-04-25 00:24+0200\n"
+"POT-Creation-Date: 2025-01-22 19:00+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -27,7 +27,7 @@ msgstr "Ende"
 
 #: AKScheduling/forms.py:26
 msgid "Duration"
-msgstr ""
+msgstr "Dauer"
 
 #: AKScheduling/forms.py:27
 #: AKScheduling/templates/admin/AKScheduling/scheduling.html:171
@@ -107,6 +107,7 @@ msgid "Event Status"
 msgstr "Event-Status"
 
 #: AKScheduling/templates/admin/AKScheduling/constraint_violations.html:113
+#: AKScheduling/views.py:48
 msgid "Scheduling"
 msgstr "Scheduling"
 
@@ -239,6 +240,7 @@ msgstr[1] ""
 "        "
 
 #: AKScheduling/templates/admin/AKScheduling/unscheduled.html:7
+#: AKScheduling/views.py:25
 msgid "Unscheduled AK Slots"
 msgstr "Noch nicht geschedulte AK-Slots"
 
@@ -246,10 +248,22 @@ msgstr "Noch nicht geschedulte AK-Slots"
 msgid "Count"
 msgstr "Anzahl"
 
+#: AKScheduling/views.py:89
+msgid "Constraint violations for"
+msgstr "Constraintverletzungen für"
+
+#: AKScheduling/views.py:104
+msgid "AKs requiring special attention for"
+msgstr "AKs die besondere Aufmerksamkeit erfordern für"
+
 #: AKScheduling/views.py:150
 msgid "Interest updated"
 msgstr "Interesse aktualisiert"
 
+#: AKScheduling/views.py:157
+msgid "Enter interest"
+msgstr "Interesse eingeben"
+
 #: AKScheduling/views.py:201
 msgid "Wishes"
 msgstr "Wünsche"
diff --git a/AKSubmission/locale/de_DE/LC_MESSAGES/django.po b/AKSubmission/locale/de_DE/LC_MESSAGES/django.po
index d395dfbc7a63f2af496babc33056210d375cff4d..1d21dff1bde7a9e89ec7fb877a30c7cd311a10e4 100644
--- a/AKSubmission/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKSubmission/locale/de_DE/LC_MESSAGES/django.po
@@ -420,7 +420,11 @@ msgstr ""
 msgid "Currently planned AKs"
 msgstr "Aktuell geplante AKs"
 
-#: AKSubmission/views.py:305
+#: AKSubmission/views.py:231
+msgid "AKs with Track"
+msgstr "AK mit Track"
+
+#: AKSubmission/views.py:300
 msgid "Event inactive. Cannot create or update."
 msgstr "Event inaktiv. Hinzufügen/Bearbeiten nicht möglich."