Build on Syncurio
Programmatic access to your rostering, workforce, governance, task, budget and reporting data. Plug payroll integrations, BI dashboards, time-clock devices and bespoke tooling straight into the system that runs your homes.
Get started →Get started in three steps
Issue an API key
Sign in, open Settings → Integrations from the profile menu, and create a key scoped to what your integration needs. Issue a separate key per integration so scopes and rate limits stay isolated.
Send your first request
Pass the key in the X-Api-Key header, and call your base URL — shown under Settings → Integrations (it differs by environment). Every endpoint requires the relevant scope grant.
Explore the reference
Browse and try every endpoint in the interactive Scalar reference, linked from Settings → Integrations in your dashboard. Opening it there points “Try it” at your own environment, so calls work with your key.
Three ways in, one key
Public API
Live records for integration partners: read the current state of shifts, audits, findings and tasks, and make changes the way staff do in the app.
- Base path
/public/v1- Paging
pageNumber/pageSize(50, max 200)- Rate limit
- 1,000 requests / hour per key
Reporting API
Flat, denormalised datasets for BI tools such as Power BI, Tableau and Looker, and for data warehouses.
- Base path
/reporting/v1- Paging
- Cursor — pass
nextCursorback unchanged - Rate limit
- 200 requests / hour per key
MCP server
The same endpoints as tools for AI assistants — Claude Desktop, Claude Code, Cursor and other MCP clients.
- Install
npx @syncurio/mcp- Writes
- Off unless you turn them on
- Limits
- Your key's scopes and rate limits
Endpoint reference
Every integration starts with GET/public/v1/homes (home:read): the home ids every other call takes. The full request and response schemas, with “Try it”, are in the interactive reference linked from Settings → Integrations.
Shifts, the people and agencies who can work them, and the rules changes are checked against.
Read
/public/v1/rostering/shifts Shifts for a home over up to 92 days, with assignmentsrostering:read/public/v1/rostering/shifts/{id} One shiftrostering:read/public/v1/rostering/employees Current employees at a home, with their rolesrostering:read/public/v1/rostering/roles The staffing role catalogue, with departmentsrostering:read/public/v1/rostering/absences Holiday and leave overlapping a date rangerostering:read/public/v1/rostering/agencies Agencies attached to a home and the roles they supplyrostering:read/public/v1/rostering/units A home's floors or wingsrostering:read/public/v1/rostering/settings Rostering rules: rest time, consecutive hours, holidayrostering:read/public/v1/rostering/templates Saved week patterns for a homerostering:read/public/v1/rostering/templates/{id} A week pattern, day by dayrostering:read/public/v1/rostering/missed-shifts Assigned shifts nobody clocked in forrostering:read/public/v1/rostering/unscheduled Time clocked without a rostered shiftrostering:readMake changes
/public/v1/rostering/shifts Create up to 100 shifts, all checked firstrostering:write/public/v1/rostering/shifts/{id} Change a shift's date, times, role or unitrostering:write/public/v1/rostering/shifts/{id}/edit-check Check a change against the rules without savingrostering:write/public/v1/rostering/shifts/{id}/assignment Assign an employee or agencyrostering:write/public/v1/rostering/shifts/{id}/assignment Unassign a shiftrostering:write/public/v1/rostering/shifts/{id} Cancel a future shift (permanent)rostering:write/public/v1/rostering/shifts/publish Publish a week — emails affected staffrostering:publishAudits and their answers, the findings they raise and the action plans that fix them.
Read
/public/v1/governance/frameworks Regulatory frameworks and each home's regulatorgovernance:read/public/v1/governance/audit-templates Audit templatesgovernance:read/public/v1/governance/audit-templates/{id} A template's questions and grade bandsgovernance:read/public/v1/governance/audit-schedules Recurring audits and when they're next duegovernance:read/public/v1/governance/audits Audits with status, grade and scoregovernance:read/public/v1/governance/audits/{id} An audit with every answergovernance:read/public/v1/governance/findings Findings, filterable by severity and statusgovernance:read/public/v1/governance/findings/{id} A finding with its tasks and observationsgovernance:read/public/v1/governance/action-plans Action plans with task countsgovernance:read/public/v1/governance/action-plans/{id} An action plan with its tasksgovernance:read/public/v1/governance/evidence/{id}/url A short-lived evidence download linkgovernance:evidence:readMake changes
/public/v1/governance/findings Raise a finding outside an auditgovernance:write/public/v1/governance/findings/{id}/comments Comment on a findinggovernance:write/public/v1/governance/findings/{id}/resolve Resolve a findinggovernance:writeTasks from every module — governance remediation, CRM follow-ups and general tasks — each tagged with its source.
Read
/public/v1/tasks/groups Task groups with open and overdue countstasks:read/public/v1/tasks/groups/{id} A task group and its taskstasks:read/public/v1/tasks/items Tasks, filterable by assignee, due date, statustasks:read/public/v1/tasks/items/{id} A task with its commentstasks:read/public/v1/tasks/assignees Who tasks at a home can be assigned totasks:readMake changes
/public/v1/tasks/items Create a general tasktasks:write/public/v1/tasks/items/{id} Change priority, due date, progress or assigneetasks:write/public/v1/tasks/items/{id}/complete Complete a tasktasks:write/public/v1/tasks/items/{id}/cancel Cancel a task, with a reasontasks:write/public/v1/tasks/items/{id}/comments Comment or record progresstasks:writeBuilt for payroll and earned-wage-access partners.
Read
/public/v1/workforce/employees Current employees with pay basis and ratesworkforce:read/public/v1/workforce/timesheets Worked timesheets with hours and payworkforce:readA home's staffing budget. Contains pay rates.
Read
/public/v1/budget/homes/{homeId} Budgeted roles, rates, uplifts and shift patternsbudget:readFlat, cursor-paginated datasets for BI tools. One row per record, nothing nested.
Rostering
/reporting/v1/rostering/shifts One row per shift, with clocked hoursreporting:rostering/reporting/v1/rostering/employee-weekly-hours Scheduled hours per employee per weekreporting:rosteringGovernance
/reporting/v1/governance/audits One row per auditreporting:governance/reporting/v1/governance/audit-responses One row per answer, with readings against targetreporting:governance/reporting/v1/governance/findings One row per finding, with recurrence and days openreporting:governance/reporting/v1/governance/action-items One row per remediation taskreporting:governanceTasks
/reporting/v1/tasks/items One row per task, from every modulereporting:tasksBudget
/reporting/v1/budget/home-summary Budget against occupancy and fees, per homereporting:budget/reporting/v1/budget/weekly-comparison Budgeted vs rostered vs worked, by role and weekreporting:budgetMCP server
Add Syncurio to your MCP client's config with your API key and base URL. Each tool calls one of the endpoints above, with the same scopes and rate limits.
{
"mcpServers": {
"syncurio": {
"command": "npx",
"args": ["-y", "@syncurio/mcp"],
"env": {
"SYNCURIO_API_KEY": "syn_live_…",
"SYNCURIO_BASE_URL": "https://<your-syncurio-api-host>"
}
}
}
}
SYNCURIO_ENABLE_WRITES
Set to true to add the tools that make changes (create shifts, complete tasks, raise findings and so on). They still need the key's write scopes. Each call carries its own Idempotency-Key, so a retried call is applied only once.
SYNCURIO_TOOLSETS
Load only the areas you need, e.g. governance,tasks. Choose from rostering, workforce, budget, governance, tasks, reporting. A shorter tool list helps the assistant pick the right tool.
The full tool list is on the npm package page.
Code examples
List today's shifts — curlcurl "$SYN_BASE/public/v1/rostering/shifts?homeId=1&from=2026-04-30&to=2026-04-30" \ -H "X-Api-Key: $SYN_KEY"List today's shifts — JavaScript (fetch)
const res = await fetch( `${process.env.SYN_BASE}/public/v1/rostering/shifts?homeId=1&from=2026-04-30&to=2026-04-30`, { headers: { 'X-Api-Key': process.env.SYN_KEY } } ); const { items, totalCount } = await res.json(); console.log(`Found ${totalCount} shift(s)`);List today's shifts — C# (HttpClient)
using var http = new HttpClient(); http.DefaultRequestHeaders.Add("X-Api-Key", Environment.GetEnvironmentVariable("SYN_KEY")); var baseUrl = Environment.GetEnvironmentVariable("SYN_BASE"); var response = await http.GetAsync( $"{baseUrl}/public/v1/rostering/shifts" + "?homeId=1&from=2026-04-30&to=2026-04-30"); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync();Pull worked timesheets for payroll — curl
curl "$SYN_BASE/public/v1/workforce/timesheets?from=2026-04-01&to=2026-04-30" \ -H "X-Api-Key: $SYN_KEY"Pull approved paid holiday for payroll (one row per day) — curl
curl "$SYN_BASE/public/v1/workforce/holidays?from=2026-04-01&to=2026-04-30" \ -H "X-Api-Key: $SYN_KEY"Create a task, safely retryable — curl
curl -X POST "$SYN_BASE/public/v1/tasks/items" \ -H "X-Api-Key: $SYN_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"homeId": 1, "title": "Order more gloves", "priority": "High"}'Stream a reporting dataset with cursor pagination — curl
# First page curl "$SYN_BASE/reporting/v1/rostering/shifts?homeId=1&from=2026-01-01&to=2026-03-31&pageSize=500" \ -H "X-Api-Key: $SYN_KEY" # Continue with the nextCursor from the previous response curl "$SYN_BASE/reporting/v1/rostering/shifts?homeId=1&from=2026-01-01&to=2026-03-31&pageSize=500&cursor=$NEXT" \ -H "X-Api-Key: $SYN_KEY"
Authentication & rate limits
Base URL
Your base URL depends on your Syncurio environment and is shown under Settings → Integrations. The examples below use $SYN_BASE as a stand-in — set it once with export SYN_BASE="https://<your-syncurio-api-host>".
X-Api-Key header
Every request must carry the key issued from the dashboard. Keys are scoped — grant only what an integration needs, and issue a separate key per integration:
Read
- home:read
- rostering:read
- workforce:read
- budget:read
- governance:read
- governance:staff:read
- governance:evidence:read
- tasks:read
Make changes
- rostering:write
- rostering:publish
- governance:write
- tasks:write
Reporting
- reporting:rostering
- reporting:governance
- reporting:tasks
- reporting:budget
A key whose required modules aren't subscribed by your organisation can't be issued, and existing keys are revoked at request time if a module is later unsubscribed.
Staff-level governance records (staff audits and findings) are only included when a key also has governance:staff:read. Evidence files need governance:evidence:read.
Making changes
A key with a write scope acts as the person who created it. Changes are recorded against their name, and they must still be an active user with the matching permission in Syncurio — if they leave or lose the permission, the key's writes stop (with 403) while its reads carry on. Every rostering and governance rule applies, exactly as in the app; a change that breaks one is rejected with 400 and a code naming the rule.
Send an Idempotency-Key header (any unique string, such as a UUID) with every change. It's required when creating records. If a request is retried with the same key and body you get the original response back, marked Idempotent-Replayed: true, instead of a duplicate; the same key with a different body is a 409. Keys are remembered for 24 hours.
Rate limits
Each key has its own hourly budget. The defaults are 1,000 requests / hour on the public API and 200 requests / hour on the reporting API (sized for periodic BI pulls rather than interactive use).
The 1,001st (or 201st) request in an hour returns 429 Too Many Requests with a Retry-After header. Need higher limits for an integration? Get in touch.
Versioning & deprecation
The base paths are /public/v1 and /reporting/v1. We commit to backwards-compatible changes within v1. When an endpoint is deprecated we publish at least six months notice via the standard Sunset and Deprecation response headers, plus a banner in the API reference.
Webhooks
Real-time event notifications are on the roadmap for a future release. In the meantime the reporting API supports incremental pulls via cursor pagination. Want to be told when webhooks ship? Drop us a line.