Escalation Tiers
Read and edit a team's escalation chain: ordered tiers, their auto-escalation and repeat settings, and the schedules under each tier.
A team's escalation chain is an ordered list of tiers. Tier 1 is paged first; the people on call in a tier are whoever the tier's schedules have on shift right now. Each tier decides whether and when the incident moves on to the next tier, and how often the tier is paged again first. Whole-chain repeats live on the team (Update a team).
Authentication
Base IM access: an IM-eligible role or an organization-wide API token, and Incident Management activated for the organization. Reading the chain is open to any caller with that access. Every write needs the team write bar: organization admin role, or team admin of this team. An API token runs with the role of the user who created it, so only a token created by an organization admin passes.
Tier fields
| Field | Type | Description |
|---|---|---|
tierOrder | integer | Position in the chain, 1 = paged first. Changed only through Reorder. |
autoEscalationEnabled | boolean | Whether the incident moves on to the next tier automatically. Default true. |
autoEscalationAfterMinutes | integer | Minutes before it moves on, 0 or more. Default 5. |
autoEscalationStopMode | string | acknowledged or resolved: the incident state that stops the escalation. Default acknowledged. |
autoEscalationSeverities | array | null | Severities that escalate automatically: a subset of critical, warning, minor. null = all. |
autoEscalationTimeFilters | array | Weekly windows in which auto-escalation may fire, up to 50, each { from: "HH:mm", until: "HH:mm", days: number[] } with ISO weekdays (1 = Monday). until may be "24:00". [] = always. |
repeats | integer | How many more times this tier is paged before moving on, 0 or more. Default 0. |
repeatsAfterMinutes | integer | null | Minutes between those repeats. null = use autoEscalationAfterMinutes. |
repeatsStopMode | string | acknowledged or resolved: the incident state that stops the repeats. Default acknowledged. |
Read the escalation chain
GET /api/im/teams/:id/escalations
Returns all tiers in order, each with its schedules, rotation groups and members, plus the team's escalation settings.
Example (cURL)
curl -X GET "$BASE_URL/api/im/teams/3/escalations" \
-H "Authorization: Bearer $TOKEN"Response
200 OK
{
"tiers": [
{
"id": 21,
"tierOrder": 1,
"autoEscalationEnabled": true,
"autoEscalationAfterMinutes": 5,
"autoEscalationStopMode": "acknowledged",
"autoEscalationSeverities": null,
"autoEscalationTimeFilters": [],
"repeats": 0,
"repeatsAfterMinutes": null,
"repeatsStopMode": "acknowledged",
"schedules": [
{
"id": 7,
"displayName": "Primary On-Call",
"timezone": "Europe/Berlin",
"effectiveFrom": null,
"effectiveUntil": null,
"weeklySchedules": [],
"rotationMode": "explicit",
"rotationRepeats": "weekly",
"customRepeatUnit": null,
"customRepeatValue": null,
"autoRotationSize": null,
"roundRobinSize": 1,
"startsOnDayOfWeek": 1,
"startsOnDateOfMonth": null,
"startsOnTime": "09:00",
"rotations": [
{
"id": 12,
"rotationOrder": 1,
"members": [
{ "userId": "u_abc123", "userName": "Ada Lovelace", "userImage": null, "memberOrder": 1 }
]
}
]
}
]
}
],
"teamSettings": {
"timezone": "Europe/Berlin",
"escalationRepeats": 1,
"escalationRepeatsAfterMinutes": 15,
"escalationRepeatsStopMode": "acknowledged",
"engagementReportEnabled": false,
"engagementReportDayOfWeek": null,
"engagementReportTime": null
}
}The schedule fields are explained under Rotation cadence and Update a schedule.
Add a tier
POST /api/im/teams/:id/tiers
Appends a tier at the end of the chain (tierOrder = highest + 1) with the default settings from the table above. In the same step it creates one schedule under the tier: named Tier N schedule, 24/7, rotationMode: "none", in the team's timezone (or UTC if the team has none), with one rotation group holding the given members in the given order.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
memberUserIds | string[] | Yes | 1 to 200 distinct user ids, all members of this team. |
Example (cURL)
curl -X POST "$BASE_URL/api/im/teams/3/tiers" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "memberUserIds": ["u_abc123", "u_def456"] }'Response
200 OK: the tier fields plus schedules, holding the one new schedule in the same shape as in the escalation chain (members without userImage).
{
"id": 22,
"tierOrder": 2,
"autoEscalationEnabled": true,
"autoEscalationAfterMinutes": 5,
"autoEscalationStopMode": "acknowledged",
"autoEscalationSeverities": null,
"autoEscalationTimeFilters": [],
"repeats": 0,
"repeatsAfterMinutes": null,
"repeatsStopMode": "acknowledged",
"schedules": [
{
"id": 8,
"displayName": "Tier 2 schedule",
"timezone": "Europe/Berlin",
"effectiveFrom": null,
"effectiveUntil": null,
"weeklySchedules": [],
"rotationMode": "none",
"rotationRepeats": null,
"customRepeatUnit": null,
"customRepeatValue": null,
"autoRotationSize": null,
"roundRobinSize": 1,
"startsOnDayOfWeek": null,
"startsOnDateOfMonth": null,
"startsOnTime": null,
"rotations": [
{
"id": 14,
"rotationOrder": 1,
"members": [
{ "userId": "u_abc123", "userName": "Ada Lovelace", "memberOrder": 1 },
{ "userId": "u_def456", "userName": "Bob Fixit", "memberOrder": 2 }
]
}
]
}
]
}Update a tier
PATCH /api/im/teams/:id/tiers/:tierId
Every field from the tier fields table except tierOrder is optional and patchable. Only fields present in the body change.
Example (cURL)
curl -X PATCH "$BASE_URL/api/im/teams/3/tiers/21" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"autoEscalationAfterMinutes": 10,
"autoEscalationSeverities": ["critical"],
"autoEscalationTimeFilters": [{ "from": "18:00", "until": "08:00", "days": [1, 2, 3, 4, 5] }]
}'Response
200 OK: the tier fields after the update (without schedules).
Delete a tier
DELETE /api/im/teams/:id/tiers/:tierId
Deletes the tier together with its schedules, rotation groups and shifts. The remaining tiers keep their tierOrder, so deleting tier 2 of 3 leaves orders 1 and 3. Close the gap with Reorder if you need contiguous numbers.
Example (cURL)
curl -X DELETE "$BASE_URL/api/im/teams/3/tiers/22" \
-H "Authorization: Bearer $TOKEN"Response
200 OK
{ "success": true }Reorder tiers
POST /api/im/teams/:id/tiers/reorder
Renumbers the chain to 1..n in the order you send.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
tierIds | number[] | Yes | Every tier id of this team exactly once, in the new order. |
Example (cURL)
curl -X POST "$BASE_URL/api/im/teams/3/tiers/reorder" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "tierIds": [22, 21] }'Response
200 OK
{ "tiers": [{ "id": 22, "tierOrder": 1 }, { "id": 21, "tierOrder": 2 }] }Add a schedule to a tier
POST /api/im/teams/:id/tiers/:tierId/schedules
Creates a further schedule under a tier, for example a follow-the-sun schedule in another timezone, with its cadence and rotation groups in one call. The tier's on-call set is the union of what all its schedules have on shift.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | 1 to 120 characters after trimming. |
timezone | string | Yes | IANA zone the schedule is evaluated in. |
effectiveFrom | string | null | No | ISO timestamp before which the schedule pages nobody. |
effectiveUntil | string | null | No | ISO timestamp after which the schedule pages nobody. |
weeklySchedules | array | No | On-call windows, same shape as autoEscalationTimeFilters. Omitted or [] = 24/7. |
rotations | array | No | Rotation groups, up to 50, each { members: string[] } with up to 200 distinct members of this team. Array order is rotation order. |
Plus the cadence fields from Rotation cadence. Omitted cadence fields default to rotationMode: "none", roundRobinSize: 1, everything else null. The resulting cadence is validated as a whole.
Example (cURL)
curl -X POST "$BASE_URL/api/im/teams/3/tiers/21/schedules" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "APAC Follow-the-Sun",
"timezone": "Asia/Singapore",
"weeklySchedules": [{ "from": "09:00", "until": "18:00", "days": [1, 2, 3, 4, 5] }],
"rotationMode": "explicit",
"rotationRepeats": "weekly",
"startsOnDayOfWeek": 1,
"startsOnTime": "09:00",
"rotations": [{ "members": ["u_abc123"] }, { "members": ["u_def456"] }]
}'Response
200 OK: the new schedule in the same shape as in the escalation chain (members without userImage).
Common errors
401 Unauthorized(unauthorized) when not authenticated403 Forbidden(imAccessDenied) for a customer-scoped token, or a session without an IM-eligible role403 Forbidden(imNotEnabled) when Incident Management is not activated for the organization403 Forbidden(imTeamWriteDenied) on any write when you are neither organization admin nor team admin of this team404 Not Found(imTeamNotFound) when the team does not exist or belongs to another organization404 Not Found(imEscalationTierNotFound) when:tierIdis not a tier of this team404 Not Found(imTeamMemberNotFound) when a user id inmemberUserIdsorrotationsis not a member of this team400 Bad Request(invalidRequestBody) when a path id is not a positive integer,memberUserIdsis missing, empty or holds an empty id,tierIdsis missing, empty, or not distinct positive integers,nameortimezoneis missing or invalid,effectiveFrom/effectiveUntilis not a valid timestamp, orrotationsis malformed422 Unprocessable Entity(imTierReorderMismatch) whentierIdsis not exactly this team's set of tier ids422 Unprocessable Entity(imInvalidRequestBody) whenautoEscalationEnabledis not a boolean422 Unprocessable Entity(imInvalidNumber) whenautoEscalationAfterMinutes,repeatsorrepeatsAfterMinutesis not an integer of0or more, or a cadence number is not an integer of1or more422 Unprocessable Entity(imInvalidStopMode) when a stop mode is notacknowledgedorresolved422 Unprocessable Entity(imInvalidSeverities) whenautoEscalationSeveritiesis neithernullnor a list ofcritical,warning,minor422 Unprocessable Entity(imInvalidTimeFilter) when a window list is not an array, has more than 50 entries, or an entry is not an object or has nodaysarray422 Unprocessable Entity(imInvalidTimeOfDay) when a window'sfrom/untilorstartsOnTimeis not"HH:mm"422 Unprocessable Entity(imInvalidDayOfWeek) when a window day orstartsOnDayOfWeekis not 1 to 7422 Unprocessable Entity(imInvalidRotationMode) whenrotationModeis notnone,autoorexplicit422 Unprocessable Entity(imInvalidRotation) when the cadence does not hold together, a list exceeds 200 members or 50 rotation groups, or a user id appears twice in one list409 Conflict(imTierOrderConflict) when two tiers were added at the same moment; retry