Part of the Phoenix Alerts Management API reference.
Each team has one on-call schedule: an ordered rotation of members, a timezone, and a rotation start time. Phoenix Alerts uses the schedule to work out who's on call right now, and pages them when an alert escalates to that team.
Get a team's schedule
GET /v1/teams/{team_uuid}/schedule
Response (200):
{
"object": "team_schedule",
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"team": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Platform Team",
"key": "platform"
},
"timezone": "America/New_York",
"rotation_start_at": "2026-06-09T09:00:00.000-05:00",
"members": [],
"rotation": {"name": "Weekly"},
"current_on_call": null,
"next_handoff_at": null,
"created_at": "2026-06-12T00:00:00.000Z",
"updated_at": "2026-06-12T00:00:00.000Z"
}
Add ?expand=overrides to include upcoming overrides in the response.
Create or replace a schedule
PUT /v1/teams/{team_uuid}/scheduleField | Type | Required | Notes |
| string | yes | IANA timezone, e.g. |
| string | yes | ISO-8601 datetime for the start of the first rotation period. |
| array | yes | Ordered list of user UUID strings. An empty array clears the schedule. |
Example request body:
{
"timezone": "America/New_York",
"rotation_start_at": "2026-06-09T09:00:00.000-05:00",
"members": ["b2c3d4e5-f6a7-8901-bcde-f12345678901"]
}
This replaces the whole schedule — supply the full member list every time, not just the changes.
Who's on call right now
GET /v1/teams/{team_uuid}/on-call
Response (200):
{
"object": "on_call",
"team": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Platform Team",
"key": "platform"
},
"as_of_at": "2026-06-12T00:00:00.000Z",
"on_call_user": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"display_name": "Alice Example",
"jira_account_id": "abc123"
},
"source": "rotation",
"rotation": {"name": "Weekly"},
"override": null,
"shift_end": "2026-06-16T09:00:00.000-05:00"
}
Pass ?at=<ISO-8601 datetime> to check a different moment (up to 365 days from now, past or future). on_call_user is null when an override has skipped coverage or no schedule is configured.
To see who's on call across every team at once, use GET /v1/on-call — same shape, one entry per team.
Preview upcoming shifts
GET /v1/teams/{team_uuid}/on-call/preview?from=<ISO-8601>&to=<ISO-8601>
Returns the ordered list of shifts in that window. GET /v1/on-call/preview does the same across every team, with cursor pagination via ?cursor= and ?limit=.
Overrides (vacations, swaps)
An override temporarily replaces (or skips) whoever the rotation would normally put on call.
POST /v1/teams/{team_uuid}/schedule/overridesField | Type | Required | Notes |
| string | yes | ISO-8601 datetime with offset. |
| string | yes | ISO-8601 datetime with offset. Must be after |
| string | yes |
|
| string or null | no | Who covers instead. |
Example request body:
{
"start_at": "2026-06-14T09:00:00.000-05:00",
"end_at": "2026-06-21T09:00:00.000-05:00",
"reason": "VACATION",
"replacement_user_uuid": "d4e5f6a7-b8c9-0123-def0-123456789012"
}
Returns 409 if the window overlaps an existing override.
List overrides with GET /v1/teams/{team_uuid}/schedule/overrides (defaults to future and active ones; add ?include_past=true for history). Delete one with DELETE /v1/teams/{team_uuid}/schedule/overrides/{override_uuid}.
