Uptimeify Docs

Schedule-Overrides

Overrides auf einem Schedule auflisten, hinzufügen, ändern und löschen: einmalige Zeitfenster, die jemanden in Bereitschaft setzen oder aus ihr nehmen, ohne die Rotation anzufassen.

Ein Override ist ein einmaliges Zeitfenster zusätzlich zur regulären Rotation eines Schedules, für einen Urlaubstausch oder einen Krankheitstag, ohne die Rotation selbst zu bearbeiten. Diese Seite behandelt Overrides, die an einem Schedule hängen. Overrides, die dem Team ohne Schedule gehören, stehen unter Team-Overrides.

Authentifizierung

Basis-IM-Zugriff: eine IM-berechtigte Rolle oder ein organisationsweiter API-Token, und Incident Management für die Organisation aktiviert. Auflisten darf jeder mit diesem Zugriff. Hinzufügen, Ändern und Löschen brauchen die Team-Schreibhürde für das Team des Schedules: Organisationsrolle admin, oder Team-Admin. Ein API-Token läuft mit der Rolle des Users, der ihn erstellt hat, also kommt nur ein Token durch, den ein Organisations-Admin erstellt hat.

Ausnahme: die eigene Schicht abgeben. Ein einfaches Mitglied des Schedule-Teams darf eine Art Override ohne die Schreibhürde anlegen und wieder löschen:

  • userId ist der Aufrufer selbst, type ist offline, applyScope ist this_team (oder fehlt), escalationTierOrder ist null (oder fehlt),
  • coveredByUserIds enthält genau eine Person, nicht den Aufrufer, und diese ist Mitglied des Schedule-Teams,
  • das Fenster ist noch nicht vorbei, höchstens 7 Tage lang und liegt von startsAt (oder jetzt, falls später) bis endsAt innerhalb eines zusammenhängenden Stücks eigener Bereitschaftsschichten des Aufrufers auf diesem Schedule (direkt aneinander anschließende Schichten zählen als ein Stück),
  • noch kein offline-Override des Aufrufers auf diesem Schedule überschneidet das Fenster.

Die übernehmende Person hat genau für dieses Fenster Bereitschaft. Das gilt auch für Bereitschaft, die ein Admin dem Aufrufer per online-Override gegeben hat: offline-Overrides wirken nach online-Overrides, also kann das Mitglied auch diese Bereitschaft abgeben. Die übernehmende Person bekommt eine E-Mail (den Bereitschaftshinweis, außer sie hat E-Mail oder Übergabehinweise in ihren Benachrichtigungseinstellungen abgeschaltet) und eine weitere, wenn der Override wieder gelöscht wird, vom Aufrufer oder von einem Admin; eine identische Wiederholung (gleiche Art, sich überschneidendes Fenster) innerhalb von 10 Minuten geht nur einmal raus, ein Wechsel zwischen abgegeben und zurückgenommen immer. Nimmt sich jemand selbst mit Vertretungen aus der Bereitschaft (ein Mitglied oder ein Admin), bekommt jede übernehmende Person diesen Hinweis, und beim Löschen des Overrides bekommt jede den Hinweis „zurückgenommen". Ein Mitglied kann höchstens 10 Schichten pro Stunde abgeben; die elfte bekommt 429 imShiftGiveAwayRateLimited. Löschen darf ein Mitglied nur einen offline-Override über sich selbst, den es selbst angelegt hat; einen Override, den ein Admin über es angelegt hat, löscht weiterhin nur ein Admin. Ändern bleibt Admins vorbehalten. Alles andere, was ein Mitglied schickt, wird mit 403 imShiftGiveAwayDenied und einem reason abgelehnt (siehe Häufige Fehler).

Override-Felder

FeldTypErforderlichBeschreibung
userIdstringJaDie betroffene Person: wer in Bereitschaft geht (online) oder aus ihr herausgenommen wird (offline).
startsAtstringJaISO-8601-Zeitstempel, Beginn des Fensters.
endsAtstringJaISO-8601-Zeitstempel, Ende des Fensters. Muss nach startsAt liegen.
typestringJaonline: Die Person hat im Fenster Bereitschaft und ersetzt alle anderen, die gerade Bereitschaft haben. offline: Die Person wird aus der Bereitschaft genommen.
coveredByUserIdsstring[]NeinNur bei offline, bis zu 200: wer übernimmt. Alle genannten Vertretungen werden alarmiert, jede genau für die Alarme, die die betroffene Person bekäme. Leer oder weggelassen hinterlässt eine Lücke, die die Eskalations-Engine beim Alarmieren aus einer anderen Stufe füllt. Muss bei online leer sein.
applyScopestringNeinthis_team (Standard) oder all_teams: gilt auch für jedes andere Team, in dem die Person Mitglied ist.
escalationTierOrderinteger | nullNeinGilt nur in dieser Stufe (tierOrder, ab 1). null oder weggelassen = alle Stufen.

Jede User-ID (betroffene Person und Vertretungen) muss ein aktiver User deiner Organisation mit der Organisationsrolle admin, editor oder responder sein.

