Referência da API

Errors & rate limits

Error shape, status codes, rate limits, and which failures are worth retrying.

Errors return a non-2xx status and a single detail field with a human-readable message. There is no machine-readable error code — branch on the HTTP status.

401 Unauthorizedjson
{
  "detail": "chave de acesso inválida"
}

Status codes

StatusMeaningRetry?
400Malformed request — invalid body, or (on the extraction endpoints) a file too large for the plan's context windowNo — fix the request
401Missing, invalid, or expired keyNo
404Unknown endpointNo
413Request body, file, page count, or schema over the plan's limitNo — shorten or split it
422max_tokens outside the accepted rangeNo — fix the value
429Per-key rate limit or the plan's daily token quota was hit — see Rate limitsYes, with the Retry-After header
502The model didn't return output matching the request (e.g. schema-constrained JSON)Sometimes — see the endpoint's own error table
503Infrastructure is starting, restarting, or briefly out of capacity — see Rate limitsYes, with the Retry-After header

/v1/documents/extract, /v1/images/extract, and /v1/documents/generate add a few statuses beyond this table — see Structured extraction and PDF generation.

Retrying

Retry only 429 and 503, sleeping for the number of seconds in Retry-After. Retrying a 4xx never succeeds — it burns a request for no benefit.

retry.tstypescript
async function withRetry(fn: () => Promise<Response>, attempts = 5) {
  for (let attempt = 0; ; attempt++) {
    const res = await fn();
    if (res.status !== 429 && res.status !== 503) return res;
    if (attempt >= attempts - 1) return res;
    const wait = Number(res.headers.get("Retry-After") ?? 5);
    await new Promise((resolve) => setTimeout(resolve, wait * 1000));
  }
}

Rate limits

Two independent limits, neither a queue — a request either goes through immediately or gets rejected with 429/503 for you to retry.

Requests per minute

Each API key has a token-bucket limit, refilled continuously up to a per-minute ceiling that scales with plan: 60/min (Go), 120/min (Pro), 300/min (Max), or a custom ceiling (Enterprise). Go over it and you get 429 with Retry-After telling you how many seconds until there's room.

Daily token quota

Separate from the per-minute limit, and off by default: a cap on tokens generated per account per day. Where it's enabled, exceeding it returns 429 with Retry-After: 3600. This catches a different failure mode than the per-minute limit — few requests, each generating a lot of tokens (long documents, verbose reasoning, large max_tokens) — which a request count alone doesn't.

Capacity, not a fixed concurrency tier

Capacity is elastic per machine, not a fixed slot count per plan — a stack running alone on its infrastructure can use nearly all of it; other stacks on the same infrastructure share it as they show up. Two 503 cases follow from that:

Retry-AfterMeaning
~5sNo free capacity at this instant — usually resolves on the next attempt
~60sYour plan's infrastructure was paused for inactivity and is starting back up — expected on the first request after idle time, not a failure

Extraction and generation endpoints have their own file size and page/resolution ceilings on top of all this, which scale with plan — see the Limits section on Structured extraction and PDF generation.