Errors

The problem detail body, status codes, and rate limits
View as Markdown

Every error response uses the same body — RFC 9457 problem detail, served as application/problem+json. Parse one shape and you can handle every failure the API produces.

The problem detail body

type, title, status, detail, and instance are the RFC standard fields and appear on every error. Everything else is an aVenture extension, present only when it applies:

  • code — a machine-readable secondary code, from a fixed set covering auth and session, rate limiting, RBAC, job infrastructure, external providers, image processing, storage, search, and inference. It appears when the HTTP status alone does not identify the recovery path, so branch on code rather than on detail, which is prose and may be reworded. Many codes describe infrastructure conditions where the right move is to surface the error and stop, not retry.
  • hint, suggestion, resolution — how to correct the request.
  • field, value, unknownParameters, validParameters — which part of the request was rejected, on validation failures.
  • details — structured conflict information on 409, including the duplicate candidates that let you decide between updating, overriding, or aborting.
  • traceId and spanId — quote these when reporting a problem.

Status codes

StatusMeaningWhat to do
400Malformed request or invalid parameterRead field and hint; fix and resend
401Missing, malformed, or unrecognized credentialCheck the header name matches your credential type
403Valid credential, not permitted hereA client secret on a write endpoint returns this
404No such record
406Requested content type cannot be servedAccept application/json
409Conflict with an existing recordRead details for the colliding candidates
415Unsupported request content typeSend Content-Type: application/json
422Well-formed but semantically rejectedRead detail and resolution
429Rate limitedBack off — see below
500, 503Server error or dependency unavailableRetry with backoff; 503 is usually transient

Retry 429, 500, and 503. Do not retry 400, 401, 403, 404, 409, 415, or 422 — the same request will fail the same way.

Rate limits

A 429 carries the limit state in the problem detail:

1{
2 "title": "Too Many Requests",
3 "status": 429,
4 "code": "rateLimited",
5 "limit": 100,
6 "remaining": 0,
7 "used": 100,
8 "windowSeconds": 60,
9 "resetAt": "2026-09-04T12:00:00Z",
10 "retryAfterSeconds": 12,
11 "limitType": "IP"
12}

Wait retryAfterSeconds before retrying, and add jitter so parallel workers do not resume in lockstep. resetAt gives the same deadline as an absolute timestamp when you would rather schedule than sleep.

limitType names which ceiling you hit — IP, SUBNET, and GLOBAL are request-rate limits, while BILLING_ALLOWANCE, NATURAL_SEARCH, WEB_SEARCH, and INFERENCE_PROVIDER are per-feature quotas. Retrying a different endpoint often succeeds when the limit was feature-scoped.

Redirects on entity slugs

Five detail lookups can answer 301 instead of 404 when a record’s slug has changed: GET /v1/entities/detail, GET /v1/news/detail, GET /v1/people/detail, GET /v1/people/detail/investments, and GET /v1/people/detail/investor-activity. Follow the redirect — curl -L and most HTTP clients do by default — and store the slug you land on.