Manage your rotations programmatically with the RotaHog REST API. Available on Team Toolkit and Ops Pro plans.
https://rotahog.com/api/v1Authorization headerhttps://rotahog.com/api/v1/openapi
All API requests require a Bearer token. Create one from your API Tokens page.
curl -H "Authorization: Bearer rh_your_token_here" \
https://rotahog.com/api/v1/rotations
Tokens come in two scopes:
read — List and view rotations and turnsread_write — All read operations plus creating rotations and completing, substituting, and cancelling turnsThis REST API takes API tokens only. If you are building a client and would rather sign users in than ask them for a token, use the MCP server, which speaks OAuth 2.1. Access tokens issued there work against /mcp and not against the endpoints below.
All endpoints are rate-limited to 30 requests per minute per token, and 60 requests per minute per IP address. Exceeding either returns a 429 response.
/api/v1/rotations
List all rotations you own or participate in.
| Param | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
{
"rotations": [
{
"token": "wk_rotation_1",
"task_name": "Weekly standup host",
"recurrence": "weekly",
"start_date": "2026-09-27",
"timezone": "UTC",
"members_count": 3,
"created_at": "2026-09-27T10:00:00Z"
}
],
"pagination": { "page": 1, "per_page": 25, "has_more": false }
}
/api/v1/rotations
read_write scope
Create a rotation. Members take turns in the order you list them, and the schedule is generated for the next year, so the response already tells you who is up next.
Your plan caps how many active rotations you can own and how many members one rotation can have. Going over either returns a 422.
| Field | Type | Description |
|---|---|---|
task_name | string | Required. What the person on duty has to do |
recurrence | string | Required. One of daily, weekdays, weekly, bi_weekly, monthly |
members | array | Objects with name and optional email, in turn order. A member with an email gets a reminder before their turn. |
start_date | string | First turn, as YYYY-MM-DD. Defaults to today. |
timezone | string | IANA timezone the schedule and reminders run in, e.g. Europe/Lisbon. Defaults to UTC. |
reminder_days_before | integer | 0, 1 or 2. Defaults to 1. |
reminder_send_time | string | Time of day to send reminders, as HH:MM. Defaults to 09:00. |
curl -X POST -H "Authorization: Bearer rh_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"task_name": "Lead the daily standup",
"recurrence": "weekdays",
"timezone": "Europe/Lisbon",
"members": [
{ "name": "Alice", "email": "alice@example.com" },
{ "name": "Bruno" }
]
}' \
https://rotahog.com/api/v1/rotations
{
"rotation": {
"token": "wk_rotation_1",
"task_name": "Lead the daily standup",
"recurrence": "weekdays",
"start_date": "2026-09-28",
"timezone": "Europe/Lisbon",
"members_count": 2,
"created_at": "2026-09-28T10:00:00Z",
"members": [
{ "id": 1, "name": "Alice", "email": "alice@example.com", "slack_handle": null },
{ "id": 2, "name": "Bruno", "email": null, "slack_handle": null }
],
"next_turn": {
"id": 42, "scheduled_date": "2026-09-28", "status": "upcoming", "acting_member": "Alice"
}
}
}
Keep the token: every other endpoint identifies the rotation by it.
/api/v1/rotations/:token
Get rotation details including members and next upcoming turn.
{
"rotation": {
"token": "wk_rotation_1",
"task_name": "Weekly standup host",
"recurrence": "weekly",
"start_date": "2026-09-27",
"timezone": "UTC",
"members_count": 3,
"created_at": "2026-09-27T10:00:00Z",
"members": [
{ "id": 1, "name": "Alice", "email": "alice@example.com", "slack_handle": null }
],
"next_turn": {
"id": 42, "scheduled_date": "2026-10-04", "status": "upcoming", "acting_member": "Alice"
}
}
}
/api/v1/rotations/:token/turns
List turns for a rotation with optional filters.
| Param | Type | Description |
|---|---|---|
status | string | Filter by status: upcoming, overdue, completed, cancelled, missed |
from | date | Start date filter (ISO 8601) |
to | date | End date filter (ISO 8601) |
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
/api/v1/rotations/:token/turns/current
Get the next upcoming turn for a rotation — who's on duty now.
{
"turn": {
"id": 42,
"scheduled_date": "2026-10-04",
"status": "upcoming",
"completable": true,
"acting_member": { "id": 1, "name": "Alice", "email": "alice@example.com", "slack_handle": null },
"original_member": null,
"backup_member": null,
"substituted_at": null,
"backup_assigned_at": null
}
}
/api/v1/rotations/:token/turns/:id/complete
Mark a turn as completed. Only the rotation owner or acting member can complete a turn.
/api/v1/rotations/:token/turns/:id/substitute
Assign a substitute for a turn. Requires the "Find a substitute" plan feature.
{ "substitute_member_id": 2 }
/api/v1/rotations/:token/turns/:id/cancel
Cancel a turn. Only the rotation owner can cancel. Requires the "Cancel a turn" plan feature.
| Status | Meaning |
|---|---|
401 | Missing or invalid API token |
403 | Plan doesn't include API access, insufficient scope, or not authorized |
404 | Resource not found |
422 | Validation error (e.g., turn not completable) |
429 | Rate limit exceeded |
All errors return JSON:
{ "error": "Not authorized" }
Also available as an MCP server for AI assistants. View MCP documentation.