# Market Structure API (GEX)

> GET /api/v1/market-structure/:symbol reference: structural Gamma Exposure, intraday GEX, Gamma Flip, walls, Max Pain, IV context, session flow, and symbol metadata.

The Market Structure API returns a **precomputed, symbol-level snapshot** of full-chain dealer-positioning structure (GEX), open interest walls, Max Pain, volatility context, and five-minute session flow plus intraday GEX summaries.

```text
GET https://www.optiondata.io/api/v1/market-structure/:symbol
```

Included with the realtime plan (`trialing` or `active`). Authenticate with a signed API key.

## Authentication

Send your API key as:

```http
Authorization: Bearer YOUR_API_KEY
```

`YOUR_API_KEY` may be a raw Stripe customer id (`cus_...`) or a portal-minted `apikey_...` token.

## Path parameters

| Name | Required | Description |
|------|----------|-------------|
| `symbol` | Yes | Underlying option root (e.g. `SPY`, `SPXW`, `AAPL`). Uppercased server-side. |

## Query parameters

| Name | Required | Description |
|------|----------|-------------|
| `date` | No | `YYYY-MM-DD` retained historical snapshot. Omit for the active/latest snapshot. |

## Example

```bash
curl "https://www.optiondata.io/api/v1/market-structure/SPY" \
  -H "Authorization: Bearer YOUR_API_KEY"

curl "https://www.optiondata.io/api/v1/market-structure/SPY?date=2026-07-24" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Response shape

Top-level:

| Field | Type | Description |
|-------|------|-------------|
| `data.symbol` | string | Exact option root requested |
| `data.symbol_meta` | object | Underlying metadata and volatility context |
| `data.flow` | object | Lightweight traded-flow overlay for the symbol |
| `data.intraday_gex` | object \| null | Latest full-chain summary GEX and spot |
| `data.structure` | object | Full-chain GEX, OI, levels, strike-by-expiration aggregates |
| `meta.effective_date` | string | Snapshot trading date (`YYYY-MM-DD`) |
| `meta.structure_as_of` | string | UTC time when structure metrics were produced |
| `meta.flow_as_of` | string | UTC time of the flow overlay |
| `meta.intraday_gex_as_of` | string \| null | UTC time of the intraday GEX summary |

### `symbol_meta` highlights

| Field | Type | Description |
|-------|------|-------------|
| `underlying_type` | `STOCK \| ETF \| INDEX \| null` | Underlying classification |
| `description` | string | Company, fund, or index name |
| `open / high / low / close / last` | number | Underlying prices from the latest completed session when the structure was built. During a session this is the previous session; use `intraday_gex.spot` for the current price |
| `iv30` | number \| null | Interpolated 30-day ATM implied volatility (decimal) |
| `iv_rank_1y` / `iv_percentile_1y` | number \| null | One-year IV rank / percentile as 0–1 fractions |
| `skew_25d_30d` | number \| null | 30-day 25-delta put/call skew |
| `iv_term_slope_30_90` | number \| null | 30-to-90-day IV term slope |

### `structure` highlights

| Field | Type | Description |
|-------|------|-------------|
| `spot` | number | Underlying price used for exposure calculations |
| `call_oi` / `put_oi` | number | All-scope open-interest contract totals |
| `call_gex` / `put_gex` | number | All-scope dollar GEX for a 1% move; put GEX is signed negative |
| `scopes` | object | Levels by DTE bucket, keyed `all`, `zero_dte`, `weekly`, and `monthly`. Each value is a levels object or `null` |
| `max_pain_curve` | array | `{ strike, payout }` points: the multiplier-adjusted aggregate payout at each candidate strike. Its lowest point is `scopes.all.max_pain` |
| `expirations` | array | Full-chain strike aggregates grouped by expiration |

### `structure.scopes.<scope>` levels

Levels are only inside a scope, for example `data.structure.scopes.all.gamma_flip`. `structure` has no top-level `gamma_flip`, `max_pain`, or wall fields.

| Field | Type | Description |
|-------|------|-------------|
| `gamma_flip` | number \| null | Nearest repriced zero-net-GEX underlying level |
| `max_pain` | number \| null | Strike with lowest multiplier-adjusted aggregate payout |
| `call_gex_wall` / `put_gex_wall` | number \| null | Strongest call/put GEX strike on the corresponding side of spot |
| `call_oi_wall` / `put_oi_wall` | number \| null | Highest call/put OI strike on the corresponding side of spot |

### `flow` highlights

| Field | Type | Description |
|-------|------|-------------|
| `call_premium` / `put_premium` | number | Session option premium by side (USD) |
| `bullish_dex` / `bearish_dex` | number | Bullish and bearish delta-exposure flow totals |
| `trade_count` | number | Option trades represented by the overlay |
| `traded_contract_count` | number | Distinct contracts with trades |

### `intraday_gex` highlights

| Field | Type | Description |
|-------|------|-------------|
| `spot` | number | Latest positive underlying price used for the summary |
| `call_gex` | number | Full-chain positive call dollar GEX, including zero-trade contracts |
| `put_gex` | number | Full-chain signed-negative put dollar GEX, including zero-trade contracts |

## Semantics notes

- **Dealer positioning is a model**, not reported dealer inventory. Put GEX uses a documented dealer-short-put signing convention.
- **Net GEX** can be derived as `call_gex + put_gex` (put already signed).
- `data.intraday_gex` and `meta.intraday_gex_as_of` can refresh every five minutes during the regular session. Structural strike GEX, walls, Gamma Flip, Max Pain, OI, expirations, and `meta.structure_as_of` change only during structural builds.
- **Put/call OI ratio** can be derived as `put_oi / call_oi` when `call_oi > 0`.
- Prefer Market Structure for positioning dashboards; use the Option Chain API when you need filterable contract-level quotes and Greeks.

## Errors

| Status | Meaning |
|--------|---------|
| `400` | Invalid symbol, or a date that is not a real `YYYY-MM-DD` calendar date |
| `401` | Missing or invalid API key |
| `403` | No active/trialing realtime entitlement |
| `404` | `SNAPSHOT_NOT_FOUND` for a date with no snapshot, or `SYMBOL_NOT_FOUND` for a symbol with no data |
| `405` | `METHOD_NOT_ALLOWED`: use `GET`; the `Allow` header lists the supported methods |
| `429` | Rate limited |
| `503` | Snapshot service unavailable or timed out; retry later |
| `500` | Unexpected server error |

## FAQ

**Q: Rate limits and access?**  
A: Requires trialing or active Pro + API key. The **current default** is about **60 requests / 60 seconds** per customer on this endpoint, for trial and paid users, enforced on a best-effort basis. HTTP **429** includes `Retry-After`.

**Planned, not yet active:** trial **30/minute and 1,200/hour**; paid Pro **60/minute and 3,600/hour**. Once enabled, both limits apply per customer across their keys and IPs; reaching either triggers rate limiting. No effective date has been announced. Enterprise limits are contract-specific. See [API rate limits](/docs/api-rate-limits) for the complete policy. Subscription access remains the same as Option Chain and Historical SQL.

**Q: Freshness?**  
A: Structural levels update on builds (`structure_as_of`). Some intraday GEX fields can refresh about every **five minutes** in session—use response meta timestamps.

**Q: History range?**  
A: Dated snapshots cover recent sessions, currently back to **2026-07-24**; older sessions age out over time. For individual trades, Historical SQL covers the past **15** days on paid plans.

**Q: Free trial / extension?**  
A: Complete qualification, then explicitly activate the **14-day** Pro trial when you are ready. Eligible trial users can receive **50% off the first year with a promotion code from Sales**; contact Sales for the code, then enter it on Billing before the trial ends. Trials are not auto-extended.

**Q: Market Structure vs Option Chain?**  
A: Structure for GEX/walls/max pain dashboards; Option Chain for filterable contract quotes/Greeks.

## Related

- Product page: [/market_structure](/market_structure)
- Option chain API: [/docs/option-chain-api/](/docs/option-chain-api)
- Realtime flow: [/docs/realtime-option-trades-api/](/docs/realtime-option-trades-api)
