Last updated: Oct 2, 2026
API Changelog
Schema and contract changes to the OptionData data APIs — Market Structure, Option Chain, Realtime WebSocket, and Historical SQL. Breaking changes are marked.
For the current request/response schema, see each product page: Option Chain · Market Structure · Historical SQL · Realtime
- FixedOption ChainOct 2, 2026
Bid and ask filled from session trades
bid and ask are now the best bid and ask recorded with the contract's most recent trade in the session. Previously most contracts returned no quote, and past sessions had none.
- This applies to the latest session and to every past date. A contract that did not trade in the session still returns null for both fields.
- The quote is from the contract's last trade, so a contract that last traded early in the day carries that earlier quote.
- ChangedOption ChainBreakingOct 2, 2026
Invalid dates and missing chains return errors
Requests that cannot return a chain now fail with an error instead of returning another session or an empty 200.
- An impossible calendar date such as 2026-02-30 in date or
expiration_datereturns 400 INVALID_REQUEST. Previously it could return the chain of a later session. - A date with no stored session (weekend, holiday, future, or outside retention) returns 404 SNAPSHOT_NOT_FOUND. A symbol with no chain on the session returns 404 SYMBOL_NOT_FOUND.
- A chain whose filters match no contract still returns 200 with an empty data array.
- An impossible calendar date such as 2026-02-30 in date or
- FixedOption ChainBreakingOct 2, 2026
Unavailable quotes and Greeks are null
bid and ask are null when no quote is stored for a contract, instead of 0. implied_volatility and the Greeks are null together when no model value is available, instead of 0.
- Handle null before arithmetic on these fields. A single 0, such as a bid of 0 with a positive ask, is still a real value.
- AddedHistorical SQLOct 2, 2026
Historical SQL reports truncation and error codes
Successful responses include meta.truncated, which is true when the query produced more rows than meta.row_limit. Every error response now includes errorCode.
meta.cappedis unchanged: it means the trial row cap applies, not that rows were cut off.- New errorCode values: INVALID_REQUEST, INVALID_SQL, UNAUTHORIZED, SUBSCRIPTION_REQUIRED, RATE_LIMITED, and METHOD_NOT_ALLOWED.
- FixedGeneralOct 2, 2026
Unsupported HTTP methods return 405
Calling an HTTP data API with the wrong method returns 405 METHOD_NOT_ALLOWED with an Allow header, instead of the website home page.
- Applies to
/api/option-chainand/api/historical/sql(POST) and/api/v1/market-structure/{symbol} (GET). OPTIONS returns 204 with the Allow header.
- Applies to
- ChangedOption ChainOct 1, 2026
Latest option chains update about every 90 seconds
During U.S. market hours, requests without date return a chain that refreshes about every 90 seconds: contracts that trade receive newer quotes, Greeks, IV, volume, open interest, and last price.
- The request and response contract is unchanged. Poll every one to two minutes at most and compare
meta.as_ofbefore doing new work.
- The request and response contract is unchanged. Poll every one to two minutes at most and compare
- ChangedHistorical SQLBreakingSep 12, 2026
Paid Historical SQL access limited to the past 15 days
Paid (active) subscriptions query only the past 15 days of trades — 360 elapsed hours, including weekends and holidays. The existing 15-minute delay remains.
- Older trades are excluded before joins and aggregations. A query spanning the boundary includes only eligible trades; an older-only row query returns no rows.
- Update queries that use older dates to target recent dates. Paid success responses include
meta.lookback_days: 15. - Trial access, row limits, and synthetic test-mode samples are unchanged.
- FixedRealtime WebSocketAug 19, 2026
Connection-limit retries are now protected
When an API token already has five concurrent realtime connections, a new WebSocket or SSE handshake now returns HTTP 429 with Retry-After while existing connections remain open.
- Respect Retry-After and use exponential backoff before retrying. Close unused connections so one token stays within its five-connection limit.
- The server no longer evicts an existing connection when a sixth handshake arrives.
- FixedHistorical SQLAug 15, 2026
Numeric overflow now returns an actionable query error
Historical SQL expressions that exceed the supported numeric range now return HTTP 422 with errorCode = INVALID_QUERY and reason = NUMERIC_OVERFLOW instead of HTTP 500.
- Cast fixed-precision operands before multiplying or aggregating them; for example, use SUM(toFloat64(price) * size * 100) for premium calculations.
- The response remains privacy-safe and does not include the submitted SQL or database-internal error text.
- FixedHistorical SQLAug 13, 2026
Invalid Historical SQL now returns INVALID_QUERY
Queries with unknown columns, functions, aliases, or incompatible data types now return HTTP 422 with errorCode = INVALID_QUERY instead of HTTP 500.
- The response now includes a privacy-safe reason such as UNKNOWN_IDENTIFIER plus an actionable errorMsg, without exposing database-internal text.
- Correct the SQL before retrying. Use errorCode to distinguish INVALID_QUERY from QUERY_TOO_BROAD, QUERY_TIMEOUT, and INTERNAL_ERROR.
- AddedGeneralAug 10, 2026
Bearer authentication added to HTTP data APIs
Historical SQL and Option Chain now accept API keys through Authorization: Bearer, matching Market Structure.
- Send Authorization: Bearer YOUR_API_KEY using the API key generated in the OptionData portal.
- The
api_keyfield in a JSON or form body remains supported for backward compatibility when the Authorization header is absent. - When Authorization is present, it takes precedence over
api_key. Unsupported authentication schemes or invalid header formatting return HTTP 401.
- ChangedHistorical SQLBreakingAug 10, 2026
Stable Historical SQL execution errors
Historical SQL execution failures now return consistent HTTP statuses, error codes, and messages.
- Queries that scan too much data return HTTP 422 with errorCode = QUERY_TOO_BROAD. Add narrower date, symbol, or other filters before retrying.
- Execution timeouts return HTTP 504 with errorCode = QUERY_TIMEOUT.
- Unexpected execution failures return HTTP 500 with errorCode = INTERNAL_ERROR.
- FixedOption ChainAug 10, 2026
Option Chain as_of timestamp corrected
Option Chain meta.as_of now reports the correct UTC timestamp for the latest data included in the response.
- Previous values could be shifted by four or five hours. The correction applies automatically and requires no client changes.
- The response shape is unchanged:
meta.as_ofremains a nullable UTC ISO 8601 string.
- ChangedHistorical SQLBreakingAug 10, 2026
Minimum 15-minute data delay enforced
Historical SQL now returns only trades whose execution timestamps are at least 15 minutes old.
- The cutoff applies to all Historical SQL queries, including nested queries, joins, and aggregations.
- At 10:00:00 ET, the newest visible execution timestamp is 09:45:00 ET. Data can be older than 15 minutes, but never newer than the minimum delay.
- Success metadata now includes
meta.minimum_data_delay_minutes= 15 and the matchingX-OptionData-Historical-Sql-Minimum-Data-Delay-Minutesresponse header. - Use the Realtime WebSocket API when current-session trades are needed without the historical cutoff.
- AddedMarket StructureJul 27, 2026
Intraday GEX summary and update time
Added a nullable five-minute full-chain GEX summary and its update timestamp to v1 responses.
- Successful responses now include data.
intraday_gex: { spot,call_gex,put_gex} | null andmeta.intraday_gex_as_of: string | null. - During the regular session, flow and intraday GEX can refresh every five minutes. GEX includes zero-trade contracts; flow fields continue to include traded contracts only.
structure_as_ofidentifies when strike GEX, walls, Gamma Flip, Max Pain, OI, and expirations were last calculated. These values do not refresh with the five-minute flow update.- This is an additive v1 schema change; existing structure and flow fields retain their meaning.
- Successful responses now include data.
- AddedMarket StructureJul 24, 2026
Market Structure API response schema v1
Added the v1 success and error contracts for full-chain symbol snapshots.
- New endpoint: GET
/api/v1/market-structure/:symbol. Authenticate with Authorization: Bearer YOUR_API_KEY; add date=YYYY-MM-DD for a retained historical snapshot. - Successful responses use { data: { symbol,
symbol_meta, structure, flow }, meta: {effective_date,structure_as_of,flow_as_of} }. - Errors use { error: { code, message } }. Stable codes include INVALID_REQUEST, UNAUTHORIZED, SUBSCRIPTION_REQUIRED, SNAPSHOT_NOT_FOUND, SYMBOL_NOT_FOUND, RATE_LIMITED, UPSTREAM_UNAVAILABLE and INTERNAL_ERROR.
- The data and meta objects include call/put GEX by strike and expiration, GEX/OI walls, Gamma Flip and Max Pain by scope, plus the latest options-flow metrics.
- Symbol metadata is self-contained: underlying type, description, exchange, sector, market cap, shares, earnings, prices, average volume, historical volatility, IV30, IV Rank/Percentile, skew, butterfly, and term slope.
- Put GEX is signed negative. Net GEX, gross GEX, put/call ratios, and gamma regime are intentionally derivable from the strike data rather than duplicated in the payload.
- New endpoint: GET
- ChangedOption ChainBreakingJul 9, 2026
Option Chain response schema simplified
Breaking change: successful responses now use { data, meta: { trading_date, as_of } }, while errors use { error: { code, message } }.
meta.trading_dateis the returned market session.meta.as_ofis the latest data update represented in the response, formatted as a UTC ISO 8601 timestamp; it can be null when unavailable.- Contract rows removed symbol,
expiry_daysand mark. close was renamed tolast_price; strike andexpiration_dateare now non-null fields. - Removed response fields status,
api_version, beta, notice, entitlement, source, returned, filters and statistics. Thetest_moderequest parameter was also removed. - Errors now provide a stable code and message. Codes include INVALID_REQUEST, UNAUTHORIZED, SUBSCRIPTION_REQUIRED, REQUEST_TOO_BROAD, RATE_LIMITED, INTERNAL_ERROR and QUERY_TIMEOUT.
- Migration: read data directly instead of checking status === "SUCCESS"; replace
meta.datewithmeta.trading_date, and replace close withlast_price. - Requests whose result exceeds the maximum supported chain size return HTTP 422 with REQUEST_TOO_BROAD instead of partial data.
- ChangedHistorical SQLJul 3, 2026
Historical SQL validation rules expanded
Unsupported multi-table and table-function query forms now return validation errors.
- Comma-separated joins such as FROM
table_a,table_bare rejected. - Use the documented table names without a database prefix; references to other databases are rejected.
- Table functions such as url(), remote(), and merge(), plus # comments, are rejected.
- The documented single-table SELECT examples are unaffected.
- Comma-separated joins such as FROM
- AddedOption ChainJul 1, 2026
Strike price filters
Added strike filtering to the Option Chain request.
- New request parameters: strike for an exact match, plus
strike_minandstrike_maxfor an inclusive range. - strike cannot be combined with
strike_minorstrike_max. - Each value can be sent as a number or as a numeric string in a form-encoded request.
- New request parameters: strike for an exact match, plus
- RemovedOption ChainBreakingJun 26, 2026
Removed the limit request parameter
The API no longer accepts a client-supplied limit parameter.
- Use date,
expiration_date,put_call, strike,strike_min, orstrike_maxto narrow a symbol request. - As of July 9, 2026, requests that exceed the maximum response size return an error instead of partial data.
- Use date,
- RemovedOption ChainBreakingJun 25, 2026
Removed strike and expiry range parameters
Removed the older strike and expiry range parameters.
- Removed request parameters:
min_strike,max_strike,min_expiry_days, andmax_expiry_days. - Strike filtering returned on July 1, 2026 through strike,
strike_min, andstrike_max.
- Removed request parameters:
- RemovedOption ChainBreakingJun 25, 2026
Removed flow fields and include_flow
The optional flow fields and the include_flow toggle were removed from the response.
- Removed the
include_flowrequest parameter and the premium, size,trade_count,latest_trade_price,latest_trade_time, andvol_oi_ratioresponse fields. - At the time of this change, close continued to provide the latest trade price for each contract.
- Removed the
- ChangedGeneralBreakingJun 22, 2026
API base URL moved to www
The canonical API host is now the www subdomain.
- The base URL is now
https://www.optiondata.io; it was previouslyhttps://optiondata.io. - Update requests to
POST /api/historical/sqlandPOST /api/option-chainto use the new base URL.
- The base URL is now
- AddedOption ChainJun 21, 2026
Beta metadata in responses
Every Option Chain response now advertises its beta status.
- Responses include
meta.api_version="v1",meta.beta= true, andmeta.notice. - Responses also include
X-OptionData-Option-Chain-Beta: true. - These beta fields were later removed by the July 9, 2026 response schema change.
- Responses include
- FixedRealtime WebSocketMar 5, 2026
Corrected the documented sentiment value
The documented neutral sentiment value is NEUTRAL.
- Use
NEUTRAL. The previous documentation misspelled the value asNEUTRUAL.
- Use
- RemovedRealtime WebSocketBreakingFeb 24, 2026
Removed realtime trade-data fields
Several fields were dropped from real-time trade messages.
- Removed fields:
bid_size,ask_size, vega, theta, rho, and exchange.
- Removed fields:
This changelog covers data-API schema and contract changes. For product, billing, and platform updates, see the blog.