Skip to main content

Error format

All errors return a JSON body with error and message:
  • error is a stable slug. Branch on this — it will not change for a given condition.
  • message is prose for humans. Never parse it; the wording may change at any time without notice.
Some errors add context fields alongside those two (documented per error below). Errors are never wrapped in the data / meta envelope used by successful responses — on any endpoint — so response.json()["error"] is safe everywhere.

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 subscription doesn’t include API access. The current_tier field shows your current plan. Upgrade to Pro to 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 a crypto-only plan gets this on SPX, and a tradfi-only plan gets it on BTC. 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)

Valid values: bybit, deribit, okx, and the virtual all / combined (aggregated).

no_data (404)

The combination of coin/exchange/expiration doesn’t exist. Common causes:
  • The exchange doesn’t list options for this coin (e.g., OKX doesn’t have XRP)
  • The expiration has already expired
  • The basecoin is mistyped (must be uppercase)

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.

Getting help