> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Resolve rotations and plan escalations

> Model who is on call at any instant, and flatten an escalation policy into the ordered page timeline an incident driver would walk — as pure compute, with no pages sent.

## Resolve rotations and plan escalations

On-call tooling and the incident driver both live behind these two endpoints — the call resolves who is accountable at a given instant, and the plan flattens the escalation ladder you would walk when an incident refuses an ACK. Both are pure compute: nothing is persisted, no pages are sent, and no state changes. An incident driver (the webhook-worker escalation scheduler) still fires pages through the notify channel downstream.

**Resolve a rotation.** `POST /api/v1/oncall/resolve` answers "who is on call now" — a rotation is a fixed-length shift schedule anchored to an absolute start (`anchor`), with `members` rotating through it in order.

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "rotation_name": "core-rotation",
      "at": "2026-08-01T12:00:00.000Z",
      "on_call": "+14155552671",
      "shift_index": 12,
      "shift_start": "2026-07-31T12:00:00.000Z",
      "shift_end": "2026-08-01T12:00:00.000Z",
      "next_on_call": "+14155559900",
      "next_handoff_at": "2026-08-01T12:00:00.000Z"
    },
    "meta": {
      "request_id": "req_resolve",
      "timestamp": "2026-08-01T12:00:00.000Z"
    }
  }
  ```
</ResponseExample>

**Plan an escalation.** `POST /api/v1/oncall/escalation/plan` flattens the policy into the ordered `pages` timeline: each step names a target (a live rotation resolved at the page's fire instant, or a static member list), the channels paged, and the `escalate_after_seconds` window before the next step. Each layer of the walk fires at a cumulative `offsetSeconds` from the incident start; `policy.repeat` loops the whole policy that many extra times if no step is ever acknowledged.

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "policy_name": "core-support",
      "start_at": "2026-08-01T12:00:00.000Z",
      "total_pages": 4,
      "pages": [
        {
          "round": 0,
          "step": 0,
          "offset_seconds": 0,
          "fire_at": "2026-08-01T12:00:00.000Z",
          "targets": ["+14155552671"],
          "channels": ["sms"]
        },
        {
          "round": 0,
          "step": 1,
          "offset_seconds": 300,
          "fire_at": "2026-08-01T12:05:00.000Z",
          "targets": ["oncall-secondary"],
          "channels": ["voice", "sms"]
        }
      ]
    },
    "meta": {
      "request_id": "req_plan",
      "timestamp": "2026-08-01T12:00:00.000Z"
    }
  }
  ```
</ResponseExample>

Rotation targets resolve at each page's fire instant, so a hand-off that lands mid-escalation reaches the right human.
