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

# On-call schedules, rotations, and overrides

> Create, manage, and maintain on-call schedules in Rootly with rotations, layers, overrides, restrictions, and previews to keep coverage clear and predictable.

## What Are On-Call Schedules?

On-call schedules form the foundation of the Rootly On-Call system. They are critical tools that ensure **alert responsibility** is always clearly assigned and continuously rotating among your team members. These schedules determine **who is on-call at any given time** and control the **rotation** of on-call duties across users or teams.

In Rootly, schedules are not only useful for defining on-call responsibilities but also for organizing who will respond to incidents. A schedule can be as simple as a single user rotating weekly, or as complex as multiple schedules nested within one another, representing different teams or geographies.

However, schedules alone do not trigger notifications or paging—they need to be linked to **Escalation Policies** to become part of the actual alerting process. **Escalation Policies** control the process of how and when on-call users are paged.

***

## Permissions & Access

Before you can create, edit, or delete schedules, certain permissions are required. Only users with the **On-Call Admin** or **On-Call User** roles have the ability to manage schedules. **On-Call Observers**, on the other hand, have read-only access to schedules and cannot modify them.

<Warning>
  **Required Permissions:**\
  To create, edit, or delete schedules, users need the **On-Call Admin** or **On-Call User** role.\
  Users without active on-call seats cannot be added to schedules.
</Warning>

***

## Creating a Schedule

To create a new on-call schedule in Rootly:

<Steps>
  <Step title="Open Schedules">
    Navigate to **On-Call → Schedules** from the main menu.
  </Step>

  <Step title="Start a New Schedule">
    Click **+ New Schedule** to start the process.
  </Step>

  <Step title="Name the Schedule">
    Enter a **Schedule Name** (required) and an optional **Description** that provides more context about the schedule’s purpose.
  </Step>
</Steps>

When naming your schedule, it’s best practice to choose a descriptive name that reflects the team or role associated with the schedule (for example, `Engineering Primary`, `Support - Weekend`, or `Platform Secondary`).

<Info>
  **Note:** The schedule name must be unique within your team to avoid conflicts. Schedule names should be concise, clear, and follow a consistent naming convention.
</Info>

***

### Step 1: Define Rotations

Rotations dictate **how on-call responsibilities rotate** between team members. The **rotation** defines the order in which members are assigned on-call duties.

A rotation is essentially a cycle that determines **who is on call** and **when they will take over the responsibility**. Depending on your organization's needs, you may set up a rotation for a single user or multiple users who rotate through different time slots.

When you define a rotation, you’ll need to give it a **name** that reflects the group or role it pertains to. For example, a rotation for the `Security Team` might simply be called "Security Rotation."

<Warning>
  **Important Reminder:**\
  A schedule can only have **one active rotation at a time**. Make sure that you define the rotation rules clearly to avoid overlaps.
</Warning>

***

### Step 2: Add Rotation Members

In this step, you will **assign users to the rotation**. You can add individual users, teams, or other schedules to a rotation. Adding **schedules as members** allows for nesting, where a team’s schedule can be part of a higher-level schedule.

Each member of the rotation will be assigned a time period based on the rules you set in Step 3. For example, if you choose weekly rotation, the on-call duty will shift every week, and the members will rotate in order.

To assign members:

1. You can either search or use the filters to find the users, teams, or schedules you wish to add.
2. Once added, the members will rotate based on the order they are listed. You can easily adjust the order by **dragging and dropping** members within the list.

When a schedule is nested inside another schedule, the **parent schedule** will call the **current on-call responder** of the **child schedule** when it’s time for the escalation policy to trigger.

<Info>
  **Note:**\
  A **Schedule cannot be part of more than one other schedule's rotation**. This restriction is in place to prevent infinite loops where schedules are circularly dependent on each other.
</Info>

***

### Step 3: Configure Rotation Rules