Überlappen sich zwei Online-Overrides, gewinnt der später erstellte. Es gibt kein Prioritätsfeld, der Vorrang ist die Erstellungsreihenfolge. Deshalb sind Listen nach id sortiert, und eine Änderung behält die id des Overrides.

Wie Overrides aufgelöst werden

Ein Override wirkt in dem Moment, in dem er gespeichert ist: Die Eskalations-Engine liest Overrides zum Zeitpunkt der Alarmierung. Kalender und Schichttabelle ziehen nach, sobald die Schichten neu materialisiert sind, innerhalb von Sekunden.

coveredByUserIds ist ein 1:1-Ersatz: Die Vertretungen bekommen genau die Alarme, die die vertretene Person bekäme, und alle werden alarmiert. Pro Schedule wird die Bereitschaft in dieser Reihenfolge aufgelöst:

  1. Die Rotation zu diesem Zeitpunkt.
  2. online-Overrides: Der zuletzt aktive ersetzt die ganze Menge durch seine Person. offline-Overrides ohne Vertretung nehmen ihre Person heraus (nicht verfügbar, Round Robin überspringt sie).
  3. Round Robin grenzt die Menge pro Incident ein.
  4. offline-Overrides mit Vertretung ersetzen die ausgewählte Person durch alle ihre Vertretungen.

Team-Overrides werden nach der Vereinigung der Schedules der Stufe eingerechnet, mit demselben Ersatz.

Laufende Incidents. Beginnt oder ändert sich ein Override, während ein Incident offen ist, richtet sich der nächste Alarm dieses Incidents (Wiederholung oder Eskalation) danach. Die Round-Robin-Auswahl merkt sich der Incident, sie wird aber beim Alarmieren neu zugeordnet: Ist die gemerkte Person in dem Moment vertreten, werden stattdessen die Vertretungen alarmiert; ist sie ohne Vertretung offline, wird sie nicht alarmiert.

Overrides auflisten

GET /api/im/schedules/:id/overrides

Liefert die Overrides des Schedules, sortiert nach id.

Query-Parameter

ParameterTypStandardBeschreibung
envelopestringkeineritems: Antwort als { items, total, page, perPage }. Ab 18.01.2027 Standard.

Beispiel (cURL)

curl -X GET "$BASE_URL/api/im/schedules/7/overrides?envelope=items" \
  -H "Authorization: Bearer $TOKEN"

Antwort (Response)

200 OK

{
  "items": [
    {
      "id": 12,
      "scheduleId": 7,
      "userId": "u_abc123",
      "userName": "Ada Lovelace",
      "userImage": null,
      "type": "offline",
      "applyScope": "this_team",
      "escalationTierOrder": null,
      "startsAt": "2026-10-20T00:00:00.000Z",
      "endsAt": "2026-10-27T00:00:00.000Z",
      "createdAt": "2026-10-09T10:00:00.000Z",
      "coveredBy": [
        { "userId": "u_def456", "userName": "Bob Fixit", "userImage": null }
      ]
    }
  ],
  "total": 1,
  "page": 1,
  "perPage": 1
}

Listenform: Mit envelope=items kommt die Liste als { items, total, page, perPage }. Ohne den Parameter antwortet der Endpunkt noch in der bisherigen Form (ein blankes Array derselben Overrides); sie ist veraltet, ab dem 18.01.2027 ist { items, ... } der Standard.

Form der Vertretungsliste: Die Liste und das einzelne GET liefern coveredBy als Array von Objekten (userId, userName, userImage). Hinzufügen (POST) und Ändern (PATCH) liefern stattdessen coveredByUserIds, ein Array von User-IDs als Strings.

Override lesen

GET /api/im/schedules/:id/overrides/:overrideId

Liest einen Override dieses Schedules zurück, in derselben Form wie ein Eintrag von Overrides auflisten. Jede IM-berechtigte Rolle darf ihn aufrufen.

Beispiel (cURL)

curl "$BASE_URL/api/im/schedules/5/overrides/31" \
  -H "Authorization: Bearer $TOKEN"

Antwort

200 OK, ein Override-Objekt wie in der Liste oben. 404 mit imOverrideNotFound, wenn :overrideId kein Override dieses Schedules ist.

Override hinzufügen

POST /api/im/schedules/:id/overrides

Body: die Override-Felder.

Beispiel (cURL)

Ada ist im Urlaub, Bob vertritt:

curl -X POST "$BASE_URL/api/im/schedules/7/overrides" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "u_abc123",
    "type": "offline",
    "coveredByUserIds": ["u_def456"],
    "startsAt": "2026-10-20T00:00:00.000Z",
    "endsAt": "2026-10-27T00:00:00.000Z"
  }'

Antwort (Response)

200 OK: der gespeicherte Override mit der Vertretungsliste als IDs.

