Skip to main content
Every non-2xx response from the API returns a JSON body with a structured error object and a request_id. Branch on error.type or error.code — never on the human-readable message, which is written for people and may be reworded at any time.
The top-level status and message fields are retained for backwards compatibility with earlier integrations. New code should read error.

Fields

string
The broad error class. Stable for the life of v1 — safe to switch on permanently. See the table below for the complete set.
string
The specific reason. New codes may be introduced within an existing type, so treat an unrecognised code as its type rather than as a failure to parse.
string
A human-readable explanation. Display it, log it, but do not parse it.
string
Present when the error is attributable to one request parameter — the field to highlight in a form or fix in a payload.
string
A deep link to the section of this page describing the code.
string
Unique per request, also returned as the X-Request-Id response header — on every response, including successful ones. Include it in any support request; it is how we find your call in our logs.

Error types

Handling errors

Retry api_error (5xx) and rate_limit_error (429) with exponential backoff. Never blind-retry a 4xx other than 429 — the request will fail identically every time.

Common codes

unauthenticated

401. No Authorization header, or the token is not a recognised wai_ key or JWT. Check you are sending Authorization: Bearer wai_... and that the key has not been revoked in Settings → API Keys.

permission_denied

403. The credential is valid but not allowed here. The most common cause is an OAuth access token (wai_oat_) attempting a write — those are read-only outside the MCP tool surface. Use a wai_ API key for writes.

not_found

404. No resource with that id is visible to your key. Note that a resource belonging to another workspace also returns not_found, not permission_denied — we don’t confirm the existence of records you can’t see.

invalid_request

400. The body or query string failed validation. When the problem is one field, error.param names it.

payload_too_large

413. The request body exceeded the 50 MB limit. Split large transcript or file payloads across multiple calls.

rate_limited

429. Over a published limit. Honour the Retry-After header. Full detail in Rate limits.

internal_error

500. An unhandled failure on our side. Retry with backoff; if it persists, open a support request with the request_id.

Getting help

Include the request_id — from the body or the X-Request-Id header — in every support conversation. It resolves in seconds what a description of the symptoms resolves in days.