Options Snapshot API — FMV, Greeks, IV & OI
The core cvforge dataset is a live snapshot of every listed U.S. option contract — sourced from Massive’s options snapshot feed, ingested continuously, and refreshed in the serving database about once a minute. Each contract carries supported contract terms, Massive fair market value (FMV), Greeks, implied volatility, open interest, session aggregates, and the underlying’s price.
Pricing boundary: cvforge does not provide option bid/ask quotes,
quote sizes, midpoint, NBBO, or last-trade data. fair_market_value is the
only current per-contract valuation field. It is a proprietary estimate, not an
executable quote, and must not be presented as one.
The /chains endpoint returns the full chain for one underlying,
grouped by expiration and strike with calls and puts side by side — the natural
shape for IV surfaces, Greeks ladders, skew charts, open-interest walls, and
payoff tools. To filter across underlyings instead, use the
screener; for free-form aggregation, use
SQL.
Coverage
- Every optionable U.S. stock and ETF (the universe refreshes daily against the snapshot feed).
- Index options via the
I:prefix:I:SPX,I:VIX,I:NDX,I:RUT,I:XSP. - Open interest updates once daily after the close; FMV, Greeks, IV, and session data update with the snapshot.
Calling it
In an app built in cvforge (see the cvApi reference):
const data = await cvApi.chain('SPY');
// or pick exactly the fields you need:
const iv = await cvApi.chain('SPY', ['expiration_date', 'strike_price', 'contract_type', 'implied_volatility']); Over REST — a GET with comma-separated params, or a POST with a JSON body:
curl -H "Authorization: Bearer cv_live_..." \
"https://tap.convexvalue.com/api/data/chains/SPY?params=expiration_date,strike_price,contract_type,implied_volatility,delta,fair_market_value" POST /api/data/chains
{ "symbol": "SPY", "params": ["expiration_date", "strike_price", "contract_type", "implied_volatility"] }
From a coding agent, the MCP tool is get_chain — see the
MCP reference.
Request rules
symbol: 1–24 characters, auto-uppercased; letters, digits, and. - / :.params: 1–32 supported field names from the table below (duplicates are dropped). Omitting fields incvApi.chain()selects the supported default set.- Responses include an
x-cv-cache: hit|missheader; the GET form also setsCache-Control: private, max-age=15, so browsers can re-render cheaply while staying fresh.
Response shape
Contracts are grouped by expiration, then strike. Each strike row is a compact
triple: [strike, callValues, putValues], where the value arrays follow
the order of your requested params (either side can be null
if that contract doesn’t exist).
The values below illustrate the compact response shape; they are not a captured market response.
{
"symbol": "SPY",
"params": ["implied_volatility", "delta", "fair_market_value"],
"chain": [
{
"expiration": "2026-07-17",
"strikes": [
[640.0, [0.22, 0.71, 18.42], [0.24, -0.29, 5.11]],
[645.0, [0.21, 0.64, 14.96], [0.23, -0.36, 6.57]]
]
}
],
"contract_count": 12488,
"elapsed_ms": 41
} All 31 supported fields
Fields marked default are what you get when you don’t specify
fields: contract_type, expiration_date, strike_price, implied_volatility, open_interest, delta, gamma, theta, vega, day_volume, underlying_price.
Identity
| Field | Type | Description |
|---|---|---|
underlying_ticker | text | Underlying symbol the contract belongs to, e.g. AAPL or I:SPX. |
ticker | text | The option contract symbol in OCC-style format, e.g. O:SPY260116C00400000. Use this as the ticker for historical bars. |
Contract terms
| Field | Type | Description |
|---|---|---|
contract_type default | text | "call" or "put". |
expiration_date default | text | Expiration date, YYYY-MM-DD. |
strike_price default | number | Strike price of the contract. |
exercise_style | text | "american" or "european". |
shares_per_contract | number | Deliverable shares per contract (typically 100). |
Pricing & valuation
| Field | Type | Description |
|---|---|---|
implied_volatility default | number | The market’s volatility forecast implied by the option’s current price, as a decimal fraction (0.25 = 25%). |
open_interest default | number | Contracts held open as of the end of the last trading day. Updated once daily after the close. |
break_even_price | number | Underlying price at which the position breaks even: strike + premium for calls, strike − premium for puts. |
fair_market_value | number | Massive’s proprietary fair market value (FMV) estimate. This is the only current per-contract valuation field; it is not a bid, ask, NBBO, or executable quote. |
Greeks
| Field | Type | Description |
|---|---|---|
delta default | number | Sensitivity of the option price to a $1 move in the underlying. |
gamma default | number | Rate of change of delta per $1 move in the underlying. |
theta default | number | Time decay: change in option value per day, all else equal. |
vega default | number | Change in option value per 1-point change in implied volatility. |
Day (session OHLCV)
| Field | Type | Description |
|---|---|---|
day_open | number | Session open price of the contract. |
day_high | number | Session high. |
day_low | number | Session low. |
day_close | number | Session close (or latest) price. |
day_previous_close | number | Previous session’s closing price. |
day_change | number | Price change on the day. |
day_change_percent | number | Percent change on the day. |
day_volume default | number | Contracts traded so far today. |
day_vwap | number | Volume-weighted average price for the session. |
day_last_updated | timestamp (ns) | When the daily bar was last updated (epoch nanoseconds). |
Underlying
| Field | Type | Description |
|---|---|---|
underlying_price default | number | Current price of the underlying asset. |
underlying_symbol | text | Symbol of the underlying asset as reported by the snapshot. |
underlying_change_to_break_even | number | How far the underlying must move to reach the break-even price. |
underlying_last_updated | timestamp (ns) | When the underlying price was last updated (epoch nanoseconds). |
underlying_timeframe | text | Whether the underlying price is REAL-TIME or DELAYED. |
Metadata
| Field | Type | Description |
|---|---|---|
fetched_at | timestamp | When this row was ingested from the upstream snapshot (server time). |
Errors & limits
400— unknown field name, empty/too-long params, or invalid symbol.401— missing or revoked API key.429— your plan’s hourly request limit is exhausted; it resets on the hour.
Get example prompts & new data guides
Occasional emails with prompts worth trying and what’s new in the data.