diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/participationStatus.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/absences/participationStatus.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..e752326355ae38fb4efcd7a999de0760b2198069
--- /dev/null
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/participationStatus.graphql
@@ -0,0 +1,18 @@
+mutation updateParticipationStatuses(
+  $input: [BatchPatchParticipationStatusInput]!
+) {
+  updateParticipationStatuses(input: $input) {
+    items: participationStatuses {
+      id
+      isOptimistic
+      relatedDocumentation {
+        id
+      }
+      absenceReason {
+        id
+        name
+        shortName
+      }
+    }
+  }
+}
diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql
index dc5c55f1a0f2ecebfa6fbc8157f412d889ef0ac0..83a6a459f8bb79a57647e06cc0749cf1e49d447d 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/coursebook.graphql
@@ -81,6 +81,7 @@ query documentationsForCoursebook(
         name
         shortName
       }
+      isOptimistic
     }
     topic
     homework
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index aae1b70603f0b0e5c738d81467d31f3844f13a86..e4e48be10e717b4f105330a7f942861794aca12c 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -17,6 +17,7 @@ from .documentation import (
     DocumentationBatchCreateOrUpdateMutation,
     DocumentationType,
 )
+from .participation_status import ParticipationStatusBatchPatchMutation
 
 
 class Query(graphene.ObjectType):
@@ -119,3 +120,4 @@ class Query(graphene.ObjectType):
 
 class Mutation(graphene.ObjectType):
     create_or_update_documentations = DocumentationBatchCreateOrUpdateMutation.Field()
+    update_participation_statuses = ParticipationStatusBatchPatchMutation.Field()
diff --git a/aleksis/apps/alsijil/schema/participation_status.py b/aleksis/apps/alsijil/schema/participation_status.py
index 48053dc224b405e23647a3deb59f90422dabb0b9..e99586e2ef26e663cdd51da2261af14acb0660d8 100644
--- a/aleksis/apps/alsijil/schema/participation_status.py
+++ b/aleksis/apps/alsijil/schema/participation_status.py
@@ -1,10 +1,20 @@
 from graphene_django import DjangoObjectType
 
 from aleksis.apps.alsijil.models import ParticipationStatus
-from aleksis.core.schema.base import DjangoFilterMixin, PermissionsTypeMixin
+from aleksis.core.schema.base import (
+    BaseBatchPatchMutation,
+    DjangoFilterMixin,
+    OptimisticResponseTypeMixin,
+    PermissionsTypeMixin,
+)
 
 
-class ParticipationStatusType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectType):
+class ParticipationStatusType(
+    OptimisticResponseTypeMixin,
+    PermissionsTypeMixin,
+    DjangoFilterMixin,
+    DjangoObjectType,
+):
     class Meta:
         model = ParticipationStatus
         fields = (
@@ -14,3 +24,11 @@ class ParticipationStatusType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObj
             "related_documentation",
             "base_absence",
         )
+
+
+class ParticipationStatusBatchPatchMutation(BaseBatchPatchMutation):
+    class Meta:
+        model = ParticipationStatus
+        fields = ("id", "absence_reason")  # Only the reason can be updated after creation
+        permissions = ("alsijil.change_participation_status",)  # FIXME
+        return_field_name = "participationStatuses"