Skip to content

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, a malformed parameter, or a write's body that does not validate — a KPI result for a period that is not a reporting period's first day, or that has not closed.
  • payload_not_allowed (413) — a body sent to a read, a write's body over 4096 bytes, or a query string over 2048 bytes.
  • length_required (411) — a write's body sent without a Content-Length, such as a chunked upload.
  • workspace_read_only (402) — a write to a workspace whose subscription has lapsed. It can still be read.
  • request_timeout (408) — a write's body did not finish arriving within ten seconds.
  • busy (503) — a write found the workspace locked by other work, such as a large import, for longer than it waits. Retry after the Retry-After interval.
  • rate_limited (429) — see Rate limits.
  • internal_error (500) — ours. Retry with backoff; if it persists, send us the X-Request-ID from the response.

What to retry

Retry 429 and 503 after the interval the response gives you, and 500, 502 and 504 with exponential backoff. A KPI result write is safe to retry: the same request records once.

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.