Pingtower Docs
Docs The service On-call schedules

On-call schedules

A schedule answers "who is on call right now". Rules name schedules in their escalation ladders, so the rule never changes when the rota does.

API only for nowSchedules, overrides and the who-is-on-call-now answer are served by the hosted service and by self-hosted boxes alike. The iOS app does not yet have screens for them; manage them from the API until it does.

Layers and rotations

A schedule is per project. It has a timezone and one or more layers. Each layer rotates through its participants every shift_minutes, starting at rotation_start. A layer with a restriction is active only inside that window, and a later layer wins over an earlier one while both are active. That is how “weekday office hours go to the ops account, everything else to the weekly rota” is written.

POST /v1/projects/{id}/oncall/schedules

{
  "name": "backend-primary",
  "timezone": "Europe/Stockholm",
  "layers": [
    { "name": "weekly",
      "participants": ["[email protected]", "[email protected]", "[email protected]"],
      "rotation_start": 1756677600, "shift_minutes": 10080 },
    { "name": "office-hours",
      "participants": ["[email protected]"],
      "rotation_start": 1756677600, "shift_minutes": 1440,
      "restriction": { "days": [1, 2, 3, 4, 5], "start_minute": 540, "end_minute": 1080 } }
  ]
}

rotation_start is a unix timestamp. days are 0 Sunday through 6 Saturday. start_minute and end_minute are minutes after midnight in the schedule’s timezone; an end before a start wraps overnight. Participants must be members of the tenant; a stranger is a 422 naming them.

GET PUT DELETE /v1/projects/{id}/oncall/schedules/{sid}.

Overrides

An override swaps one person in for a window without editing the rota. Newest override wins where two overlap.

POST /v1/projects/{id}/oncall/schedules/{sid}/overrides

{ "account_id": "…", "starts_at": 1756800000, "ends_at": 1756886400 }

Unix timestamps, half-open [starts_at, ends_at), at most a year long. GET lists them; DELETE …/overrides/{oid} removes one.

Who is on call now

GET /v1/projects/{id}/oncall/schedules/{sid}/current

{ "on_call": true, "account_id": "…", "email": "[email protected]", "via": "layer:weekly" }

Using it from a rule

Name the schedule in an escalation rung: {"after_minutes": 15, "schedules": ["backend-primary"]}. When the rung is reached the schedule is resolved at that instant and the person on call is added to the page. Shift changes emit oncall.shift_started and oncall.shift_ended events to integrations that subscribe to them.

Deleting a schedule a rule still namesReturns 409 with the rules referencing it. Remove it from those ladders first; a rung that pointed at nothing would page nobody. Removing a member who is a participant is refused the same way, listing the schedules, escalations and overrides that name them.
Last updated 1 Sep 2026 Report a problem with this page