Skip to content
Last updated

Errors and status codes

404 means "not found, or not yours"

When a caller is not allowed to see a resource, the API returns 404 Not Found — not 403 Forbidden. The response is deliberately identical to the one you get for an ID that was never issued, so that the API never confirms whether a resource exists to someone who is not entitled to read it.

A 404 is not proof that a resource was deleted. It means one of:

  • the ID does not exist, or never did
  • the resource exists but belongs to another account
  • the resource exists in your account but your token may not read it
  • your token is missing, expired, or invalid

Do not build reconciliation, sync or clean-up logic that treats a 404 as a deletion signal — you will delete records on your side that are alive and well on ours, merely because a permission changed. If you need to know that something was deleted, use webhooks.

These 404 responses have an empty body. There is no message to parse and no code to branch on, so do not expect the error envelope described below.

The error envelope

Every other error returns JSON with a human-readable message:

{
  "message": "Sorry, we found issues with some of the submitted data - please review and try again."
}

Two responses add a field to it:

FieldAppears onMeaning
errors422Per-field validation failures
codeUnexpected server errorsA reference to quote to support

message is translated, so its wording follows the request's locale and is not stable enough to branch on. Branch on the status code and, for 422, on the keys inside errors.

Common status codes

StatusWhen
200 OKA successful read, update, or a write that returns the resource
201 CreatedA successful create, returning the new resource
204 No ContentA successful delete, with an empty body
401 UnauthorizedBad credentials at the token endpoint only — see below
403 ForbiddenA business rule refused the action — see below
404 Not FoundNot found, or not yours — see above
422 Unprocessable EntityThe request was understood but the data failed validation
429 Too Many RequestsA rate limit window was exceeded — see Rate limits

On 401

401 is narrower than it looks. It comes from the token endpoint, when the credentials you exchanged for a token were rejected.

It is not what you get for a missing or expired token on a normal API endpoint. That returns the same bare 404 as everything else in the section above. So if a previously working integration starts returning 404 across every endpoint at once, suspect the token before you suspect the data.

On 403

Because authorisation failures collapse into 404, a 403 never means "you may not see this". It means the opposite: the resource is yours and we know who you are, but a rule specific to that operation refused it — a quota exhausted, a duplicate that is not permitted, a state that forbids the change.

A 403 is therefore always endpoint-specific, and is documented on the endpoint that can return it, together with the message it sends.

Validation errors

A 422 names every field at fault. errors is keyed by field name, and each value is the list of problems with that field. Nested fields are dotted.

{
  "message": "Sorry, we found issues with some of the submitted data - please review and try again.",
  "errors": {
    "status": ["The selected status is invalid."],
    "user_id": ["The user id field is required."]
  }
}

Read errors rather than the message — the message is the same generic sentence on every validation failure.

Unexpected errors

If something fails on our side, the response carries a reference instead of the underlying detail:

{
  "message": "Unexpected Error on Rosterfy",
  "code": "ACEH292"
}

Log code and quote it to support; it identifies the specific failure. Treat these as retryable only if the operation is safe to repeat.

Endpoint-specific statuses

Some endpoints return a status that does not follow from any of the above — a 402 where a payment is outstanding, a 410 where a form has closed, a 403 for a rule unique to that operation. Those are documented on the endpoint itself, so check its reference page as well as this one.