On-Call Schedules
An on-call schedule answers one question: who should be notified right now? Use it as a recipient in a notification role or an escalation policy, and the alert goes to whoever is on call when it is sent.
Schedules are included in the Business plans.
How Xitoring decides who is on call
Xitoring checks these in order and stops at the first match:
- An override covering that moment. If overrides overlap, the newest one wins.
- The layers, from the lowest position to the highest. The first layer with someone on duty at that moment wins. On a holiday, the first layer is skipped.
- Nobody. The schedule adds no recipient, and the role's other recipients are still notified.
A common setup is a follow-the-sun or weekend rotation at the top, with a weekly rotation underneath that covers every hour the top layer doesn't.
Time zone
Each schedule has one time zone, such as Europe/Berlin. Handoff times, restrictions and holidays are all read in it. Reminders are shown in each person's own time zone. Accounts start on UTC, so someone who has never set a time zone sees UTC.
Layers and rotations
Each layer has its own rotation:
| Setting | What it means |
|---|---|
| Position | 1 to 100. Lower positions are checked first. New layers go to the end |
| Name | Optional |
| Rotation | Daily, Weekly, or Custom with a shift length of 1 to 720 hours |
| Handoff time | When one shift ends and the next starts, as HH:MM |
| Start date | The first shift starts on this date at the handoff time. The layer is empty before that |
| Members | Up to 50 people, each at most once, in rotation order. Each must be the account owner or a team member |
| Restrictions | Optional. See below |
Things to know:
- The rotation is worked out from the start date. Adding, removing or reordering members can change who is on call straight away, and can change who has the upcoming shifts.
- Daily and weekly shifts keep the same local handoff time across daylight saving changes. Custom shifts count real hours, so their local handoff time moves by an hour when the clocks change.
Restrictions
Restrictions limit a layer to certain hours, such as weekdays from 09:00 to 17:00. Outside them the layer has nobody on duty and Xitoring moves to the next layer.
Each layer can have up to 14 windows. A window has its days (1 is Monday, 7 is Sunday), a start time and an end time.
- If the end is earlier than the start, the window runs past midnight into the next day.
22:00to06:00on Friday ends on Saturday morning. - The rotation keeps counting during restricted hours, so a restriction doesn't delay anyone's turn.
Overrides
An override puts one person on call for a set time and beats every layer. Use it for sick days, swaps and handovers.
- The person can be the account owner or any team member, whether or not they are in a layer.
- The end must be after the start, and at most one year from now.
- You can add a reason of up to 255 characters.
- Deleting an override returns that time to the rotation.
Holidays
A holiday is a date in the schedule's time zone, with a name. For that whole date, the first layer (the lowest position) is skipped and the next layer takes over.
Use this with a primary rotation on top and a smaller holiday rotation underneath. On a schedule with only one layer, nobody is on call on a holiday unless there is an override. Overrides still apply on holidays.
Each date can be added once per schedule, and holidays don't repeat each year.
Cover requests
If you can't take your shift, ask your team to cover it instead of arranging an override yourself.
- Ask for cover for a time window. You must be on call for all of it, it must end in the future, and it can span at most 31 days. A start in the past is moved to now.
- Everyone else in the schedule's layers is notified by email, push notification and Slack direct message, if they use the Slack app.
- They answer under On-call in Xitoring. The first person to accept takes the shift: Xitoring creates an override for them, and you are notified.
- If everyone declines, the request closes and you are notified.
A few rules:
- You can't have two open requests for overlapping time on a schedule.
- Someone with their own open request for that time can't accept yours.
- You can cancel your own request while it is open. So can anyone who can edit the schedule.
- A request nobody answered expires at the end of its window.
Use a schedule as a recipient
Add a schedule as a recipient on a notification role or on an escalation policy step. Deleting a schedule removes it from both.
Calendar subscription
Subscribe to on-call shifts in any calendar app that reads iCal URLs.
| Feed | Shows |
|---|---|
| My shifts | Your own shifts across all schedules in the account |
| One schedule | Everyone's shifts on that schedule |
Create a feed to get its URL, then add it to your calendar:
- Google Calendar: Other calendars → + → From URL.
- Outlook: Add calendar → Subscribe from web.
- Apple Calendar: File → New Calendar Subscription.
Good to know:
- A feed covers the past 7 days and the next 60 days. Calendar apps refresh subscriptions on their own timing, so changes can take a while to show.
- The URL works without logging in, so treat it like a password. Xitoring shows it only when it is created.
- Creating a feed again replaces the URL and the old one stops working. You can also revoke a feed.
- A feed stops working if you leave the account, the schedule is deleted, or the account no longer has a Business plan.
Shift reminders
Xitoring sends each person a reminder by email and push notification:
- Before a shift starts. 30 minutes before by default. You can set this from 0 to 1440 minutes (24 hours), and it applies to all your schedules.
0turns this reminder off. - When a shift has ended. This one is always sent.
Back-to-back shifts for the same person count as one shift, even across layers.
API
Authenticate with an API key. All paths start with /api/v2/oncall.
| Request | What it does |
|---|---|
GET /now | Who is on call now, per schedule |
GET /schedules | List schedules |
POST /schedules | Create a schedule: name, timezone, optional description |
GET /schedules/{id} | Layers, overrides, holidays and who is on call |
PUT /schedules/{id} | Update a schedule |
DELETE /schedules/{id} | Delete a schedule |
GET /schedules/{id}/shifts | Final shift timeline. from and to default to the next 7 days, and can span at most 93 days. A shift with no member means nobody is on call |
POST /schedules/{id}/layers | Add a layer |
PUT /schedules/{id}/layers/{layerId} | Update a layer. Sending members replaces the list |
DELETE /schedules/{id}/layers/{layerId} | Delete a layer |
POST /schedules/{id}/overrides | Add an override: member, starts_at, ends_at, optional reason |
DELETE /schedules/{id}/overrides/{overrideId} | Delete an override |
POST /schedules/{id}/holidays | Add a holiday: date, name |
DELETE /schedules/{id}/holidays/{holidayId} | Delete a holiday |
GET /cover-requests | List cover requests. status is open (default) or all. Optional schedule_id |
POST /schedules/{id}/cover-requests | Ask for cover: starts_at, ends_at, optional reason |
POST /cover-requests/{id}/accept | Accept a cover request |
POST /cover-requests/{id}/decline | Decline a cover request |
DELETE /cover-requests/{id} | Cancel a cover request |
POST /schedules/{id}/calendar-feed | Create a schedule feed and return its URL |
DELETE /schedules/{id}/calendar-feed | Revoke your schedule feed |
POST /my-calendar-feed | Create your personal feed and return its URL |
DELETE /my-calendar-feed | Revoke your personal feed |
GET /my-settings | Your reminder setting and feeds |
PUT /my-settings | Set reminder_minutes |
Send times in ISO 8601 with an offset, such as 2026-11-09T18:00:00+01:00. The API reads a time without an offset as UTC.
A layer looks like this:
{
"position": 1,
"name": "Business hours",
"rotation": "weekly",
"handoff_time": "09:00",
"starts_on": "2026-11-09",
"restrictions": [
{"days": [1, 2, 3, 4, 5], "start": "09:00", "end": "17:00"}
],
"members": [
{"type": "client", "id": 3},
{"type": "contact", "id": 7}
]
}
For a custom rotation, use "rotation": "custom" with custom_shift_hours. In members, client is the account owner and contact is a team member.
From an AI assistant
The MCP server has list_on_call_schedules, get_on_call_schedule, who_is_on_call and create_on_call_override. Unlike the API, these tools read a time without an offset in the schedule's time zone.