On-Call & Escalations

Escalation policies, rotation schedules and phone-call alerts that actually wake people up.

What an escalation policy is

An escalation policy is an ordered chain of steps that fire when a monitor goes down and nobody has acknowledged it. Each step has a level, a wait_minutes delay, and a set of contacts — if step 1 goes unanswered, step 2 fires, and so on up the chain.

The last step can be a phone call — a ringing phone at 3 AM wakes people up in a way a muted Slack channel does not.

Building a policy

curl -X POST https://api.shxrk.systems/api/v1/uptime/status-pages/<id>/on-call/policies \
  -H "Authorization: Bearer sk_shx_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "primary-oncall",
    "is_default": true,
    "steps": [
      {
        "level": 1,
        "wait_minutes": 0,
        "contacts": [
          { "type": "email", "value": "[email protected]" },
          { "type": "slack", "value": "https://hooks.slack.com/services/..." }
        ]
      },
      {
        "level": 2,
        "wait_minutes": 10,
        "contacts": [
          { "type": "sms", "value": "+4915123456789" },
          { "type": "call", "value": "+4915123456789" }
        ]
      }
    ]
  }'

Contact type values: email, discord, slack, sms, call. A step fires all of its contacts at once; wait_minutes delays the step relative to the alert starting.

Assigning policies

  • A policy with is_default: true covers every monitor on the page
  • A single monitor can carry its own escalation_policy_id — set it on the monitor for per-service chains ("database pages the DBA, frontend pages nobody")

Rotation schedules

Schedules define who is on-call right now: named rotations with shifts (start_at/end_at, per user_id, in a timezone). The escalation worker resolves the active shift at alert time, so the same policy always reaches the current on-call person — no policy edits when rotations change.

GET /status-pages/:id/on-call/schedules
POST /status-pages/:id/on-call/schedules
GET /PUT/DELETE /status-pages/:id/on-call/schedules/:scheduleId

Billing notes

email, discord and slack contacts are free. sms and call contacts consume your SMS/Call add-on quota — metered per delivered message/call, reserved at alert time so an exhausted quota degrades gracefully instead of failing mid-escalation.

Managing policies

GET /status-pages/:id/on-call              # active policy
GET/POST /status-pages/:id/on-call/policies
PUT/DELETE /status-pages/:id/on-call/policies/:policyId
GET /status-pages/:id/on-call/policies/export
POST /status-pages/:id/on-call/policies/import

Import/export makes it easy to copy a proven escalation chain across status pages.