On-call schedules
A schedule answers "who is on call right now". Rules name schedules in their escalation ladders, so the rule never changes when the rota does.
Layers and rotations
A schedule is per project. It has a timezone and one or more layers. Each layer rotates through its participants every shift_minutes, starting at rotation_start. A layer with a restriction is active only inside that window, and a later layer wins over an earlier one while both are active. That is how “weekday office hours go to the ops account, everything else to the weekly rota” is written.
POST /v1/projects/{id}/oncall/schedules
{
"name": "backend-primary",
"timezone": "Europe/Stockholm",
"layers": [
{ "name": "weekly",
"participants": ["[email protected]", "[email protected]", "[email protected]"],
"rotation_start": 1756677600, "shift_minutes": 10080 },
{ "name": "office-hours",
"participants": ["[email protected]"],
"rotation_start": 1756677600, "shift_minutes": 1440,
"restriction": { "days": [1, 2, 3, 4, 5], "start_minute": 540, "end_minute": 1080 } }
]
}
rotation_start is a unix timestamp. days are 0 Sunday through 6 Saturday. start_minute and end_minute are minutes after midnight in the schedule’s timezone; an end before a start wraps overnight. Participants must be members of the tenant whose role has alerts:write, so not viewers; a stranger or a member without it is a 422 naming them. The same goes for escalation ladders and overrides.
GET PUT DELETE /v1/projects/{id}/oncall/schedules/{sid}.
Overrides
An override swaps one person in for a window without editing the rota. Newest override wins where two overlap.
POST /v1/projects/{id}/oncall/schedules/{sid}/overrides
{ "account_id": "…", "starts_at": 1756800000, "ends_at": 1756886400 }
Unix timestamps, half-open [starts_at, ends_at), at most a year long. A schedule holds at most 500 current or upcoming overrides. GET lists them; DELETE …/overrides/{oid} removes one.
A member or above, or any role with oncall:write, can set and remove anyone’s overrides. A responder, or any role with oncall_overrides:write but not oncall:write, can only create an override whose account_id is their own and only delete their own; anything else is a 403. Viewers and up can read schedules, overrides and who is on call now. A member limited to some projects reads the schedule list only through a grant whose role holds oncall:read.
Who is on call now
GET /v1/projects/{id}/oncall/schedules/{sid}/current
{ "on_call": true, "account_id": "…", "email": "[email protected]", "via": "layer:weekly" }
Using it from a rule
Name the schedule in an escalation rung: {"after_minutes": 15, "schedules": ["backend-primary"]}. When the rung is reached the schedule is resolved at that instant and the person on call is added to the page. Shift changes emit oncall.shift_started and oncall.shift_ended events to integrations that subscribe to them.
409 with the rules referencing it. Remove it from those ladders first; a rung that pointed at nothing would page nobody. Removing a member works differently: it always succeeds, takes them out of every rotation, ladder and current override, and lists what it changed, so check that each schedule still has someone on it.