Skip to main content

Error format

All errors return a JSON body with error and message. Branch on error, a stable slug; message is prose for humans and may change at any time, so never parse it. Errors are never wrapped in the data / meta envelope used by successful responses, on any endpoint, so response.json()["error"] is safe everywhere. Some errors add hint fields that let a client or an agent correct itself:

HTTP status codes

Error codes

unauthorized (401)

Check that:
  • The X-API-Key header is present
  • The key is correct (no copy-paste whitespace)
  • The key hasn’t been revoked
  • The key starts with gex_sk_
unauthorized covers two cases: no credential was supplied, and a credential was supplied but did not resolve to a user — the latter returns "Could not resolve a user identity from the supplied credentials." Both share one code deliberately, so you only need a single branch.

subscription_required (403)

Your plan doesn’t include API access (a plan entitlement, not a tier name). current_tier shows your current tier. Get API access.

market_not_in_plan (403)

Your key is valid and API access is enabled, but the symbol you requested belongs to a market your plan doesn’t cover. GammaFlip sells crypto and tradfi as separate markets, so the Crypto plan gets this on SPX or QQQ, and the TradFi plan on BTC. The Complete plan covers both. Only endpoints taking a <coin> path parameter can return this. The discovery endpoints (/exchanges, /coins) list availability rather than market data, and are never gated this way. To fix it, add the market to your subscription, or request a symbol from a market you already have.

invalid_exchange (400)

For crypto coins valid values are bybit, deribit, okx, derive, binance, all / combined, or a subset like deribit+derive; valid_exchanges lists what is currently available. See Markets and exchanges.

invalid_pair (400)

The exchange does not match the coin’s market: a crypto venue with a TradFi ticker, or tradfi with a crypto coin.

invalid_expiration (400)

The expiration isn’t one of the live expirations. nearest_expirations holds up to five ISO dates closest to the one you sent (the earliest five if the value is not a date). Use TOTAL, or pick one from nearest_expirations or /expirations.

invalid_param (400)

A query parameter is invalid: view must be full or levels (valid_values), and range_pct must be in (0, 50] (max_value). On the history endpoints it also covers an unparseable start, end, at, date or cursor, start after end, a year outside 2020 to 2100, an unknown granularity or file (valid_values), and ?compare= other than 1d, 7d, 30d or used with a single expiration.

unsupported_coin (404)

The coin is neither a crypto coin on any of our exchanges nor a US ticker we track. Returned by every {exchange}/{coin} endpoint, including history, before any exchange check. Pick a symbol from the two lists, or call /coins.

no_data (404)

The combination of coin/exchange/expiration has no data. Common causes:
  • The exchange doesn’t list options for this coin (e.g., OKX doesn’t have XRP)
  • The expiration has already expired

market_unavailable (503)

The data source for the market is down. Retry after a short delay.

rate_limit_exceeded (429)

The rate_limit object repeats the figures from the X-RateLimit-* headers.
No Retry-After header is sent. Schedule your retry from X-RateLimit-Reset (or the identical rate_limit.reset in the body).
See Rate Limits for handling strategies.

History errors

The history endpoints add these slugs.

history_not_available (400)

Venue subsets such as deribit+derive have no history. Use one venue or combined. The same applies to ?compare= on /levels.

range_too_large (400)

The window of /history/levels is longer than the granularity allows: 15m up to 31 days, 1h up to 180 days, close unlimited. Shorten the window or use a coarser granularity.

no_snapshot (404)

/history/snapshot found no capture within 15 minutes of at. Retry with one of nearest_timestamps (up to three, from the TOTAL captures).

no_file (404)

There is no daily file for that exchange, symbol, date and kind. The date is outside coverage, or the session is not complete yet. No file credit is spent.

files_unavailable (503)

File storage is down or not reachable. Retry later. No file credit is spent.

method_not_allowed (405)

A history file download was requested with HEAD. The response has Allow: GET. No file credit is spent.

history_files_limit_exceeded (429)

The daily file credits are used up (trial 20, other plans with API access 200). There is no Retry-After header; read X-History-Files-Reset or /me. See Rate limits.

Getting help