Appearance
REST API Reference
The same roster data the MCP server exposes, over plain HTTP. Use this for dashboards, scripts and integrations that are not AI agents.
Base URL
https://app.manageroster.com/api/v1Authentication
Bearer token in the Authorization header. Create one in Settings → API & MCP — see MCP server setup, the same tokens work for both.
bash
curl -s https://app.manageroster.com/api/v1/me \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Accept: application/json'Every token is bound to one workspace. There is no workspace parameter on any endpoint — the token determines it.
Responses
Success responses wrap the payload in data:
json
{ "data": { "…": "…" } }Errors return an error object and a matching HTTP status:
json
{
"error": {
"code": "insufficient_scope",
"message": "This token is missing the required scope. Needs one of: leaves:read. It currently has: agents:read.",
"required_scopes": ["leaves:read"],
"token_scopes": ["agents:read"]
}
}| Status | Code | Meaning |
|---|---|---|
| 401 | unauthenticated | Token missing, invalid, revoked or expired |
| 403 | forbidden | Workspace API disabled, or the user is no longer a member |
| 403 | insufficient_scope | Token lacks the scope, or is read-only and you attempted a write |
| 422 | — | Validation failed. errors names the fields |
| 404 | — | Record not found in this workspace |
Date ranges
Endpoints taking a range accept either explicit dates or a relative period.
| Parameter | Values |
|---|---|
from / to | YYYY-MM-DD. Both required together; overrides period |
period | today, next_week, this_month, next_month. Defaults to the current week |
Ranges longer than 366 days are truncated.
Endpoints
GET /me
Who the token acts as, its workspace, and its effective scopes. No scope required — use it to verify a token.
json
{
"data": {
"user": { "id": 4, "name": "Rahim Chowdhury", "email": "…" },
"workspace": { "id": 2, "name": "xCloud Support", "timezone": "Asia/Dhaka", "agent_count": 8, "features": {…}, "your_role": "owner" },
"token": { "name": "Claude Code — laptop", "scopes": ["schedule:read", "leaves:read"], "is_read_only": true, "last_used_at": "2026-09-06T10:22:41+00:00" }
}
}GET /workspace
Scope: workspace:read
Workspace name, timezone, active agent count and enabled feature modules.
GET /agents
Scope: agents:read
| Query | Description |
|---|---|
active_only | true (default) or false |
Returns id, name, active, colour, holiday group, office days and off days.
GET /agents/available
Scope: schedule:read
Agents not rostered and not on approved leave for a date.
| Query | Description |
|---|---|
date | Required. YYYY-MM-DD |
hour | 0–23. Omit to check the whole day |
Agents on a public holiday are included with on_public_holiday: true rather than filtered out — they are often available for overtime, and you want that context before asking.
GET /schedule
Scope: schedule:read
| Query | Description |
|---|---|
from / to / period | Date range |
agent_id | Limit to one agent |
Consecutive hours for the same agent are collapsed into blocks. end_hour is exclusive.
json
{
"data": {
"from": "2026-09-07", "to": "2026-09-13",
"days": [
{ "date": "2026-09-07",
"blocks": [
{ "agent_id": 3, "agent_name": "Nadia", "start_hour": 9, "end_hour": 17, "hours": 8, "is_ot": false, "shift_type": "morning_day" }
] }
],
"total_assigned_hours": 112
}
}GET /schedule/coverage
Scope: schedule:read
Uncovered hours as contiguous ranges, plus an overall coverage percentage.
| Query | Description |
|---|---|
from / to / period | Date range |
min_agents | Minimum agents for an hour to count as covered. Default 1 |
json
{
"data": {
"from": "2026-09-07", "to": "2026-09-13",
"min_agents": 1,
"gaps": [ { "date": "2026-09-08", "start_hour": 2, "end_hour": 6, "hours": 4, "assigned": 0, "required": 1 } ],
"gap_count": 1,
"uncovered_hours": 4,
"coverage_percent": 97.6
}
}POST /schedule
Scope: schedule:write
json
{ "agent_id": 3, "date": "2026-09-08", "start_hour": 9, "end_hour": 17, "is_ot": false, "notes": null }Returns 201. Refuses with 422 if the agent is on approved leave or already rostered in those hours, naming the conflict.
For an overnight shift, make two calls — one ending at hour 24, one starting at hour 0 on the next date.
DELETE /schedule
Scope: schedule:write
Same body as POST minus is_ot and notes. Returns the number of hours removed.
GET /leaves
Scope: leaves:read
| Query | Description |
|---|---|
from / to / period | Date range |
status | pending, approved, rejected |
agent_id | Limit to one agent |
Matches on overlap, so leave starting before the range and running into it is included.
POST /leaves
Scope: leaves:write
json
{ "agent_id": 3, "type": "annual", "start_date": "2026-09-14", "end_date": "2026-09-18", "notes": null }type is one of annual, sick, casual, maternity. status defaults to pending.
Refuses with 422 on overlapping leave. Returns a warnings array — not an error — when the agent is already rostered during the requested dates, since those shifts need reassigning.
PATCH /leaves/{id}
Scope: leaves:write
json
{ "status": "approved" }GET /holidays
Scope: holidays:read
| Query | Description |
|---|---|
from / to / period | Date range. Defaults to the current month |
group | Holiday group code, e.g. BD, PH |
Each holiday includes affects_agents — the agents in that holiday group — because groups are per-agent and one workspace can run several national calendars.
GET /ot-events
Scope: ot:read
| Query | Description |
|---|---|
status | draft, active, closed |
GET /ot-events/{id}/coverage
Scope: ot:read
Slot-by-slot volunteer coverage for one OT event, and uncovered_slots.
GET /work-reports/missed
Scope: reports:read
| Query | Description |
|---|---|
from / to / period | Date range |
agent_id | Limit to one agent |
Only counts dates where the agent was actually rostered.
Rate limits
The default API throttle is 60 requests per minute per token. Exceeding it returns 429 with a Retry-After header.
Examples
Who is on leave next week
bash
curl -s 'https://app.manageroster.com/api/v1/leaves?period=next_week&status=approved' \
-H 'Authorization: Bearer YOUR_TOKEN'Which slots are empty this week
bash
curl -s 'https://app.manageroster.com/api/v1/schedule/coverage?period=this_week' \
-H 'Authorization: Bearer YOUR_TOKEN'Assign a night shift crossing midnight
bash
curl -s -X POST https://app.manageroster.com/api/v1/schedule \
-H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
-d '{"agent_id":3,"date":"2026-09-08","start_hour":22,"end_hour":24}'
curl -s -X POST https://app.manageroster.com/api/v1/schedule \
-H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
-d '{"agent_id":3,"date":"2026-09-09","start_hour":0,"end_hour":6}'Related
- MCP server setup — connect an AI client instead
- MCP tool reference — the tool equivalents of these endpoints
- Connection scopes — what each scope permits