Endpoints

Escalation policies

GET/api/v1/organizations/{org_id}/escalation-policies

Every escalation policy in the active org, name-ordered.

Authorization

HTTPBearer
AuthorizationBearer <token>

In: header

Path Parameters

org_id*Org Id
Formatuuid

Response Body

application/json

application/json

curl -X GET "https://example.com/api/v1/organizations/497f6eca-6276-4993-bfeb-53cbbbba6f08/escalation-policies"
{  "items": [    {      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",      "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",      "name": "string",      "is_system": true,      "levels": [        {          "level": 0,          "notify_users": [            "0b2f0d78-0e33-4642-88bd-6777402bee1c"          ],          "notify_roles": [            "string"          ],          "timeout_minutes": 0        }      ],      "repeat_after_minutes": 0    }  ]}
POST/api/v1/organizations/{org_id}/escalation-policies

Authorization

HTTPBearer
AuthorizationBearer <token>

In: header

Path Parameters

org_id*Org Id
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

POST /organizations/{org_id}/escalation-policies body.

Response Body

application/json

application/json

curl -X POST "https://example.com/api/v1/organizations/497f6eca-6276-4993-bfeb-53cbbbba6f08/escalation-policies" \  -H "Content-Type: application/json" \  -d '{    "name": "string",    "levels": [      {        "level": 1,        "timeout_minutes": 1      }    ]  }'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",  "name": "string",  "is_system": true,  "levels": [    {      "level": 0,      "notify_users": [        "0b2f0d78-0e33-4642-88bd-6777402bee1c"      ],      "notify_roles": [        "string"      ],      "timeout_minutes": 0    }  ],  "repeat_after_minutes": 0}
POST/api/v1/organizations/{org_id}/escalation-policies/deviceless-check

#727's read-side of the deviceless check — the console (#731) POSTs a draft's levels here while editing, before submit, and gets back the same per-level verdict create/update would enforce, without persisting anything. Read-only, so require_any_member (matching list/get above) rather than the write gate. Unlike the write path, this endpoint never raises on a failing level — a live editor wants the verdict rendered inline, not an error response for every in-progress keystroke; valid is what a submit button gates on.

Authorization

HTTPBearer
AuthorizationBearer <token>

In: header

Path Parameters

org_id*Org Id
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

POST /organizations/{org_id}/escalation-policies/deviceless-check body (#727) — the live-editor preview the console (#731) polls while a policy is being drafted, before submit. Deliberately does not run EscalationPolicyCreate/Update's _levels_sequence contiguity validator: a draft mid-edit (levels reordered, one being inserted) can be transiently non-contiguous, and deviceless-ness is orthogonal to ordering — the write path still enforces contiguity at submit time. An empty levels list is valid and returns an empty, vacuously-valid response, matching a fresh unstarted draft.

Response Body

application/json

application/json

curl -X POST "https://example.com/api/v1/organizations/497f6eca-6276-4993-bfeb-53cbbbba6f08/escalation-policies/deviceless-check" \  -H "Content-Type: application/json" \  -d '{}'
{  "valid": true,  "levels": [    {      "level": 0,      "resolved_user_count": 0,      "deviceless": [        {          "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",          "email": "string"        }      ],      "ok": true    }  ]}
GET/api/v1/organizations/{org_id}/escalation-policies/{policy_id}

One policy by id, within the active org — 404, never 403, across tenants, matching every other org-scoped route in this codebase. Returns the full policy (every level's targeting) in one call, per #724's acceptance criteria for the console editor (#731).

Authorization

HTTPBearer
AuthorizationBearer <token>

In: header

Path Parameters

org_id*Org Id
Formatuuid
policy_id*Policy Id
Formatuuid

Response Body

application/json

application/json

curl -X GET "https://example.com/api/v1/organizations/497f6eca-6276-4993-bfeb-53cbbbba6f08/escalation-policies/497f6eca-6276-4993-bfeb-53cbbbba6f08"
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",  "name": "string",  "is_system": true,  "levels": [    {      "level": 0,      "notify_users": [        "0b2f0d78-0e33-4642-88bd-6777402bee1c"      ],      "notify_roles": [        "string"      ],      "timeout_minutes": 0    }  ],  "repeat_after_minutes": 0}
PATCH/api/v1/organizations/{org_id}/escalation-policies/{policy_id}

is_system policies accept only levels[*].notify_users/ notify_roles changes — see EscalationPolicyService._enforce_system_policy_restrictions.

Authorization

HTTPBearer
AuthorizationBearer <token>

In: header

Path Parameters

org_id*Org Id
Formatuuid
policy_id*Policy Id
Formatuuid

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

PATCH /organizations/{org_id}/escalation-policies/{policy_id} body.

Every field optional — model_fields_set decides what actually changes, matching TeamUpdate's convention (app/schemas/team.py). is_system-policy field restrictions are enforced in the service layer, not here — see EscalationPolicyService._enforce_system_policy_restrictions for the exact rule and the doc it implements.

Response Body

application/json

application/json

curl -X PATCH "https://example.com/api/v1/organizations/497f6eca-6276-4993-bfeb-53cbbbba6f08/escalation-policies/497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "Content-Type: application/json" \  -d '{}'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "org_id": "a40f5d1f-d889-42e9-94ea-b9b33585fc6b",  "name": "string",  "is_system": true,  "levels": [    {      "level": 0,      "notify_users": [        "0b2f0d78-0e33-4642-88bd-6777402bee1c"      ],      "notify_roles": [        "string"      ],      "timeout_minutes": 0    }  ],  "repeat_after_minutes": 0}
DELETE/api/v1/organizations/{org_id}/escalation-policies/{policy_id}

is_system (seeded default) policies cannot be deleted.

Authorization

HTTPBearer
AuthorizationBearer <token>

In: header

Path Parameters

org_id*Org Id
Formatuuid
policy_id*Policy Id
Formatuuid

Response Body

application/json

curl -X DELETE "https://example.com/api/v1/organizations/497f6eca-6276-4993-bfeb-53cbbbba6f08/escalation-policies/497f6eca-6276-4993-bfeb-53cbbbba6f08"
Empty