{
  "id": 12,
  "teamId": 3,
  "scheduleId": 7,
  "userId": "u_abc123",
  "type": "offline",
  "applyScope": "this_team",
  "escalationTierOrder": null,
  "startsAt": "2026-10-20T00:00:00.000Z",
  "endsAt": "2026-10-27T00:00:00.000Z",
  "createdAt": "2026-10-09T10:00:00.000Z",
  "coveredByUserIds": ["u_def456"]
}

Override ändern

PATCH /api/im/schedules/:id/overrides/:overrideId

Eine Teilaktualisierung: Sende nur die Override-Felder, die du ändern willst, keines ist Pflicht. Weggelassene Felder behalten ihren gespeicherten Wert, und die Regeln gelten für das Ergebnis: endsAt muss weiter nach startsAt liegen (gespeichert oder gesendet), und ein Override, der online wird, verliert seine Vertretungen, außer du sendest coveredByUserIds. Der Override behält seine id und damit seinen Vorrang.

Enthält der Body alle vier Felder userId, type, startsAt und endsAt, ersetzt er den Override wie bisher: Weggelassene optionale Felder fallen auf ihre Standardwerte zurück (applyScope: "this_team", alle Stufen, keine Vertretungen).

# Nur das Ende des Fensters verschieben
curl -X PATCH "$BASE_URL/api/im/schedules/7/overrides/12" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "endsAt": "2026-10-25T00:00:00.000Z" }'

Beispiel (cURL)

curl -X PATCH "$BASE_URL/api/im/schedules/7/overrides/12" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "u_abc123",
    "type": "offline",
    "coveredByUserIds": ["u_def456"],
    "startsAt": "2026-10-20T00:00:00.000Z",
    "endsAt": "2026-10-24T00:00:00.000Z"
  }'

Antwort (Response)

200 OK: dieselbe Form wie beim Hinzufügen.

Override löschen

DELETE /api/im/schedules/:id/overrides/:overrideId

Beispiel (cURL)

curl -X DELETE "$BASE_URL/api/im/schedules/7/overrides/12" \
  -H "Authorization: Bearer $TOKEN"

Antwort (Response)

200 OK

{ "success": true }

Häufige Fehler

  • 401 Unauthorized (unauthorized) wenn du nicht authentifiziert bist
  • 403 Forbidden (imAccessDenied) bei einem kunden-gescopten Token, oder wenn deine Session keine IM-berechtigte Rolle hat
  • 403 Forbidden (imNotEnabled) wenn Incident Management für die Organisation nicht aktiviert ist
  • 403 Forbidden (imTeamWriteDenied) beim Hinzufügen, Ändern oder Löschen, wenn du weder Organisations-Admin noch Team-Admin noch (beim Hinzufügen und Löschen) Mitglied des Schedule-Teams bist; beim Ändern für jedes einfache Mitglied
  • 403 Forbidden (imShiftGiveAwayDenied), wenn ein einfaches Teammitglied etwas anderes schickt als die Abgabe der eigenen Schicht. data.reason nennt die verletzte Bedingung: not_self (userId ist jemand anderes), type (nicht offline), scope (applyScope ist all_teams), tier (escalationTierOrder ist gesetzt), covered_by (nicht genau eine übernehmende Person, oder der Aufrufer übernimmt selbst), window (das Fenster ist vorbei, länger als 7 Tage oder liegt nicht innerhalb eines zusammenhängenden Stücks eigener Schichten des Aufrufers auf diesem Schedule), coverer_not_in_team (die übernehmende Person ist kein Mitglied des Schedule-Teams), already_given_away (ein offline-Override des Aufrufers auf diesem Schedule überschneidet das Fenster bereits), no_duty (der Aufrufer hat im Fenster keine noch nicht beendete Schicht auf diesem Schedule), not_own_giveaway (Löschen: der Override ist kein offline-Override über den Aufrufer, den dieser selbst angelegt hat)
  • 429 Too Many Requests (imShiftGiveAwayRateLimited, mit retryAfter in Sekunden), wenn ein einfaches Teammitglied mehr als 10 Schichten innerhalb einer Stunde abgibt
  • 404 Not Found (imScheduleNotFound) wenn :id nicht existiert oder zu einer anderen Organisation gehört
  • 404 Not Found (imOverrideNotFound) wenn :overrideId kein Override dieses Schedules ist
  • 404 Not Found (userNotFound) wenn userId oder eine Vertretung nicht existiert oder zu einer anderen Organisation gehört
  • 400 Bad Request (invalidRequestBody) wenn eine Pfad-ID keine positive Ganzzahl ist, userId fehlt, startsAt/endsAt fehlt oder kein gültiger Zeitstempel ist, startsAt nicht vor endsAt liegt, type nicht online oder offline ist, applyScope ungültig ist, escalationTierOrder weder positive Ganzzahl noch null ist, coveredByUserIds kein Array aus IDs ist oder mehr als 200 Einträge hat, oder ein online-Override Vertretungen hat
  • 400 Bad Request (imUserNotEligible) wenn die betroffene Person oder eine Vertretung inaktiv ist oder nicht die Organisationsrolle admin, editor oder responder hat

Auf dieser Seite