CrewFlow API
One consistent, organisation-scoped REST API over every part of workforce mobilisation — people, compliance, planning, jobs, time, money and documents. Every integration CrewFlow ships is built on exactly what you see here.
Quickstart
Create a sandbox key in Settings → Developer, then make your first call. Sandbox keys return realistic fixtures, so you can build and test long before touching live worker data.
curl "https://your-crewflow-domain/api/public/v1/workers?limit=5" \
-H "Authorization: Bearer cfk_sandbox_..."{
"object": "list",
"data": [ { "id": "…", "first_name": "Ana", "last_name": "Kowalska", … } ],
"pagination": { "limit": 5, "offset": 0, "total": 42, "has_more": true }
}Authentication
Every request carries a bearer credential. A credential belongs to exactly one organisation and can never read or write another organisation's data — that boundary is enforced in the database, not in application code.
For your own back-office systems. Created in the CrewFlow UI, shown once, stored hashed.
Authorization: Bearer cfk_live_…For products acting on behalf of a CrewFlow user. Authorization code with PKCE, refresh token rotation, and client credentials for machine-to-machine.
GET https://your-crewflow-domain/oauth/authorize
?client_id=cfc_…
&redirect_uri=https://app.example.com/callback
&response_type=code
&scope=read+workers:write
&state=…
&code_challenge=…&code_challenge_method=S256
POST https://your-crewflow-domain/api/public/v1/oauth/token
grant_type=authorization_code
code=…&code_verifier=…&client_id=…Scopes
Scopes are least-privilege by design. read and write are the broad grants; everything else is per resource.
Conventions
- Base URL:
https://your-crewflow-domain/api/public/v1 - Pagination via
?limit=(max 200) and?offset=; responses include apaginationobject. - Incremental sync via
?updated_since=with an ISO 8601 timestamp. - All timestamps are UTC ISO 8601. All identifiers are UUIDs.
- Every response carries
x-request-id; quote it in support requests.
Resources
| Resource | Operations | Scopes |
|---|---|---|
/v1/workers People the organisation mobilises. | list, get, create, update | read workers:read write workers:write |
/v1/clients Customer companies that receive labour. | list, get, create, update | read clients:read write clients:write |
/v1/projects Sites and contracts workers are deployed to. | list, get, create, update | read projects:read write projects:write |
/v1/jobs Mobilisation records produced by the Job Wizard. | list, get | read jobs:read write jobs:write |
/v1/assignments Which worker is on which project, and when. | list, get, create, delete | read projects:read write projects:write |
/v1/planner Availability windows used by CrewFlow. | list, get | read planner:read write |
/v1/documents Compliance documents. File contents are never returned; use signed links. | list, get | read documents:read write documents:write |
/v1/document-packs Bundles of templates issued together during mobilisation. | list, get | read documents:read write documents:write |
/v1/timesheets Hours captured in the Worker Portal. | list, get, update | read finance:read write finance:write |
/v1/expenses Worker expense claims and receipts. | list, get, update | read finance:read write finance:write |
/v1/ai-jobs CrewFlow Intelligence extraction queue. | list, get | read write |
/v1/notifications In-product notifications raised for the organisation. | list, get | read write |
/v1/tasks Work items raised by staff or by automations. | list, get, create, update | read write |
/v1/automations Automation rules configured for the organisation. | list, get | read automations:read write |
Webhooks
Subscribe an HTTPS endpoint to any event in the catalogue. Deliveries are signed, retried with exponential backoff and carry a stable idempotency key so you can safely deduplicate.
POST https://example.com/hooks/crewflow
x-crewflow-event: worker.compliance_expiring
x-crewflow-delivery: 6f0e…
x-crewflow-idempotency-key: 6f0e…
x-crewflow-timestamp: 1767225600
x-crewflow-signature: t=1767225600,v1=<hex hmac-sha256>
{
"id": "evt_…",
"type": "worker.compliance_expiring",
"created_at": "2026-01-01T00:00:00Z",
"org_id": "…",
"data": { … }
}Verify the signature as HMAC-SHA256 over `${timestamp}.${rawBody}` using the endpoint's signing secret, and reject timestamps older than five minutes.
const expected = crypto
.createHmac("sha256", signingSecret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");Respond with any 2xx within 10 seconds. Non-2xx responses are retried; after the maximum attempts the delivery is dead-lettered and can be replayed from the CrewFlow UI.
Sandbox
Create a key with the sandbox environment and the same endpoints return deterministic fixtures instead of live records. Writes are accepted and echoed back but never persisted, so you can exercise your full integration path safely.
Errors and rate limits
{
"error": { "code": "insufficient_scope", "message": "Scope `workers:write` required." },
"request_id": "req_…"
}- 401 — missing, expired or revoked credential.
- 403 — the credential lacks the required scope.
- 404 — unknown resource, or a record outside your organisation.
- 422 — the request body failed validation.
- 429 — rate limited. Each credential has a per-minute budget; responses carry
x-ratelimit-limit,x-ratelimit-remainingandretry-after.