Skip to content

Errors

Every failure returns the same envelope, with the HTTP status carrying the class and code carrying the specific reason:

{
"success": false,
"error": "Upload exceeds the maximum allowed size",
"code": "PAYLOAD_TOO_LARGE",
"details": { "maxBytes": 262144000 },
"timestamp": "2026-08-19T09:41:12.004Z",
"requestId": "req_01J..."
}

Branch on code, never on error. The message is English prose written for a human reading a log; it can be reworded in any release. code is contract. details carries the machine-readable specifics for the codes that have them.

Keep requestId. It identifies the request in our logs, and quoting it in a support conversation is the difference between a diagnosis and a guessing game.

Code Status Means
BAD_REQUEST 400 Malformed request — a parameter is the wrong shape.
INVALID_CURSOR 400 The pagination cursor is unreadable or tampered with.
UNAUTHORIZED 401 Missing, invalid, revoked or expired key — or a path that does not exist.
FORBIDDEN 403 The key is valid but lacks the scope, or the record is out of its reach.
NOT_FOUND 404 No such record in this organization.
CONFLICT 409 The write contradicts the current state.
LENGTH_REQUIRED 411 A raw binary upload arrived without Content-Length.
PAYLOAD_TOO_LARGE 413 Upload over the ceiling. details.maxBytes carries it.
VALIDATION_ERROR 422 Failed validation — a rejected file type, a checksum mismatch, a cross-field rule.
TOO_MANY_REQUESTS 429 Rate limited. Honour Retry-After.
BILLING_FEATURE_REQUIRED 402 The organization’s plan does not include this capability.
STORAGE_QUOTA_EXCEEDED 402 The organization is out of document storage.
IMPORT_ROW_QUOTA_EXCEEDED 402 The import exceeds the plan’s per-import row cap. details carries submittedRows and limitRows.
INTERNAL_ERROR 500 Our fault. Retry with backoff; quote requestId if it persists.
SERVICE_UNAVAILABLE 503 Temporarily unable to serve — including object storage being unconfigured for the environment.
  • 429 — wait for Retry-After, then continue. Not an error in your code; a signal to slow down.
  • 5xx — retry with exponential backoff and jitter. Cap the attempts.
  • 4xx other than 429 — do not retry. The request will fail identically until you change it.

Writes are not automatically idempotent, so a blind retry of a POST can duplicate work. The two upload endpoints are the exception: they are idempotent on file content, which is what makes an interrupted bulk run safe to re-run.