Errors
Every failed request returns a non-2xx HTTP status and a JSON body describing what went wrong.
The error body
{
"code": "NOT_FOUND",
"status": 404,
"message": "No pricing quote with that id.",
"defined": true
}
| Field | Notes |
|---|---|
code | Machine-readable and stable. Branch on this. |
status | The HTTP status, repeated in the body so a logged payload is self-describing. |
message | Human-readable. Written for a developer reading logs; wording can change between releases. |
defined | true when the failure is one the endpoint declares, false for an unexpected one. |
data | Extra context, present only for codes that carry any. |
message is for humans and code is for code. Matching on message text will break the first time we reword one.
Status codes
| Status | code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | The body or query parameters failed validation. |
| 401 | UNAUTHORIZED | The API key is missing or invalid. See Authentication. |
| 403 | FORBIDDEN | The key's role lacks the scope the endpoint needs, or it may not act on this resource. |
| 404 | NOT_FOUND | No such resource, or it isn't visible to this key. |
| 409 | CONFLICT | The request conflicts with the resource's current state. |
| 412 | PRECONDITION_FAILED | The resource isn't in a state that allows this operation. |
| 413 | PAYLOAD_TOO_LARGE | The request body exceeded 10 MB. |
| 429 | TOO_MANY_REQUESTS | Rate limit exceeded. See Rate limits. |
| 500 | INTERNAL_SERVER_ERROR | Something failed on our side. |
An id belonging to another organization is always refused, but the exact code varies by endpoint — expect either 403 or 404. Don't read anything into which one you get: the difference doesn't reliably tell you whether the id exists, and it isn't a distinction to build logic on. Treat both as "this key cannot reach that resource," and if you get one on an id you believe is valid, check it belongs to the key's organization.
What to retry
429— retry. Back off first; see Rate limits for the headers that tell you how long to wait.500— retry. Use exponential backoff. If it persists, get in touch with the request details.- Everything else — don't.
400,401,403,404,409,412and413describe the request, so the same request will fail the same way. Fix it rather than repeating it.
Retrying a write that may have partly succeeded is your call — the API doesn't currently accept an idempotency key, so prefer reading back the resource to confirm state before resending.