Authentication & scopes
How API keys authenticate requests and what each scope grants.
API keys
The Public API authenticates with API keys only. Send the key as a bearer token:
Authorization: Bearer strd_<key>X-API-Key: strd_<key> is also accepted. Keys are created and managed in
Settings → API keys.
- Team-scoped. The team is resolved from the key. Every request is implicitly scoped to that team; cross-team access is impossible.
- No session cookies. The public surface never reads or falls back to a browser session. A cookie on a public request is ignored.
- Shown once. The full secret is returned only at creation. Store it securely; it cannot be retrieved again. If you lose it, revoke the key and create a new one.
Who a key acts as
Keys are created by team admins and owners only (a regular member or restricted role cannot mint one). A key is a workspace credential that carries the explicit scopes chosen at creation and acts as its creator. For most resources that is the same team-wide access any member has; for permission-gated data (time tracking rates and another employee's entries, and travel) the key acts with its admin creator's rights, resolved live at request time. A key reading trips sees the team's trips only while its creator is still a travel manager; otherwise it sees that person's own trips. If the creator later loses that access or leaves the team, those calls fail closed.
Because a workspace key can outlive its creator's access, revoke a member's keys when they leave the team or lose admin. Per-user personal access tokens, bounded by the holder's own permissions, are planned as a separate capability.
Scopes
A key holds a set of fine-grained resource:action scopes. The grammar is flat:
there are no wildcards. The tokens are every combination of:
- Resources:
organizations,contacts,employees,projects,tasks,activities,assignments,cvs,time_entries,documents,attachments,trips - Actions:
read,write
For example organizations:read or documents:write. (A key can also carry an imports
scope, but that resource is reserved for connected apps and has no public REST or
GraphQL endpoint, so it is not part of the surface documented here.)
tripsis read-only. A trip is created, approved, and sealed in the app, sotrips:readis the only token that exists for it.trips:writeis not a scope: it cannot be granted, and requesting it is rejected.writeimpliesreadfor the same resource (and only that resource). A key holdingcvs:writemay also read CVs. It grants nothing on any other resource.- REST. Each endpoint requires the matching token: a
GETneeds<resource>:read, a write needs<resource>:write. A key missing the token gets403 forbidden. - GraphQL. Enforced per resolver; a query needs the resource's
:read, a mutation its:write. The single endpoint authenticates the key; each field then asserts its own scope. - Search.
searchhas no scope of its own. Results are filtered to the resource types the key can read; a key that can read none of the searchable types (organizations, contacts, employees, cvs, projects) gets403 forbidden.
Because scopes carry no wildcards, a key is only ever granted the resources named at creation time. When a new resource is added to the API, existing keys do not automatically gain access; they keep working unchanged and must be re-issued to opt in. This is an additive, non-breaking change; see versioning.
Key limits
A team may hold at most 50 active keys (non-revoked, non-expired). Creating a key
at the limit returns 409 key_limit_reached. Revoking a key, or letting one expire,
frees a slot.