Now that you've set up the members, it’s time to configure the rotation rules. This step is where you define the **frequency** and **timing** of the rotation.

Rootly provides several options for configuring your rotations:

* **Rotation Types:**
  * Daily
  * Weekly
  * Biweekly
  * Monthly
  * Custom (for example, hourly, daily, weekly)
* **Active Days:**\
  You can define which days of the week your rotation is active.
* **Active Hours:**\
  You can specify whether the rotation is active all day or only for specific hours.
* **Timezone:**\
  Choose the timezone for the rotation. Set it to UTC for around-the-sun setups; use a regional IANA timezone like `Asia/Bangkok` for single-region rotations.

For custom rotations, you can set specific timeframes and choose **shift length** (for example, 8-hour shifts, 12-hour shifts). You also have the option to adjust the **handoff time** for when one rotation ends and another begins.

<Note>
  **Important:**\
  Only one rotation can be active at any given time. If two rotations overlap, Rootly will follow the **bottom-most** rotation logic.
</Note>

***

### Step 4: Add Paging Logic

Once your schedule is set up with rotation rules, you’ll need to link it to an **Escalation Policy** to ensure that the correct person is paged.

An **Escalation Policy** defines **how and when users should be paged**. To page the on-call user, you must:

1. Create an **Escalation Policy**.
2. Assign the schedule to the policy by selecting it as a **notification target** within the escalation steps.
3. Make sure the escalation policy is connected to a **service** or **team** for active monitoring.

<Note>
  **Reminder:**\
  Without being connected to an **Escalation Policy**, a schedule will not trigger any alerts. Ensure that you add the schedule to a policy so it becomes part of the alerting flow.
</Note>

***

## Editing a Schedule

To modify a schedule:

<Steps>
  <Step title="Open Schedules">
    Go to **On-Call → Schedules**.
  </Step>

  <Step title="Open the Schedule Menu">
    Select the schedule you want to edit by clicking the **⋯** menu.
  </Step>

  <Step title="Edit the Schedule">
    Click **Edit** to update the schedule name, description, members, or rotation rules.
  </Step>
</Steps>

***

## Deleting a Schedule

To delete a schedule:

<Steps>
  <Step title="Open Schedules">
    Navigate to **On-Call → Schedules**.
  </Step>

  <Step title="Open the Schedule Menu">
    Find the schedule and click the **⋯** menu.
  </Step>

  <Step title="Delete the Schedule">
    Select **Delete**, and confirm your choice in the dialog window.
  </Step>
</Steps>

<Warning>
  **Important:**\
  Deleting a schedule is **permanent** and cannot be undone. If you want to temporarily stop a schedule, consider deactivating it or removing it from active escalation policies.
</Warning>

***

## Schedule Management Features

The **Schedules Page** in Rootly provides an overview of all schedules, showing:

* **Who is currently on-call** for each schedule
* The **next shift change**
* Which **Escalation Policy** is associated with the schedule
* Filter and search options for easy navigation

You can also sort schedules by **name**, **date created**, and **last updated**.

***

## Coverage Gaps And Fallback

A schedule has a **coverage gap** any time the rotation logic produces an interval with no on-call user — for example, a business-hours rotation outside its active window, a rotation whose users are all deleted or paused, or a layered schedule where no layer covers a particular hour. Rootly surfaces gaps in three places and provides an opt-in fallback to keep paging working through them.

### Where Gaps Show Up In The UI

| Surface           | What You See                                                                                                                                                                                                                                                                        |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Schedule list     | A **Gaps Detected** badge appears on any schedule that currently contains one or more gaps.                                                                                                                                                                                         |
| Schedule editor   | A banner at the top of the editor reads: *"We've detected gaps in your Schedule. Until gaps are filled we will automatically page the Schedule Owner \[name] as the fall-back to ensure full coverage."* The bracketed slot is replaced with the owner's actual name when rendered. |
| Schedule timeline | Hover any uncovered interval in the timeline to see the tooltip *"This is a gap in the schedule, falling back to the schedule owner."* The gap interval itself is not highlighted with a colored marker — gap detail surfaces on hover, not as a per-interval icon.                 |

