Scopes#
Every operation requires exactly one scope, named <resource>.<action>:
shifts.read locations.write timesheets.read
GETrequires.read.POST,PATCH,DELETErequire.write.Write implies read —
shifts.writealso satisfiesshifts.read, so you never need to request both.
The catalog#
The grantable set is closed and shipped as part of the contract. Here it is in full — one row per resource, each with its .read and .write scope:
Scopes |
Covers |
|---|---|
|
Tenant settings (singleton). |
|
Areas within a location. |
|
Employee availability blocks (incl. recurring). |
|
Break rule definitions. |
|
Labor budgets and revenue targets. |
|
Employees, their memberships, invites and lifecycle. |
|
Employment types and their payroll defaults. |
|
General (non-shift) events and their attendees. |
|
Public-holiday calendar. |
|
Labor-cost report. |
|
Leave balances (read-only). |
|
Leave policies and their tier ladders. |
|
Leave requests and their review transitions. |
|
Locations. |
|
Open-shift offers (read-only on this API). |
|
Positions, their skill expectations and employee assignments. |
|
Shifts, their publication state and assignments. |
|
Skill catalog. |
|
Shift swap offers (read-only on this API). |
|
Time-compensation ledger and balances. |
|
Timesheets, clock stamps, breaks and approvals. |
|
Webhook endpoint registration and secret rotation. |
|
Dispatched-event history for reconciliation. |
|
Work rules (incl. the Art. 17b time-compensation block). |
For a single endpoint you don’t need this table: every operation in the API Reference declares the exact scope it requires, right on the operation. Both that requirement and the table above are derived from the same value the server’s permission check reads, so what is documented and what is enforced cannot drift apart.
Asking for the right ones#
Scopes are granted per integration client when we register it, so ask for what the integration actually does and nothing more. A payroll export that reads hours gets timesheets.read and nothing else.
A typo is caught at registration, not at runtime: shift.read is refused with a suggestion rather than registering a client that fails on every call.
To add a scope later, email support@shiftavo.com — it does not require new credentials.
When a scope is missing#
A call with a valid token but without the required grant is:
{
"error": {
"type": "permission_error",
"code": "insufficient_scope",
"message": "…",
"details": []
}
}
with status 403. That is distinct from a 401 (the token itself is bad — see Authentication) and from a 404, which is also what you get for a record outside your company, so that existence never leaks.