Reference
Errors
Every failure has a status, a stable code, and a request id. The status tells you what to do; the code tells you what happened.
The body#
An error is a JSON object with ok: false and a stable error code. Text is never interpolated into the body, so the code is safe to branch on.
{
"ok": false,
"error": "validation_failed"
}What each status means, and what to do#
| Status | Code | What to do |
|---|---|---|
400 | validation_failed | A parameter was present and unacceptable (limit, cursor, or a stamped clinic header). Fix the request; retrying unchanged will fail the same way. |
401 | unauthorized | No credential, or one that did not verify. Do not retry. Check the key, or rotate it. |
403 | forbidden_clinic | The key verified but holds no live clinic grant. Ask for the grant; retrying will not help. |
403 | forbidden_scope | The key verified but lacks the scope the route requires. The missing scope is deliberately not named in the response. |
403 | forbidden_ip | The key verified, but the request did not come from an address on the allowlist. This only happens once your integration is moved to enforce mode; alert mode records mismatches without refusing anything. Ask us to add the range. |
429 | rate_limited | Quota exhausted. Wait for Retry-After. See rate limits. |
500 | internal_error | Our bug. Report it with the request id; retrying may work but we want to know. |
503 | service_unavailable | We could not check the credential or the quota. Carries Retry-After: 5. Retry with the same key. This is never a statement about the key. |
Do not conflate 401 and 503
A client that treats503 as an invalid key deletes a working credential during our outage and blames itself. Retry 503; never retry 401.Request ids#
Every response, including refusals, carries x-request-id. On a successful read the body carries the same value as request_id. Quote either when reporting a problem; they reach the same log row.
Retry strategy, in one table#
| Status | Retry? | How |
|---|---|---|
400 | No | Fix the request first. |
401 | No | Fix or rotate the key; alert. |
403 | No | Request the grant or scope. |
429 | Yes | After Retry-After, with jitter. |
500 | Maybe | Exponential backoff, capped; report it. |
503 | Yes | After Retry-After, same key, backoff. |