/v2/gex/{symbol}/history Every GEX capture of one session
gex_getHistory
Every capture of one exchange session, oldest first, each shaped like a GET /v2/gex/{symbol}/grid response. Use it to replay how dealer gamma exposure moved through a day.
Path parameters
symbolstring requiredUnderlying symbol, e.g.
SPY
Query parameters
datestring ISO dateExchange session to read, ISO
YYYY-MM-DD(required).fromstringWindow start,
HH:MMexchange time (ET) ondate, inclusive. Default: the start of the day.tostringWindow end,
HH:MMexchange time (ET) ondate, exclusive. Default: the end of the day.by_expirybooleantruereturns one row per(strike, expiry)instead of one net row per strike.topinteger · int32Keep only the N strikes with the largest absolute
gexin each capture. Requests with an API key that omit it gettop=20.
Details
from and to narrow the result to a window of the day; meta.session_open and meta.session_close give that date's regular session (09:30 and 16:00, or 13:00 on a half day). net_gex always covers the full curve, before any top trim.
Units
gex,net_gexanddelta_adjare dollars of dealer hedging per $1 move in the underlying (calls positive, puts negative).- Share-denominated GEX is dollar GEX ÷ the capture's
spot, usingprior_close_spotwhenspotisnull. Delta-adjusted shares aredelta_adj÷ the same price. strikeis in integer thousandths of a dollar (600000= $600.00);call_oiandput_oiare contracts.spot,prior_close_spotandflip_pointare dollars;captured_atis epoch milliseconds.
GEX on this route is in dollars. For shares or delta-adjusted figures and how to convert, see Units: dollars, shares and delta-adjusted.
Freshness
A new capture lands every 5 minutes during the session. A past session never changes, so its response carries a strong ETag and answers If-None-Match with 304 Not Modified; today's session is not cached.
Limits
A full session is large (SPY untrimmed is about 14 MB). Requests with an API key that send no top get top=20 (about 0.7 MB for SPY), echoed as meta.top with meta.top_defaulted: true; send an explicit top for more or fewer strikes, and from/to to narrow further. No other per-operation limit applies.
Empty results
A weekend, a holiday, a symbol without GEX coverage, or a window with no capture returns 200 with captures: [].
Example
GET /v2/gex/SPY/history?date=2026-09-24&top=1{
"data": {
"symbol": "SPY",
"session_date": "2026-09-24",
"captures": [
{
"captured_at": 1790253412446,
"spot": 763.36,
"prior_close_spot": 767.18,
"net_gex": -1241673953.06,
"flip_point": null,
"strikes": [
{
"strike": 760000,
"gex": -230644255.65,
"call_oi": 65552,
"put_oi": 164210,
"delta_adj": -60586711.02
}
]
}
]
},
"meta": {
"capture_count": 12,
"session_open": "09:30",
"session_close": "16:00",
"top": 1
}
}Response
Prices are dollars, timestamps epoch milliseconds, strikes integer thousandths of a dollar; null means unknown. Units →
200application/json
{symbol, session_date, captures[]} in data; each capture is {captured_at, spot, prior_close_spot, net_gex, flip_point, strikes[]} with the grid's units and row shape. from/to (ET HH:MM) narrow the bundle to the half-open [from, to) window on captured_at; both default to the whole calendar day. A session with no captures — a weekend, a holiday, a symbol the engine does not cover, or a window nothing was captured in — is captures: [], never synthesized. meta.session_open/meta.session_close carry the exchange calendar's regular session for that date (null on a non-trading date). Past sessions carry a strong ETag (over the window and the body) and honour If-None-Match with 304; today's session is uncached.
object
A successful response: the payload consumers parse plus response metadata. data shapes are the platform types — never reshaped by the envelope.
data object required
The session bundle: one symbol, one ET session, every capture.
captures array<GexHistoryCapture> required
captured_at integer · int64 required epoch ms Epoch ms; ascending across captures.
flip_point number · double nullable null unless the cumulative net actually crosses zero.
net_gex number · double required USD Per-$1-move dollars, summed over the full curve (before any top trim).
prior_close_spot number · double nullable USD Previous session's close, dollars.
spot number · double nullable USD Underlying price the capture was valued at, dollars.
strikes array<GexGridStrike> required
call_oi integer · int32 nullable Call open interest, contracts.
delta_adj number · double nullable $ per $1 move Delta-adjusted exposure, dollars per $1 move. null on older historical rows captured before the field existed.
expiry string · date nullable ISO date Present only with by_expiry=true.
gex number · double required $ per $1 move Net dealer gamma exposure at this strike, dollars per $1 move (calls positive, puts negative).
gex_0dte number · double nullable The part of gex from the nearest (0DTE) expiry, when known.
put_oi integer · int32 nullable Put open interest, contracts.
strike integer · int64 required 1/1000 $ Strike in integer thousandths of a dollar (exact OSI unit)
session_date string · date required ISO date symbol string required meta object required
Response metadata.
caps object nullable
meta.caps — the entitlement caps that shaped this response. applied lists the caps that actually changed it (for example range_clamped).
applied array<string> required Which caps actually shaped this response (e.g. range_clamped). Empty = nothing was clamped.
darkpool boolean nullable Whether this account can use Off-Exchange in the site.
flow boolean nullable Whether the OPRA option-flow capability (flow) is granted to this principal in the app: site Pro plus a CBOE non-professional attestation (never on an itm_ key). Emitted explicitly — true and false — by the account endpoints, so the app reads the grant instead of inferring it from tier and attestation; absent on routes that do not report it.
gexDepth string nullable GEX data depth when the route reports it. Camel-cased to match the browser capability bundle; absent on unrelated routes.
tier string required The tier the request was served under.
cursor string nullable Opaque continuation cursor (pass back as ?cursor=); absent when there is nothing more to read.
plane string nullable Which serving tier answered the read (meta.plane). Informational provenance: treat it as an opaque label, because new values may appear.
Errors
Every error is the JSON error envelope; branch on error.code.
| Status | Meaning |
|---|---|
| 400 |
|
| 401 |
|
| 403 |
|
| 502 |
|
| 503 |
|