---
title: "Hand duty over temporarily"
method: POST
path: "/api/v1/schedules/{schedule}/overrides"
tags: ["On-call schedules"]
---

# Hand duty over temporarily

`POST /api/v1/schedules/{schedule}/overrides`

## Request

- Base URL: `https://wardenpoint.com` (the document declares no server; this is the origin it was published from)
- URL: `https://wardenpoint.com/api/v1/schedules/{schedule}/overrides`
- Auth: API key in header `X-API-Key`

Puts somebody else on duty for a window without editing the rotation: the resolver consults handovers before shifts, so when the window ends the original person resumes on their own and nothing has to be restored. Who is being covered for is captured at creation time and reported as `replacing`. Not idempotent — repeating the call creates a second handover, and the later-starting one wins where they overlap. The window may not exceed 30 days.

## Path parameters

- `schedule` string, uuid, required

## Request body

- ScheduleOverrideRequest
  - `role` 'primary' | 'secondary' | 'manager', required: Which slot of the rotation is handed over.
  - `recipient_uuid` string, uuid, required: Who stands in. Must be a recipient of this company.
  - `starts_at` string, date-time, required: ISO-8601 WITH an explicit offset ("2026-08-10T09:00:00Z" or "2026-08-10T09:00:00+02:00"). A value without an offset is rejected with 422: it would otherwise be read in the platform timezone and land hours away from what you meant.
  - `ends_at` string, date-time, required: ISO-8601 with an explicit offset. Must be after starts_at and no more than 30 days later.
  - `reason` string, nullable: Why the handover happens, in your own words — shown beside it on the schedule page so the next person to look does not have to ask. Nothing is matched or routed on it, and it is not sent to the stand-in.

## Response `201`

The handover.

- object
  - `data` ScheduleOverride: A temporary swap laid OVER the shifts rather than an edit of them: the resolver looks for an override covering the moment first and only then at shifts. Nothing needs restoring when it ends — the original person resumes by themselves.
    - `uuid` string, uuid
    - `role` 'primary' | 'secondary' | 'manager'
    - `recipient` object, nullable: Who stands in.
      - `uuid` string, uuid
      - `name` string
    - `replacing` object, nullable: Who they cover for, captured when the handover was created. Null when no shift covered the start moment — a handover over an empty rotation is still valid.
      - `uuid` string, uuid
      - `name` string
    - `starts_at` string, date-time: When the handover begins, rendered in the schedule's own timezone rather than UTC — the same wall clock the schedule page shows.
    - `ends_at` string, date-time: When it ends, in the schedule's timezone.
    - `reason` string, nullable: Whatever was given when the handover was created. Free text for people; nothing routes on it.
    - `is_active` boolean: True while the window covers this instant — i.e. this person is the one an alert would reach right now.
    - `created_at` string, date-time

## Other responses

- `401`: API key missing, invalid, revoked or expired.
- `403`: API key lacks the config.write ability, or the schedule belongs to another company.
- `404`: No schedule with this UUID, or on-call schedules are switched off for this deployment.
- `422`: Validation failed — a timestamp without a UTC offset, ends_at not after starts_at, a window longer than 30 days, or a recipient that is not part of this company.

---

[API](https://skmtc.dev/wardenpoint/apis/wardenpoint-api.md) · [All operations](https://skmtc.dev/wardenpoint/apis/wardenpoint-api/llms.txt) · [OpenAPI document](https://skmtc.dev/wardenpoint/apis/wardenpoint-api/revisions/259ee445728e?raw)
