跳到主要内容

Docs/Option Chain API

Option Chain API

POST /api/option-chain reference: full U.S. option chains with strikes, expirations, bid/ask, OI, IV, Greeks, and optional flow fields.

Open product page →

Beta. This API is in beta testing. The request and response schema (fields, units, and semantics) may change. Each response includes meta.api_version, meta.beta: true, and meta.notice, plus an X-OptionData-Option-Chain-Beta: true header.

The Option Chain API exposes per-contract chain rows for an underlying, for a given trading date:

POST https://www.optiondata.io/api/option-chain

It is included with the realtime plan — both trialing and active realtime subscriptions get full access. Signed-in users without realtime access can use test_mode=true for 10 sample rows.

Request

JSON and form (application/x-www-form-urlencoded / multipart/form-data) bodies are supported. Field names are snake_case.

Required:

  • symbol: one underlying ticker (uppercased by the server; 1–16 chars).

Optional:

  • api_key: cus_... (raw Stripe customer id) or a generated apikey_... token. If omitted, the signed-in session is used.
  • date: YYYY-MM-DD. If omitted, the latest available date in mv_contract_rank_flow is used (meta.filters.date_mode reports explicit vs latest).
  • expiration_date: YYYY-MM-DD.
  • put_call: CALL or PUT.
  • min_strike, max_strike: numbers.
  • min_expiry_days, max_expiry_days: integers (days to expiration).
  • include_flow: boolean (default false) — include the flow fields (see below).
  • limit: default 1000, capped by OPTION_CHAIN_MAX_ROWS.
  • test_mode: boolean — return 10 sample rows (still requires a resolvable customer; skips the realtime-subscription gate only).

Source and semantics

Reads mv_contract_rank_flow, a per-contract-per-day materialized mart, with aggregate-state merge functions grouped by option_symbol for the requested date. Several fields are derived in the query (see the Response tables). Prices are in USD; Greeks/IV are decimals (e.g. IV 0.22 = 22%).

Response — core fields (always returned)

{ "status": "SUCCESS", "data": [ ... ], "meta": { ... } }

FieldTypeNotes
symbolstringUnderlying ticker
option_symbolstringOCC option symbol
put_callCALL | PUT
strikenumber | nullStrike price
expiration_datestring | nullYYYY-MM-DD
expiry_daysnumber | nullDays to expiration = dateDiff(date, expiration_date)
bidnumber | nullBest bid
asknumber | nullBest ask
marknumber | nullBid/ask midpoint; falls back to the latest trade price when there is no two-sided quote (bid>0 && ask>0)
closenumber | nullLatest trade price — NOT a settlement/closing price
open_interestnumber | null
open_interest_changenumber | nullopen_interest − prior-day OI (prior OI null ⇒ treated as 0)
volumenumber | nullDaily volume
implied_volatilitynumber | nullDecimal
delta / gamma / theta / veganumber | nullGreeks (decimal)

Response — flow fields (only when include_flow=true)

FieldTypeNotes
premiumnumber | nullTotal premium = ask + bid + mid premium
sizenumber | nullTotal contracts = ask + bid + mid size
trade_countnumber | null
latest_trade_pricenumber | nullLast trade price (same value as close)
latest_trade_timestring | null
vol_oi_rationumber | nullvolume / open_interest (open_interest 0 ⇒ 0)

A field is null when the value is not present in the source row. (Note: dex/sentiment fields are not returned by this endpoint.)

Response — meta

FieldNotes
api_versionSchema version (currently v1)
betatrue while the API is in beta
noticeBeta notice string
entitlementactive | trialing | sample (sample for test_mode)
sourcemv_contract_rank_flow
dateThe snapshot date used
row_limitEffective row cap
returnedRow count returned
filtersEcho of applied filters incl. date_mode (explicit/latest)
statisticsPassthrough ClickHouse query stats (when available)
test_modetrue for sample responses

Errors

All errors return { "status": "ERROR", "errorMsg": "..." } with an HTTP status:

StatusMeaning
400Invalid body or failed request validation (errorMsg lists the problems)
401Could not resolve a customer (missing/invalid api_key and no session)
403Resolved, but no active/trialing realtime subscription
429Rate limited (best-effort, in-memory, per-customer; honors Retry-After)
504Query timed out
500Unexpected server error