The Round Robin API
The Round Robin API is an HTTP interface to the same data the dashboard and the Slack bot work with: your rotations, their schedules, and who is on call right now. It exists for the things Slack cannot do for you: putting the on-call person on a status page, paging them from your own incident tooling, driving a deployment gate, or feeding a dashboard that already shows everything else about your service.
It is a separate surface from the one the dashboard uses, and it is the only one covered by a promise: what is documented here keeps working. Anything you find by watching the dashboard’s network tab is not part of it and will change without notice.
You need: a team API key. Create one in the dashboard under Settings → API keys: choose what it may do and which rotations it may reach, and copy the secret, which is shown once. See Creating and managing API keys.
Make your first call
Section titled “Make your first call”Everything lives under one host, and the team is implicit: a key belongs to exactly one Slack workspace, so no workspace id ever appears in a path.
curl https://api.roundrobinbot.eu/v1/keys/self \ -H "Authorization: Bearer rr_live_..."GET /v1/keys/self is the call to start with, and the one to come back to when something is refused: it answers with the key’s name, its scopes, and the rotations it may reach.
{ "id": "6a2f…", "name": "Status page", "teamId": "T0123ABCD", "scopes": ["read:oncall"], "selector": "Rotations", "rotationIds": ["664f…"], "apiVersion": "2026-08-01", "createdAt": "2026-08-14T09:12:44+00:00"}Ask who is on call
Section titled “Ask who is on call”The question most integrations exist to answer takes one request:
curl "https://api.roundrobinbot.eu/v1/rotations/{rotationId}/on-call?expand=users" \ -H "Authorization: Bearer rr_live_..."?expand=users side-loads the full directory record for every person the answer names, so you get Slack ids and display names without a second round trip. Leave it off and you get ids alone, plus an ETag you can use to make the next poll free (see Conventions).
What you can read
Section titled “What you can read”| What | Endpoint |
|---|---|
| Your rotations, a page at a time | GET /v1/rotations |
| One rotation, with its schedule and business hours | GET /v1/rotations/{rotationId} |
| Who is on call right now | GET /v1/rotations/{rotationId}/on-call |
| Projected shifts in a window you name | GET /v1/rotations/{rotationId}/schedule?from&to |
| A person, group or channel from the synced directory | GET /v1/users/{id}, /v1/groups/{id}, /v1/channels/{id} |
| The key’s own workspace | GET /v1/team |
| The key itself | GET /v1/keys/self |
What you can change
Section titled “What you can change”Every write against something that already exists requires an If-Match carrying the ETag from your last read. A write without one is refused: see Conditional writes.
| What | Endpoint | Scope |
|---|---|---|
| Hand the shift to the next person | POST /v1/rotations/{rotationId}/rotate |
write:duty |
| Put named people on duty | PUT /v1/rotations/{rotationId}/on-call |
write:duty |
| Change a rotation’s configuration | PATCH /v1/rotations/{rotationId} |
write:rotation |
| Replace a rotation’s schedule | PUT /v1/rotations/{rotationId}/schedule |
write:rotation |
| Create a rotation | POST /v1/rotations |
write:rotation |
The two duty writes answer with the rotation’s new on-call state and a fresh ETag, so a deployment gate that rotates and then reports who now holds the shift needs one request, not two. The other three answer with the whole rotation.
PATCH changes only the fields you send, so renaming a rotation means sending the name and nothing else. The schedule is a replacement rather than a patch, because the schedule kinds do not share a field set and a field left out of one kind means nothing in another.
Creating takes an Idempotency-Key instead of an If-Match: there is no version to match on yet, and rotation names are not unique, so nothing else could tell a retry from a second rotation. See Creating things.
The roster is read-only over /v1: who is in a rotation is changed from the dashboard or from Slack.
The full request and response shapes are in the API reference, which is generated from the same OpenAPI document the service publishes at https://api.roundrobinbot.eu/openapi/public.json. Point an SDK generator or Postman at that URL directly.
Versions
Section titled “Versions”A key is pinned to a dated contract version (2026-08-01 for every key issued today), and GET /v1/keys/self reports it. Fields get added to responses within a version, so parse leniently and ignore what you do not recognise. Nothing is removed or renamed within a version; that needs a new one, and your key keeps answering on the old one until you move it.
/v1 is the path, not the version. It changes only if the shape of the API changes so fundamentally that a dated version cannot carry it.
Next steps
Section titled “Next steps”- Authentication: how to present a key, and what each refusal means
- Scopes and access: what a key may do, and which rotations it may reach
- Conventions: paging, sorting, timestamps, conditional reads and conditional writes
- Errors: the codes to branch on
