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" }
]
}
}
}
| Field | Description |
|---|---|
error.code | Stable code (table below). Branch on it. |
error.message | Human-readable text, in English. Do not parse. |
error.details | Present on some errors — useful structured data (offending field, reason, missing scope). See examples below. |
Codes
code | HTTP | When |
|---|---|---|
bad_request | 400 | Malformed query/body — invalid JSON, unknown filter/operator, invalid cursor, empty filter value, invalid limit. |
invalid_token | 401 | Token missing, malformed, invalid signature, or expired. |
invalid_audience | 401 | The token's aud is not accepted. |
token_revoked | 401 | Token revoked. |
insufficient_scope | 403 | Valid token, but missing the required scope. details carries required and granted. |
unknown_organization | 403 | The token's sub does not match any workspace. |
not_found | 404 | Resource does not exist or is outside your workspace — due to isolation, a resource from another tenant reads as 404. |
conflict | 409 | State 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_entity | 422 | Valid 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_limited | 429 | Rate limit reached. See Rate Limiting. |
internal_error | 500 | Unexpected 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" }
}
}