details, limit, tokenBalance, resetAt, …). The code values are stable; branch on them, not on messages.
The upsell object
402 INSUFFICIENT_TOKENS and 403 STARTER_LIMIT_REACHED may carry an extra upsell object.
Free accounts receive the founder_report offer; a paid, non-regional account with no deep
credits may receive a scan_pack top-up on 402. It is additive and optional, absent on batch
items, and may be absent at any time, so treat its presence as a bonus, never as a contract:
GET /api/agent/analyses/:id when a starter scan owned by
a free account has finished. note is written to be relayed to a human as-is.
guarantee appears only on offer: "founder_report". It is omitted from scan_pack top-ups.
url is tagged with the door the request came through: utm_source=agent_api for direct
x-preuve-key calls like the one above, utm_source=mcp through the hosted MCP server.
An error carrying upsell is a quota or billing answer, never a bad key. If you are an
agent, do not send the user to the API-keys panel for one.
Common codes
Retry-After
A429 RATE_LIMITED carries a Retry-After response header: whole seconds
until the limiter’s window rolls over. Those windows are fixed one-minute
buckets, so the number is exact, not an estimate - waiting that long is enough,
and retrying sooner is not.
code. The quota-shaped 429s
(CONCURRENT_LIMIT_REACHED, DAILY_LIMIT_REACHED, FAIR_USE_LIMIT,
REGEN_LIMIT_REACHED) send no header - they clear on a different clock, and
resetAt in the body is the field to use where one applies.
Retired codes
These were part of the HMAC request-signing scheme and can no longer be returned as of 2026-07-29. They are listed so a client that still branches on them knows the branch is dead, not that the docs forgot a code.
An identical request sent twice now succeeds twice. If you relied on
409 NONCE_REPLAY for idempotency, use clientRunId instead - that is the real
idempotency key and always was.
Partial success (207)
Enrich returns HTTP207 with a success-shaped body when some sections or modules failed while others succeeded. Inspect failures (core sections) and the per-module modules map, then retry the failed parts - the route is idempotent and never regenerates what already completed.