The same surfaces are used for **unassigned shifts** (rotation interval exists but has no assignee — for example, after a user is removed from the rotation), with the badge labelled *Unassigned Shift Detected* instead.

### Schedule Owner And Fallback Assignee

Every schedule has a **Schedule Owner** and an optional **Fallback Assignee**. These users absorb pages whenever a gap or unassigned shift is detected — Rootly does not silently drop the page.

* **Schedule Owner** — the default fallback. If a gap is detected and no Fallback Assignee is set, the owner gets paged.
* **Fallback Assignee** — an explicit override for the owner. Use this when the owner role is administrative (a team admin) but the actual paging-capable user is someone else.

Both are configured in the schedule's settings under **Schedule Owner** and **Fallback Assignee**.

### Enabling 24/7 Coverage

Turn on **Enable 24/7 coverage for this Schedule** in the schedule settings to make gap detection active. When this is on, Rootly continuously evaluates the schedule for gaps and routes paging to the Fallback Assignee if one is configured, otherwise the Schedule Owner — preserving the precedence described above.

<Warning>
  Gap detection only runs while a rotation is active. If a rotation has an **end date** in the past, Rootly stops detecting gaps after that date — the schedule will appear "gapless" because there is no active rotation to compare against. Audit rotation end dates regularly if you rely on the gap badge to surface coverage problems.
</Warning>

### Finding Gaps Before They Page

The gap surfaces above flag the *current* state of a schedule. To audit future coverage proactively, use:

* The [On-Call Readiness report](/on-call/on-call-readiness) — shows whether every responder in your on-call schedules has working notification methods configured. Confirms *the person* the schedule points to can actually be reached; use it alongside the schedule-side gap surfaces above, not as a replacement.
* The [On-Call Shifts page](/on-call/on-call-shifts) — visualizes generated shifts for the next several weeks; intervals with no assignee make gaps obvious well before they hit production.

***

## Exporting a Schedule to an External Calendar

Rootly allows you to export your on-call schedule to an external calendar so you and your team can view upcoming shifts directly from your preferred calendar app.

Open a schedule in **On-Call → Schedules**, select **Export to Calendar**, and choose **Google Calendar**, **Copy link to ICS File**, or **Download ICS File**. Schedule changes may take time to reflect on external calendars.

## Auditing Schedule Changes

Rootly tracks all changes made to schedules through an **audit log**. This provides transparency, allowing you to track:

* When a schedule was created or modified
* Updates to rotation members or rotation rules
* Changes in shift timings or handoff schedules

To access the audit log, simply start editing the schedule and click on **View Version History** in the top-right corner of the editor.

***

## Best Practices for Managing Schedules

* **Clearly name schedules:** Use descriptive names for schedules to make it easy for teams to identify the right schedule at a glance.
* **Simplify rotations:** Keep rotation cycles simple and clear. Avoid overly complex configurations unless absolutely necessary.
* **Use custom rotations when needed:** For specific teams or roles that need different rotation types, use the custom option to tailor schedules to your needs.
* **Review schedules periodically:** Regularly check schedules to ensure there are no overlaps or issues with rotation rules.
* **Add schedules to Escalation Policies:** Ensure that schedules are linked to the appropriate escalation policies to ensure timely paging.

***

## Frequently Asked Questions (FAQs)

