Content-Type: application/problem+json and a consistent JSON shape.
Error response format
Status code reference
4xx — client errors
5xx — server errors
Common errors
Validation (422)
Required fields missing or wrong types.Unique constraint (409)
Duplicate value on a unique column. Theerrors[].field tells you which column.
Foreign key (422)
Referencing a related record that doesn’t exist.Not found (404)
Rate limit exceeded (429)
Retry-After:
Query timeout (504)
Field names in errors
Database column names are converted to camelCase in error messages — a constraint oncreated_at reports the field as createdAt. This matches what you send and receive in JSON bodies.
Handling errors in code
Switch onstatus first, then on type for ambiguous statuses:
FAQ
Why are validation errors 422 and not 400?
Why are validation errors 422 and not 400?
400 means the request itself was malformed (bad JSON, wrong content type). 422 means the request was syntactically fine but semantically invalid — required fields missing, types wrong, constraints violated. The distinction tells your code whether to retry the same payload or fix the request shape first.What's the difference between 401 and 403?
What's the difference between 401 and 403?
401 means “we don’t know who you are” — the auth token is missing, expired, or invalid. 403 means “we know who you are, but you can’t do this” — the role doesn’t have the necessary permission. Refresh tokens for 401; surface a permission error for 403.Should I retry on 5xx?
Should I retry on 5xx?
Yes, with exponential backoff. Most 5xx errors are transient. Cap retries at 3–5 and alert if they keep failing.
Can I get more detail than `detail`?
Can I get more detail than `detail`?
The
errors array gives field-level reasons. For complex cases, the instance URL points to the request that failed — useful for support tickets.What happens to a `Idempotency-Key` request when it errors?
What happens to a `Idempotency-Key` request when it errors?
2xx and 4xx responses are cached and returned on retry with the same key. 5xx responses are not cached, so retries actually re-run the operation. See Idempotency.