Skip to main content

Errors

Every error response uses a stable JSON envelope.

warning

Branch your logic on code, never on the message text — the message is human-readable and may change; the code is the contract.

Envelope

{
"error": {
"code": "unprocessable_entity",
"message": "Request body validation failed.",
"details": {
"issues": [
{ "path": "amount", "code": "invalid_string", "message": "Invalid" }
]
}
}
}
FieldDescription
error.codeStable code (table below). Branch on it.
error.messageHuman-readable text, in English. Do not parse.
error.detailsPresent on some errors — useful structured data (offending field, reason, missing scope). See examples below.

Codes

codeHTTPWhen
bad_request400Malformed query/body — invalid JSON, unknown filter/operator, invalid cursor, empty filter value, invalid limit.
invalid_token401Token missing, malformed, invalid signature, or expired.
invalid_audience401The token's aud is not accepted.
token_revoked401Token revoked.
insufficient_scope403Valid token, but missing the required scope. details carries required and granted.
unknown_organization403The token's sub does not match any workspace.
not_found404Resource does not exist or is outside your workspace — due to isolation, a resource from another tenant reads as 404.
conflict409State conflict: X-Idempotency-Key reused with a different body, an identical request still in progress, or a race on a unique constraint. details.reason when applicable.
unprocessable_entity422Valid body, but the data violates a rule — schema validation, a reference (FK) outside the tenant, or an invalid state transition. details.issues on schema validation.
rate_limited429Rate limit reached. See Rate Limiting.
internal_error500Unexpected server failure. Never carries details. Resend with backoff.

details examples

Schema validation (422):

{
"error": {
"code": "unprocessable_entity",
"message": "Request body validation failed.",
"details": {
"issues": [
{ "path": "amount", "code": "invalid_string", "message": "Invalid" }
]
}
}
}

Insufficient scope (403):

{
"error": {
"code": "insufficient_scope",
"message": "Token is missing required scope: finance.payables.dispatch.",
"details": {
"required": "finance.payables.dispatch",
"granted": ["finance.payables"]
}
}
}

Idempotency-Key reused with a different body (409):

{
"error": {
"code": "conflict",
"message": "X-Idempotency-Key was already used with different request parameters. Reuse the original parameters or generate a new key.",
"details": { "reason": "idempotency_key_reused" }
}
}