<AccordionGroup>
  <Accordion title="How do I ensure no one misses a shift?" icon="clock-rotate-left">
    To ensure on-call responders are actually notified, your schedule must be connected to an **Escalation Policy**.\
    Schedules by themselves only define *who* is on call—they do not trigger paging. Once a schedule is added as a notification target in an escalation policy and that policy is assigned to a service or team, Rootly can page the active on-call responder reliably.
  </Accordion>

  <Accordion title="Can I assign a team directly to a schedule?" icon="calendar">
    No. Schedules can only contain **individual users** or **other schedules**.\
    Teams are not valid members of a schedule rotation. If you want a team to participate in on-call, create a schedule for that team and then nest that schedule inside a higher-level schedule if needed.
  </Accordion>

  <Accordion title="What if I need to pause a schedule instead of deleting it?" icon="pause">
    If you need to temporarily stop a schedule from paging responders, you do not need to delete it.\
    Instead, remove the schedule from any associated escalation policies or deactivate it. This preserves the schedule configuration while preventing it from triggering alerts.
  </Accordion>

  <Accordion title="How do I manage overlapping rotations?" icon="circle-info">
    Rootly allows multiple rotations within a single schedule, but only **one rotation can be active at any given time**.\
    If rotation rules overlap, Rootly automatically prioritizes the **bottom-most rotation** in the list. To control which logic applies, ensure your rotations are ordered intentionally and reviewed for overlap.
  </Accordion>

  <Accordion title="Where does Rootly show me coverage gaps on a schedule?" icon="triangle-exclamation">
    Three places: a **Gaps Detected** badge on the schedule list card, a banner on the schedule editor, and a hover tooltip on gap intervals in the timeline. There is no colored per-interval marker — timeline detail surfaces on hover. See [Coverage Gaps And Fallback](#coverage-gaps-and-fallback) for the full mechanism and the rotation-end-date caveat that can silently disable detection.
  </Accordion>

  <Accordion title="What happens if a gap is detected and no one is on call?" icon="user-shield">
    Rootly pages the **Schedule Owner** (or the **Fallback Assignee** if one is configured) so the alert never silently drops. Both are set in the schedule's settings. Enable **24/7 coverage** to make this fallback active.
  </Accordion>

  <Accordion title="How do I export my schedules for backup or source control?" icon="download">
    There's no in-product "Download" or "Export" button for schedule configuration today — bulk export is programmatic. (Note: this is different from [exporting a schedule to an external calendar](#exporting-a-schedule-to-an-external-calendar), which produces an iCal feed for viewing shifts.) Three paths cover the common needs:

    * **API.** `GET /v1/schedules` returns every schedule on your account. Walk into each schedule with `GET /v1/schedules/{id}/schedule_rotations`, then `GET /v1/schedule_rotations/{id}/schedule_rotation_users` and `/schedule_rotation_active_days` to capture the full structure.
    * **CLI.** The [Rootly CLI](/integrations/cli) supports `rootly oncall list --format=json` to dump every schedule as JSON in one command.
    * **Terraform.** Use the [Terraform provider](/integrations/terraform) with the `rootly_schedule`, `rootly_schedule_rotation`, `rootly_schedule_rotation_user`, `rootly_schedule_rotation_active_day`, and `rootly_override_shift` resources. The [Importing Existing Resources](/integrations/terraform#importing-existing-resources) workflow pulls your existing schedules into Terraform state so they live in source control going forward.
  </Accordion>
</AccordionGroup>

***

On-call schedules are central to keeping your team responsive, organized, and ready. Once set up, they enable seamless transitions and ensure that alerts are always addressed in a timely manner, no matter the time zone or time of day.

***

## Related Pages

<CardGroup cols={3}>
  <Card title="Escalation Policies" icon="stairs" href="/on-call/escalation-policies">
    Where schedules are wired in — a schedule pages nobody until an escalation policy references it.
  </Card>

  <Card title="Editing Schedules" icon="pen" href="/on-call/edit-schedules">
    How to modify existing schedules, pause without deleting, and manage rotations over time.
  </Card>

  <Card title="Holiday Calendar" icon="party-horn" href="/on-call/holiday-calendar">
    Overlay holidays and PTO to catch coverage conflicts before they turn into missed pages.
  </Card>
</CardGroup>
