Errors
Errors share one envelope (see the overview). Branch on code, log meta.request_id, and treat message as English text for humans.
Client errors
Section titled “Client errors”| Code | Status | Meaning and what to do |
|---|---|---|
validation_failed |
400 | A field failed validation. field names it; details explains. Fix the field. |
bad_request |
400 | The request could not be read at all: malformed JSON, a broken Content-Encoding stream, an aborted body. There is no field to fix; check the transport. |
validation_error |
400 | X-Account-Id was sent to an endpoint that forbids it (/auth/login, /auth/refresh, /auth/swap-company, /auth/logout). |
cursor_expired |
400 | The pagination cursor is older than 24 hours. Start the listing again. |
unauthenticated |
401 | Missing or invalid token. Refresh the session or check the key. A sign-in locked after ten failed attempts (30 minutes) is answered the same way as a wrong password, on purpose. |
invalid_signature |
401 | A webhook signature did not verify. See Webhooks. |
forbidden |
403 | The token is valid but lacks the permission. |
account_context_mismatch |
403 | X-Account-Id does not match the token’s account. The client’s notion of the current company has drifted; re-read it from the session. |
not_found |
404 | The resource does not exist or belongs to another account or site. The API never distinguishes the two. |
conflict |
409 | State conflict: optimistic lock, unique constraint, or an action not allowed in the current state (for example writing to a merged conversation). |
idempotency_key_conflict |
409 | The Idempotency-Key was reused with a different body. |
payload_too_large |
413 | The body exceeds the limit for this endpoint family. |
unsupported_media_type |
415 | Wrong Content-Type. |
unprocessable |
422 | Valid JSON, but a business rule refused it (for example a booking slot outside working hours). |
storage_quota_exceeded |
422 | The account reached its plan’s storage limit. details carries used_bytes, quota_bytes and requested_bytes; free space or upgrade. |
rate_limited |
429 | Slow down. Honour Retry-After and details.retry_after_seconds. |
Server errors
Section titled “Server errors”| Code | Status | Meaning and what to do |
|---|---|---|
internal_error |
500 | Unexpected failure. Retry once, then contact support with request_id. |
upstream_unavailable |
502 | The gateway could not reach the service at all. A short retry usually succeeds. |
service_unavailable |
503 | Planned maintenance or an open circuit breaker. Retry after the Retry-After header. |
ai_vendor_out_of_funds |
503 | Your AI provider refused the call for billing reasons (a 402 or a quota 429 from the vendor). Top up the vendor account; a retry will not help. |
upstream_timeout |
504 | The service did not answer in time. Retry when retry_after is present. |
Retrying
Section titled “Retrying”Retry 429, 502, 503, 504 and network failures with exponential backoff, and send the same Idempotency-Key on the retry so that a write is never applied twice. Do not retry 4xx other than 429.