When a request fails, the API returns a non-2xx HTTP status and an error envelope with a machine-readableDocumentation Index
Fetch the complete documentation index at: https://docs.backquant.com/llms.txt
Use this file to discover all available pages before exploring further.
code field, a human-readable
message, and (sometimes) a structured details payload.
All error codes
| Code | HTTP status | When it fires |
|---|---|---|
UNAUTHORIZED | 401 | Missing, invalid, or revoked X-API-Key header. |
FORBIDDEN | 403 | Key is valid but the subscription tier doesn’t allow this resource. |
NOT_FOUND | 404 | Symbol, expiry, or other resource not present in cache or DB. |
VALIDATION_ERROR | 400 / 422 | Bad query parameter — out of range, wrong type, or unknown enum value. |
RATE_LIMIT_EXCEEDED | 429 | Per-tier rate limit hit. Retry after meta.rate_limit.reset or the Retry-After header. |
UPSTREAM_ERROR | 502 / 503 / 504 | Cache (Redis) or database (Postgres) temporarily unreachable. Retry with backoff. |
INTERNAL_ERROR | 500 | Unexpected server-side failure. Include meta.request_id when reporting. |
/v2/meta — useful if you want to keep your
client’s error map in sync with the API.
Handling errors in code
Always checksuccess before reading data. Use error.code to branch
your error handling.
Guidance per code
UNAUTHORIZED — Check the X-API-Key header is present, the value
has no leading/trailing space, and the key hasn’t been revoked at
backquant.com/api-access.
FORBIDDEN — Your subscription doesn’t allow this resource.
Usually a sign you’ve downgraded a paid tier or your subscription
lapsed.
NOT_FOUND — Don’t retry. Either the symbol/expiry doesn’t have
cache yet (cold start, or unsupported symbol), or the path is wrong.
VALIDATION_ERROR — Read error.details.errors for the failing
parameter list. Common causes: passing BTC instead of BTCUSDT,
unsupported ?greek= value, out-of-range numeric param.
RATE_LIMIT_EXCEEDED — Read Retry-After header (or
meta.rate_limit.reset) and wait. The
/v2/options/chain is the most expensive
single endpoint — if you’re polling it aggressively, batch with
multi-symbol bundles or pull only the
contracts you need with ?max_contracts.
UPSTREAM_ERROR — Transient. Exponential backoff (2s, 4s, 8s)
usually clears it within ~30s. If it persists past a minute, check
/v2/health.
INTERNAL_ERROR — Always include meta.request_id when reporting
to dev@backquant.com. We trace by it.
Always-present headers
Even on errors, the response carries:X-RateLimit-Limit— your tier’s per-minute capX-RateLimit-Remaining— calls left in the current windowX-RateLimit-Reset— Unix timestamp when the window resetsRetry-After— seconds until safe to retry (on 429 only)X-Request-ID— the same UUID asmeta.request_id
See also
Rate limits
Per-tier limits and how to think about backoff.
Authentication
Avoiding
UNAUTHORIZED errors.Data freshness
What
NOT_FOUND actually means per endpoint.