Docs
GET /v2/options/{symbol}/vol/surface

Implied-volatility surface for one underlying

vol_getSurface

Every contract of one underlying whose implied volatility ITMatrixHQ's greeks engine solved, as one point each. Use it to plot the raw volatility surface or smile.

Path parameters

symbol string required

Registered underlying, e.g. SPY

Details

Points are raw: not interpolated, smoothed or fitted, so a gap in the surface is a contract that did not solve. Each point carries expiry, strike, right, iv, delta, gamma, mark (the option price the solve used), mark_source (which price that was, such as the last trade or the quote midpoint) and moneyness. The expiries summary is the same as GET /v2/options/{symbol}/vol/term. A full SPY surface is several thousand points.

Units

  • iv is annualized, as a fraction (0.1286 = 12.86%).
  • strike is in integer thousandths of a dollar (765000 = $765.00).
  • mark is dollars per share; spot is dollars.
  • moneyness is strike / spot, unitless.
  • as_of_ms is epoch milliseconds.

Freshness

Updated with every new solve during market hours; outside them, the last solve is served.

Limits

No per-operation limit applies to requests with an API key.

Empty results

An underlying the engine does not cover yet returns 200 with as_of_ms: null, empty expiries and points, and a meta.note. An unregistered symbol is 404 not_found.

Example

http
GET /v2/options/SPY/vol/surface
json
{
  "data": {
    "symbol": "SPY",
    "as_of_ms": 1790256746156,
    "spot": 764.09,
    "expiries": [
      {
        "expiry": "2026-09-25",
        "dte": 0,
        "atm_strike": 764000,
        "atm_iv": 0.1189,
        "n_contracts": 268
      }
    ],
    "points": [
      {
        "expiry": "2026-09-25",
        "strike": 765000,
        "right": "call",
        "iv": 0.1286,
        "delta": 0.466,
        "gamma": 0.0455,
        "mark": 4.735,
        "mark_source": "options_trades",
        "moneyness": 1.0012
      }
    ]
  }
}

Response

Prices are dollars, timestamps epoch milliseconds, strikes integer thousandths of a dollar; null means unknown. Units →

200application/json

{symbol, as_of_ms, spot, expiries, points} in data; empty with a meta.note when the underlying is not covered

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
as_of_ms integer · int64 nullable epoch ms
expiries array<VolTermExpiry> required
atm_iv number · double nullable

Mean of the call and put IV at atm_strike.

atm_strike integer · int64 nullable 1/1000 $

The ATM strike (integer thousandths), or null when no strike in this expiry has both rights solved.

dte integer · int64 required

Calendar days from the current ET session to expiry.

expiry string required ISO date

YYYY-MM-DD.

n_contracts integer required

Contracts in this expiry whose IV solved.

points array<VolSurfacePoint> required
delta number · double nullable
expiry string required
gamma number · double nullable
iv number · double required
mark number · double required
mark_source string required
moneyness number · double required

strike / spot.

right string required

call | put.

strike integer · int64 required 1/1000 $

Integer thousandths of a dollar.

spot number · double nullable
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.

StatusMeaning
400

invalid_params

401

unauthenticated

403

not_entitled_tier — the symbol's own entitlement class

404

not_found — symbol is not registered