Skip to main content
Workspace admin

API errors

Every rejected call returns the same JSON shape, whatever went wrong. Read the code, not the message — the code is stable, the wording is not.

The envelope

{
"error": {
"code": "access_denied",
"message": "invalid or expired widget token",
"correlation_id": "9f3c…",
"details": [
{ "field": "question", "message": "must not be blank" }
]
}
}

correlation_id is present when you send one, as X-Correlation-Id or X-Request-Id. Send one per request and log it — it is what lets us find your call in our logs. details appears only for field-level validation failures.

Codes

StatuscodeWhat happenedRetry?
401access_deniedNo token, or one that is unknown, expired or presented from a domain it does not allow.No — issue a new token
403access_deniedThe token is valid but not for this knowledge base.No
403entitlement_missingThe workspace is not entitled to this module.No
402billing_deniedThe workspace has no spend authorisation left.No — top up
422schema_invalidquestion is missing or blank.No
413payload_too_largeThe request body exceeds the limit.No
429rate_limitedToo many requests.Yes, after a pause
503kb_reindexingThe knowledge base is rebuilding its index and cannot answer yet.Yes
503dependency_unavailableA service behind the answer is down.Yes
503service_auth_unavailableInternal authentication is temporarily unavailable.Yes
504timeoutThe answer took too long.Yes
500internal_errorAn unhandled fault on our side — including a request body that is not valid JSON, which is not reported as a validation error.Once, then report it

Back off between retries rather than repeating immediately — a retryable code means the condition is expected to clear, not that it has.

The three you will actually hit

401 within an hour of working. The token expired. Tokens last 60 minutes by default; see Developer access and widget tokens.

401 from a browser but not from curl. The page's origin is not on the token's list. A call from your own server sends no Origin header and is accepted; a browser one must match exactly, scheme and port included — https://app.example.com does not cover http://app.example.com.

503 kb_reindexing. Someone changed the knowledge base's embedding settings and it is rebuilding. Nothing is wrong; queries resume when it finishes.

Not an error

A 200 with abstained: true means Elie found no evidence good enough to answer from. Show the message to the reader — retrying the same question produces the same result.

Next

Steps verified on . Something wrong with this page?