> ## 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 API

> Create an on-call schedule, add rotation layers, and check who is currently on call using the scaling.cloud API.

On-call schedules define who is responsible for responding to incidents during any given time window. A schedule contains one or more rotation layers, each with its own rotation type, handoff time, and list of participants.

This guide walks you through creating a schedule, adding a rotation layer, and checking who is currently on call over the REST API.

<Tip>
  Prefer to work in the dashboard? See [Set Up On-call](/guides/set-up-oncall-schedule) for the UI walkthrough.
</Tip>

<Steps>
  <Step title="Create a schedule">
    Send a `POST` request to `/api/oncall/schedules` with a name and IANA timezone identifier.

    ```bash theme={null}
    curl -X POST https://api.scaling.cloud/v1/oncall/schedules \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Platform On-call",
        "description": "Primary platform rotation",
        "timezone": "America/New_York"
      }'
    ```

    A successful response returns the new schedule:

    ```json theme={null}
    {
      "data": {
        "id": "sched_01jqm5x3k8vz9e2f4g7h",
        "orgId": "org_01jqm4ab2c3de5fg6hij",
        "name": "Platform On-call",
        "description": "Primary platform rotation",
        "timezone": "America/New_York",
        "createdBy": "user_01jqm3xy4z5abc6de7fg",
        "createdAt": "2026-04-07T10:00:00.000Z",
        "updatedAt": "2026-04-07T10:00:00.000Z"
      }
    }
    ```

    <Tip>
      Always use IANA timezone identifiers (e.g., `America/New_York`, `Europe/London`, `Asia/Tokyo`) rather than abbreviations like `EST` or `UTC+5`. IANA identifiers automatically account for daylight saving time changes. You can find the full list at [iana.org/time-zones](https://www.iana.org/time-zones) or use a reference like the [tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
    </Tip>
  </Step>

  <Step title="Add a rotation layer">
    A rotation layer defines when the schedule is active and which participants rotate through it. Send a `POST` request to `/api/oncall/schedules/{scheduleId}/layers`, replacing `{scheduleId}` with the ID returned in the previous step.

    ```bash theme={null}
    curl -X POST https://api.scaling.cloud/v1/oncall/schedules/sched_01jqm5x3k8vz9e2f4g7h/layers \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Primary",
        "rotationType": "weekly",
        "rotationLengthDays": 7,
        "handoffTime": "09:00",
        "effectiveFrom": "2026-01-01T00:00:00.000Z",
        "participantIds": ["user_aaa", "user_bbb", "user_ccc"]
      }'
    ```

    The response returns the created layer:

    ```json theme={null}
    {
      "data": {
        "id": "layer_01jqm6a2b3cd4ef5gh6i",
        "scheduleId": "sched_01jqm5x3k8vz9e2f4g7h",
        "orgId": "org_01jqm4ab2c3de5fg6hij",
        "name": "Primary",
        "rotationType": "weekly",
        "rotationLengthDays": 7,
        "handoffTime": "09:00",
        "effectiveFrom": "2026-01-01T00:00:00.000Z",
        "effectiveUntil": null,
        "participantIds": ["user_aaa", "user_bbb", "user_ccc"],
        "createdAt": "2026-04-07T10:05:00.000Z",
        "updatedAt": "2026-04-07T10:05:00.000Z"
      }
    }
    ```

    Key fields to know:

    | Field                | Description                                                                           |
    | -------------------- | ------------------------------------------------------------------------------------- |
    | `rotationType`       | One of `daily`, `weekly`, or `custom`                                                 |
    | `rotationLengthDays` | Number of days per rotation shift (minimum 1)                                         |
    | `handoffTime`        | Time of day the rotation switches, in `HH:MM` 24-hour format                          |
    | `effectiveFrom`      | ISO 8601 datetime when this layer becomes active                                      |
    | `effectiveUntil`     | Optional ISO 8601 datetime when this layer expires; `null` means it runs indefinitely |
    | `participantIds`     | Ordered list of user IDs who rotate through the layer                                 |

    Participants rotate in the order listed. The first user in `participantIds` is on call starting at `effectiveFrom`, then each subsequent user takes over after `rotationLengthDays` days at `handoffTime`.
  </Step>

  <Step title="Check who is currently on call">
    Query the schedule to see which participant is currently on call. Send a `GET` request to `/api/oncall/schedules/{scheduleId}/resolve`.

    ```bash theme={null}
    curl https://api.scaling.cloud/v1/oncall/schedules/sched_01jqm5x3k8vz9e2f4g7h/resolve \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    The response returns the **Schedule Owner** (used as the incident **Lead**), the **Paging Targets** (full set the schedule would page), and a `currentOncallView` with per-layer detail:

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

    To check who would be on call at a specific point in time, add an `at` query parameter with an ISO 8601 datetime:

    ```bash theme={null}
    curl "https://api.scaling.cloud/v1/oncall/schedules/sched_01jqm5x3k8vz9e2f4g7h/resolve?at=2026-04-14T09:00:00.000Z" \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    If `entries` is empty, no layer is active at the requested time. Check that your layer's `effectiveFrom` has passed and that `effectiveUntil` has not expired.
  </Step>
</Steps>
