---
title: "Generate a weekly rotation"
method: POST
path: "/api/v1/schedules/{schedule}/rotation"
tags: ["On-call schedules"]
---

# Generate a weekly rotation

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

## 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}/rotation`
- Auth: API key in header `X-API-Key`

Lays the duty pool out over the coming weeks for ONE role, one person per week, wrapping around the list. Idempotent within its window: calling it twice with the same arguments produces the same set. Existing generated shifts inside the window are replaced, a generated shift that started before the window is truncated at the boundary so the current responder is not yanked off duty mid-shift, and shifts marked `manual` plus every handover are left untouched. Weeks are cut at the schedule's handoff moment in the schedule's own timezone, so a DST transition does not move them.

## Path parameters

- `schedule` string, uuid, required

## Request body

- RotationRequest
  - `role` 'primary' | 'secondary' | 'manager', required: Which slot of the rotation is being filled. Generating one role never touches the others.
  - `recipient_uuids` string[], required: The duty pool, IN DUTY ORDER: the first person takes the first week, the second the second, and the list wraps. Order is significant and is honoured exactly as sent. Duplicates are collapsed. Every uuid must be an active recipient of this company — an unknown or foreign one is rejected with 422 instead of being silently dropped from the pool.
  - `weeks` integer: How many weeks forward to lay out. Defaults to 12.
  - `start_now` boolean: True hands duty to the first person immediately, with a partial shift running until the next handoff moment; the first FULL week then goes to the second person, because the partial shift is already the first person's turn. False (the default) starts the rotation at the next handoff and gives the first full week to the first person.

## Response `201`

The shifts that were created, in chronological order. One per week, plus a partial first one when start_now was set.

- object
  - `data` ScheduleShift[]
    - `uuid` string, uuid
    - `role` 'primary' | 'secondary' | 'manager'
    - `recipient` object, nullable: Null only if the person was deleted after the shift was generated.
      - `uuid` string, uuid
      - `name` string
    - `starts_at` string, date-time
    - `ends_at` string, date-time
    - `source` 'rotation' | 'manual': `rotation` — generated, and the next generation covering the same window will replace it. `manual` — created by hand and survives regeneration.

## 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 — an unknown role, an empty pool, weeks outside 1..52, or a recipient uuid that is not an active recipient 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)
