Skip to main content
Every failure in the Developer API returns the same JSON envelope. Branch on code, never on error. This page lists the envelope fields, the status codes the API can return, the complete code set, and the retry policy that goes with each.

The error envelope

Published as components.schemas.Error and referenced by every operation in the OpenAPI document. Only error and code are always present.
Error envelope
string
required
Human-readable explanation of the failure. Show it to a person. Never branch on it — the wording changes without notice.
string
required
Stable machine-readable code. This is the only field you may branch on. The set below is complete today and only grows.
string
For validation failures, the dot-separated path of the rejected request field, such as where.published_after or cursor. Absent when the failure is not tied to one field.
string
The recommended next step for this specific failure. Written for an agent to act on directly.
boolean
Whether repeating the identical request can succeed. When false, change the request or stop. When absent, fall back to the status code class.
number
Seconds to wait before retrying. Mirrors the Retry-After header when one is sent. See Rate limits.
string
Additional context, when the failure has any.
Some failures add fields beyond the envelope. A 409 from a plan limit also carries current, limit, tier, upgradeAvailable, and contact. Read them when present; do not require them.

Status codes

These twelve failure statuses are the complete published set. The API returns nothing else on the documented paths.
429 is the only status that always carries retry timing. 503 never does — choose your own backoff.

Error codes

The codes you are most likely to see, harvested from the server. Branch on these; treat a code that is not listed the same way you treat a new one.

Credentials and access

Quotas

Requests

Resources

Conflicts

Upstream and dependencies

Article failures

POST /v1/articles/extract, POST /v1/articles/read, and POST /v1/articles/search return these codes from the extraction layer. They are uppercase — that is deliberate and stable. Several are permanent: retrying burns quota and never succeeds.
Do not retry PAYWALL_ERROR, UNSUPPORTED_PUBLISHER, VALIDATION_ERROR, or ARTICLE_CONTENT_UNAVAILABLE. Each retry spends an operation from the account budget and the result never changes.

Retry policy

Four rules cover every failure:
  1. Never retry a 4xx unchanged. The only exceptions are 429 and the 409 codes commit_in_progress and asset_upload_busy, which are retryable as sent.
  2. Honour Retry-After. On 429 the server tells you exactly how long to wait. Waiting less wastes the retry.
  3. Back off exponentially with jitter on 5xx. Cap attempts at three. Unjittered retries from many workers re-create the overload.
  4. Trust retryable when it is present. It overrides the status-class heuristic. commit_in_progress is a 409 with retryable: true; that is not a contradiction.
An unrecognised code means smry added one. Treat it as retryable once, then stop and report it.

A retry helper

Both implementations branch on code first, retryable second, and the status class last.

Next

Rate limits

The numbers behind every 429, and how to read your own remaining budget.

Retries and idempotency

Which retries are safe, and the three mechanisms that make them safe.
Last modified on September 13, 2026