The envelope
Every endpoint returns the same three-field wrapper, success and failure alike. There is no “sometimes it is a bare object” case, so you can parse one shape.message is written for a person and is safe to surface in a UI. result.code
is the stable identifier to branch on. Match on code, never on message,
which may be reworded.
Health probes (
/health, /healthz, /readyz) and the billing webhook are
the only endpoints that are not enveloped.Status codes
Handling errors
Retrying safely
429and5xxare worth retrying with exponential backoff and jitter.400,401, and402are not. They fail identically until you change something.- Searches are idempotent in effect but not in billing: a retried search is
a new charge unless it hits the cache. Prefer re-fetching a known result with
GET /api/search/searches/{id}, which is free.
Partial failures
POST /api/search/contents returns 200 even when some URLs fail. Check each
entry for an error field before reading its content. See
Page content.