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

# On-call Schedules

> Define who is on-call, how rotations work, and how scaling.cloud determines the current on-call responder at any point in time.

An on-call schedule defines a group of team members who rotate responsibility for responding to incidents. Each schedule has one or more **rotation layers** that determine who is on-call at any given time based on a repeating cycle.

Schedules are the building blocks for escalation policies. When an escalation policy targets a schedule, scaling.cloud looks at the schedule's active layers to determine who to notify.

## Schedule fields

| Field         | Required | Notes                                                                                                                        |
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `name`        | Yes      | 1–255 characters. Must be unique within your organization.                                                                   |
| `description` | No       | Optional context about the schedule's purpose.                                                                               |
| `timezone`    | Yes      | An IANA timezone identifier, e.g. `America/New_York` or `Europe/London`. All handoff times are interpreted in this timezone. |

<Tip>
  Always set the schedule timezone to match where the majority of your on-call
  team is based. This ensures handoff times behave as expected — for example, a
  `09:00` handoff will fire at 9 AM local time for your team.
</Tip>

## Rotation layers

Each schedule can have multiple rotation layers. A layer defines a repeating on-call cycle for a specific group of participants.

Layers within a schedule are **ordered by `position`** — an integer (unique per schedule) where **position 0 is the owner-bearing layer**. Lower position = higher precedence for ownership resolution. The position determines:

* Which layer's resolved participant becomes the **Schedule Owner** (used to populate the incident **Lead** at incident creation).
* Which layer the schedule-wide override displaces when the override is active.
* The display order of layers in the UI.

New layers are appended at the next available position. Use the schedule edit screen — or the [layer reorder endpoint](/api/oncall/layers#put-oncall-schedules-scheduleid-layers-order) — to change the order.

When scaling.cloud pages for an incident whose escalation policy targets this schedule, **every** currently-active layer's resolved participant gets paged — not just position 0. Use position to decide who owns the schedule, not who gets paged.

### Layer fields

| Field                | Required | Notes                                                                                                                                |
| -------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `name`               | Yes      | 1–255 characters. Must be unique within the schedule.                                                                                |
| `position`           | Auto     | Assigned by the server. Lower = higher precedence; position 0 is the owner-bearing layer. Change with the layer reorder endpoint.    |
| `rotationType`       | Yes      | `daily`, `weekly`, or `custom`. See rotation types below.                                                                            |
| `rotationLengthDays` | Yes      | The length of each rotation shift in days. Minimum 1.                                                                                |
| `handoffTime`        | Yes      | The time of day when the rotation shifts to the next participant. Format: `HH:MM` (24-hour), interpreted in the schedule's timezone. |
| `effectiveFrom`      | Yes      | ISO 8601 datetime. When this layer becomes active.                                                                                   |
| `effectiveUntil`     | No       | ISO 8601 datetime. When this layer expires. Omit for an open-ended layer.                                                            |
| `participantIds`     | Yes      | An ordered list of org member IDs who rotate through this layer. 1–100 members. The order determines rotation sequence.              |

### Rotation types

<Tabs>
  <Tab title="Daily">
    Each participant is on-call for one calendar day before the rotation shifts to the next person. Set `rotationLengthDays` to `1`.

    ```json theme={null}
    {
      "rotationType": "daily",
      "rotationLengthDays": 1,
      "handoffTime": "09:00"
    }
    ```
  </Tab>

  <Tab title="Weekly">
    Each participant is on-call for one full week. Set `rotationLengthDays` to `7`.

    ```json theme={null}
    {
      "rotationType": "weekly",
      "rotationLengthDays": 7,
      "handoffTime": "09:00"
    }
    ```
  </Tab>

  <Tab title="Custom">
    Each participant is on-call for a custom number of days. Set `rotationLengthDays` to any value of 1 or more.

    ```json theme={null}
    {
      "rotationType": "custom",
      "rotationLengthDays": 3,
      "handoffTime": "08:00"
    }
    ```
  </Tab>
</Tabs>

<Note>
  The `rotationType` field is informational and used to label the rotation in
  the UI. The actual rotation calculation always uses `rotationLengthDays`.
</Note>

## Participant order

The order of `participantIds` defines the rotation sequence. The first participant in the list is on-call starting from `effectiveFrom`. After `rotationLengthDays` days at `handoffTime`, the second participant takes over — and so on, cycling back to the first when the list is exhausted.

To change the rotation order, update the layer with the full `participantIds` array in the new sequence.

## Querying who is on-call

You can ask scaling.cloud who is currently on-call for any schedule. The [`GET /oncall/schedules/{scheduleId}/resolve`](/api/oncall/schedules#get-oncall-schedules-scheduleid-resolve) endpoint returns three views in one response:

* **`owner`** — the single **Schedule Owner** (used to populate the incident **Lead**). The lowest-positioned currently-active layer's resolved participant, with that layer's override applied if active. Falls through to the next position when position 0 is between effective windows. `null` if no layer is active.
* **`pagingTargets`** — the full set of users an escalation policy targeting this schedule would page right now. One entry per currently-active layer in position order, with each layer's override applied.
* **`currentOncallView`** — a richer breakdown with per-entry `position`, `source` (`rotation` or `override`), and (when applicable) the displaced `overriddenUser` and `viaOverrideId`.

Pass an `at` query parameter to resolve at a specific point in time instead of now.

```json theme={null}
{
  "owner": {
    "user": {
      "id": "user_bbb",
      "firstName": "Alice",
      "lastName": "Chen",
      "email": "alice@acme.io"
    }
  },
  "pagingTargets": [
    {
      "user": {
        "id": "user_bbb",
        "firstName": "Alice",
        "lastName": "Chen",
        "email": "alice@acme.io"
      }
    }
  ],
  "currentOncallView": {
    "scheduleId": "sch_01j...",
    "resolvedAt": "2026-04-07T10:00:00.000Z",
    "owner": {
      "user": {
        "id": "user_bbb",
        "firstName": "Alice",
        "lastName": "Chen",
        "email": "alice@acme.io"
      }
    },
    "entries": [
      {
        "rotationLayerId": "lay_01j...",
        "rotationLayerName": "Primary",
        "position": 0,
        "user": {
          "id": "user_bbb",
          "firstName": "Alice",
          "lastName": "Chen",
          "email": "alice@acme.io"
        },
        "source": "rotation"
      }
    ]
  }
}
```

If `entries` is empty (and therefore `owner` is `null` and `pagingTargets` is `[]`), no layers are active for that schedule at the requested time.
