Uptimeify Docs
Incident management

Routing Rules

List, create, update and delete Incident Management routing rules: which team a new incident is assigned to, and an optional severity override.

GET /api/im/routing · POST /api/im/routing · GET /api/im/routing/:id · PATCH /api/im/routing/:id · DELETE /api/im/routing/:id

A routing rule decides which team a new incident belongs to. When an alert opens an incident, the rules of your organization are walked in order of priority (lowest first, id as tiebreak). The first rule whose match applies wins: the incident goes to that rule's teamId, and severityOverride (if set) replaces the alert's severity. If no rule matches, the incident goes to the team of the alert source that received the alert.

Authentication

Requires the base IM access every endpoint in this API needs (an IM-eligible role admin, editor or responder, or an organization-wide API token; Incident Management must be enabled for the organization). Reading is open to any IM-eligible role. Creating, updating and deleting additionally require the write bar: your role must be admin, or you must be a team admin of the rule's team. An organization-wide API token runs with the role of the user who created it, so a token created by an organization admin passes this bar. Team-admin membership never applies to a token.

The match object

FieldTypeDescription
source_idsinteger[]Alert source IDs. Max 500 entries.
severitystring[]Alert severities, each one of sev1, sev2, sev3, sev4.
customer_idsinteger[]Customer IDs. Max 500 entries.
monitor_idsinteger[]Monitor IDs. Max 500 entries.
tagsstring[]Non-empty strings. Max 200 entries.
field_matchesobjectString values only. Max 50 keys.

An empty object {} (or omitting match) matches every alert, which makes a catch-all rule at a high priority number. Every ID in source_ids, customer_ids and monitor_ids must belong to your organization, otherwise the request fails with 422.

Today the routing engine evaluates only source_ids and severity. A rule that sets any of customer_ids, monitor_ids, tags (non-empty) or field_matches (even as {}) is stored, but never matches an alert. Use source_ids and severity for rules that must take effect.

List routing rules

GET /api/im/routing

Returns all rules of your organization, in evaluation order (priority ascending, then id ascending).

Example (cURL)

curl -X GET "$BASE_URL/api/im/routing" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

Response

200 OK

[
  {
    "id": 4,
    "organizationId": 1,
    "priority": 10,
    "match": { "source_ids": [7], "severity": ["sev1", "sev2"] },
    "teamId": 3,
    "escalationPolicyId": null,
    "severityOverride": "sev1",
    "createdAt": "2026-09-14T08:00:00.000Z",
    "updatedAt": "2026-09-14T08:00:00.000Z"
  },
  {
    "id": 5,
    "organizationId": 1,
    "priority": 100,
    "match": {},
    "teamId": 2,
    "escalationPolicyId": null,
    "severityOverride": null,
    "createdAt": "2026-09-14T08:05:00.000Z",
    "updatedAt": "2026-09-14T08:05:00.000Z"
  }
]

Get a routing rule

GET /api/im/routing/:id

Returns one rule, same shape as a list item.

Create a routing rule

POST /api/im/routing

Request Body

FieldTypeRequiredDescription
teamIdintegerYesTarget team. Must belong to your organization. You need the write bar on this team.
priorityintegerNoEvaluation order, lower first. Non-negative integer, default 100.
matchobjectNoSee the match object. Default {} (matches everything).
severityOverridestring | nullNosev1 to sev4, or null (default) to keep the alert's severity.
escalationPolicyIdinteger | nullNoLegacy field. Accepted (positive integer or null) and stored, but has no effect.

Example (cURL)

curl -X POST "$BASE_URL/api/im/routing" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "teamId": 3,
    "priority": 10,
    "match": { "source_ids": [7], "severity": ["sev1", "sev2"] },
    "severityOverride": "sev1"
  }'

Response

200 OK: the created rule (same shape as a list item).

Update a routing rule

PATCH /api/im/routing/:id

Partial update. Send only the fields you want to change: priority, match, teamId, severityOverride, escalationPolicyId (same validation as on create). Other fields are ignored. A new match replaces the stored one completely. You need the write bar on the rule's current team, and, when you change teamId, also on the new team (which must belong to the same organization).

curl -X PATCH "$BASE_URL/api/im/routing/4" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "priority": 5 }'

200 OK: the updated rule.

Delete a routing rule

DELETE /api/im/routing/:id

curl -X DELETE "$BASE_URL/api/im/routing/4" \
  -H "Authorization: Bearer $TOKEN"

200 OK

{ "success": true }

Common errors

  • 401 Unauthorized when not authenticated
  • 403 Forbidden (imAccessDenied) when using a customer-scoped token, or a session without an IM-eligible role
  • 403 Forbidden (imNotEnabled) when Incident Management is not enabled for the organization
  • 403 Forbidden (imTeamWriteDenied) when you do not meet the write bar for the rule's team (or the new team)
  • 400 Bad Request (invalidRequestBody) when :id is not a positive integer, teamId is missing or invalid, priority is not a non-negative integer, severityOverride is not a valid severity, escalationPolicyId is not a positive integer, or match is malformed (wrong types, too many entries)
  • 404 Not Found (imRoutingRuleNotFound) when the rule does not exist, or belongs to another organization
  • 422 Unprocessable Entity (invalidTeamId) when teamId does not belong to your organization
  • 422 Unprocessable Entity (imRoutingInvalidMatchReference) when an ID in match belongs to another organization or does not exist. data.field names the field (source_ids, customer_ids or monitor_ids), data.foreignIds lists the rejected IDs

On this page