Errors
Everything fails in one shape.
{
"error": {
"code": "forbidden",
"message": "This key does not hold the people:read scope."
}
}
code is stable and safe to branch on. message is written for a person reading a log and may change. Some errors carry details with more to work with — a validation failure names the fields.
The codes
unauthorized(401) — the key was not accepted. Every reason answers identically; see Authentication.forbidden(403) — a valid key without the scope this endpoint needs.not_found(404) — no such record in this workspace. A record belonging to somebody else answers exactly the same way, because telling the two apart would confirm that an id names a real record somewhere.invalid_request(400) — a filter value outside the accepted set, an altered cursor, or a malformed parameter.payload_not_allowed(413) — a request body, or a query string over 2048 bytes. This API is read-only and accepts no body.rate_limited(429) — see Rate limits.internal_error(500) — ours. Retry with backoff; if it persists, send us theX-Request-IDfrom the response.
What to retry
Retry 429 after the interval the response gives you, and 500, 502, 503 and 504 with exponential backoff.
Do not retry 400, 401, 403 or 404. Nothing about them changes on a second attempt, and a client that retries a 401 in a loop is how a key gets locked out of a rate-limit window it did not need to spend.
Every response carries a request id
X-Request-ID: 3f9a2c1e-...
Log it. If you need to ask us what happened to a request, that is the one piece of information that lets us find it.