Skip to content

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

  1. 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.
  2. 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_date returns 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.
  3. 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.
  4. 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.capped is 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.
  5. 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-chain and /api/historical/sql (POST) and /api/v1/market-structure/{symbol} (GET). OPTIONS returns 204 with the Allow header.
  6. 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_of before doing new work.
  7. 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.
  8. 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.
  9. 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.
  10. 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.
  11. 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_key field 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.
  12. 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.
  13. 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_of remains a nullable UTC ISO 8601 string.
  14. 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 matching X-OptionData-Historical-Sql-Minimum-Data-Delay-Minutes response header.
    • Use the Realtime WebSocket API when current-session trades are needed without the historical cutoff.
  15. 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 and meta.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_of identifies 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.
  16. 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.
  17. 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_date is the returned market session. meta.as_of is 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_days and mark. close was renamed to last_price; strike and expiration_date are now non-null fields.
    • Removed response fields status, api_version, beta, notice, entitlement, source, returned, filters and statistics. The test_mode request 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.date with meta.trading_date, and replace close with last_price.
    • Requests whose result exceeds the maximum supported chain size return HTTP 422 with REQUEST_TOO_BROAD instead of partial data.
  18. 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_b are 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.
  19. 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_min and strike_max for an inclusive range.
    • strike cannot be combined with strike_min or strike_max.
    • Each value can be sent as a number or as a numeric string in a form-encoded request.
  20. 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, or strike_max to narrow a symbol request.
    • As of July 9, 2026, requests that exceed the maximum response size return an error instead of partial data.
  21. 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, and max_expiry_days.
    • Strike filtering returned on July 1, 2026 through strike, strike_min, and strike_max.
  22. 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_flow request parameter and the premium, size, trade_count, latest_trade_price, latest_trade_time, and vol_oi_ratio response fields.
    • At the time of this change, close continued to provide the latest trade price for each contract.
  23. 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 previously https://optiondata.io.
    • Update requests to POST /api/historical/sql and POST /api/option-chain to use the new base URL.
  24. 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, and meta.notice.
    • Responses also include X-OptionData-Option-Chain-Beta: true.
    • These beta fields were later removed by the July 9, 2026 response schema change.
  25. FixedRealtime WebSocketMar 5, 2026

    Corrected the documented sentiment value

    The documented neutral sentiment value is NEUTRAL.

    • Use NEUTRAL. The previous documentation misspelled the value as NEUTRUAL.
  26. 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.

This changelog covers data-API schema and contract changes. For product, billing, and platform updates, see the blog.