Errors

Every error on the API is a machine-readable RFC 9457 problem document. The shape of that document and the full set of status codes you can expect.

Every error the API returns is a single, machine-readable shape: RFC 9457 application/problem+json. You never have to parse a bespoke error format or scrape a string, on any endpoint.

The shape

http
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
json
{
  "type": "about:blank",
  "title": "Forbidden",
  "status": 403,
  "detail": "key lacks required scope: sources:write"
}
FieldMeaning
typeA URI identifying the error kind. Defaults to about:blank when the status code alone is enough.
titleA short, stable, human-readable summary of the status.
statusThe HTTP status code, repeated in the body for convenience.
detailA specific explanation of this occurrence. Safe to log; read it, do not pattern-match on it.

Status codes

StatusWhen you see it
400The request is malformed, or a filter is invalid or over your key's term cap. A ?source_type=push with no narrowing (keyword, tag, or source) is rejected here, so nobody streams a whole push tier unfiltered.
401The API key is missing, malformed, or revoked.
403The key is valid but lacks the scope the operation requires, or tries to widen beyond what it is bound to.
404The resource does not exist, is not yours, or the channel is unknown.
410A resume cursor (Last-Event-ID) is older than your retained history window. Reconnect without it to resume from the live tail.
422The request is well-formed but semantically invalid (for example, rotating the signing secret of a destination that is not a webhook).
429The key's rate limit is exceeded. Honor the Retry-After header.
500An unexpected server error. Safe to retry with backoff.
503A feature is not enabled on this deployment, or no capacity is available to serve the request.

Handling them

  • Retry 429 after Retry-After, and 500 / 503 with exponential backoff.
  • Do not retry 400, 401, 403, 404, or 422 unchanged; they will fail again. Fix the request, the key, or the scope first.
  • On 410, drop the cursor and reconnect to resume from the live tail. See resume without gaps.