Recurring schedules
Recurring service agreements, occurrences, and presets
Recurring agreements live in recurringSchedules. Occurrence generation
(skip / move / resize / resync / generate) is ported from the
Servicebay Cloud Functions and runs inline — the same wall-clock math and
ledger rules as the app.
Required scopes: recurring-schedules:read / recurring-schedules:write / recurring-schedules:delete. Pause, resume, end, resync, generate, and occurrence skip/move/resize all use recurring-schedules:write.
-
GET
/organisations/{orgId}/recurring-schedules -
POST
/organisations/{orgId}/recurring-schedules -
GET
/organisations/{orgId}/recurring-schedules/{scheduleId} -
PUT
/organisations/{orgId}/recurring-schedules/{scheduleId} -
DELETE
/organisations/{orgId}/recurring-schedules/{scheduleId} -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/pause -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/resume -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/end -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/resync -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/generate -
GET
/organisations/{orgId}/recurring-schedules/{scheduleId}/occurrences -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/occurrences/{index}/skip -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/occurrences/{index}/move -
POST
/organisations/{orgId}/recurring-schedules/{scheduleId}/occurrences/{index}/resize -
GET
/organisations/{orgId}/recurring-presets
Series-shape edits
Changing frequency, interval, anchors, month fields, or tightening the end
condition returns 409 SERIES_SHAPE_CHANGE unless you pass
?resync=thisAndFuture. That rewrites unworked future visits the same way
the app's resync action does. nextOccurrenceAt is never written as null
— pause/end delete the field. Skip of a worked visit → 409
OCCURRENCE_WORKED. Move/resize of an ungenerated visit → 409
OCCURRENCE_NOT_GENERATED. Delete while still in use → 409
SCHEDULE_IN_USE.
Dates
startDate / endDate are wall-clock strings (offset optional,
ignored) stored as those components read as UTC, matching the Flutter model.