API

Search the developer hub

Jump to a page or an endpoint.

API reference

The public CREW25 HTTP API. JSON in, JSON out, scoped to one organisation.

The CREW25 API is organised around REST. Resource-oriented URLs, JSON request bodies, JSON responses, and standard HTTP verbs and status codes.

The API under /api/v1 is authenticated by a secret API key and used by your own systems. It is in beta and small so far: start with the organisation call, and check the changelog as more records join it.

Two other ways in reach further today. Webhooks push events about people, jobs, quotes and invoices to your server as they happen. The MCP server gives an AI agent, or your own automation, the same tools as CREW25's own agent: jobs, the schedule, hours, quotes, invoices, purchasing and more. The same API keys work there.

Authentication

API keys

Everything under /api/v1 needs an API key. An owner or admin of the organisation creates keys in the office under Settings → Developer → API Keys. Each key belongs to one organisation, so there is no organisation in the URL: the key decides whose data you see.

Send the key as a bearer token in the Authorization header:

curl https://api.crew25.com/api/v1/organisation \
  -H "Authorization: Bearer crew25_sk_…"

That call returns the organisation the key belongs to, which makes it the quickest check that a key works.

Keys have one of two access levels, chosen when the key is created:

Access Can
Read only Every GET under /api/v1
Read and write Everything a read-only key can, and change records

A few rules keep keys safe:

  • The key is shown once, when it is created. CREW25 stores only a hash of it, so nobody can show it to you again. If you lose it, revoke it and create another.
  • Keep keys on your server. Never put one in a browser, a mobile app or a public repository. Anyone holding a key can act as the organisation. Every key starts with crew25_sk_, so secret scanners can spot a leaked one.
  • Revoking is immediate. A revoked key is refused on its next request with 401.
  • Use one key per integration, named after it. Settings shows when each key was last used, so you can tell which keys are still in use before revoking any.
  • Keys open /api/v1 and the MCP server. They never reach the office's own routes, and the office session never reaches either. On the MCP server a key acts as the person who created it.

A missing, malformed or revoked key gets 401:

{ "error": "This API key is not valid. It may have been revoked." }

A read-only key that tries to write gets 403. When the organisation's subscription has lapsed, reads keep working and writes get 402.

Requests

The base URL is:

https://api.crew25.com

Send Content-Type: application/json on every write; anything else is 415. Bodies are capped at 16 KB. Lists come back as { "object": "list", "data": [...], "hasMore": false }.

Errors

Errors are always the same shape:

{ "error": "Enter a valid date." }

The message is written for a person and is safe to show to one. Match on the status, not the text.

Status Meaning
400 Malformed JSON.
401 The API key is missing, malformed or revoked.
402 The organisation's subscription is inactive, so writes are closed.
403 A read-only API key used to write, or a caller who may not do this.
404 No organisation, or no record, with that identifier.
415 The request was not application/json.
422 Validation failed. The message names the fields, semicolon-separated.
429 Rate limited. Retry after the Retry-After header.
500 Something broke on our side. Safe to retry.

Rate limits

Each API key may make 600 requests per minute. A limited request comes back 429 with Retry-After: 60. Cache what you read in your own app rather than polling it.