Guide
Conventions
On this page
Parameters#
All parameters go in the query string. POST /v1/exports and POST /mcp take JSON bodies.
| Type | Format |
|---|---|
| string | At most 128 characters unless the endpoint says otherwise. Symbols have their own patterns. |
| integer, number | Plain decimal digits: 100, -3, 0.25. No exponent and no thousands separators. |
| decimal (strikes) | Positive, at most 6 decimal places in general and 3 for option strikes: 5800, 5812.5. |
| boolean | Exactly true or false. |
| enum | A lowercase snake_case token from the documented list: rth, above_ask. |
| list | Comma-separated in one parameter: symbols=SPX,NDX,VIX. Each endpoint documents the maximum number of items. |
time (unix-ms) | Unix epoch milliseconds, an integer between 946684800000 (2000-01-01) and 4102444800000 (2100-01-01). |
| date | YYYY-MM-DD. |
Strict parameters#
Strictness is deliberate, so a typo never silently changes what you asked for:
- An unknown parameter is
400 unknown_parameter(the names are listed), a repeated parameter is400 duplicate_parameter(use a comma-separated list), a missing required parameter is400 missing_parameterand an invalid value is400 invalid_parameter.error.detailsnames every offending parameter and what is wrong with it. - An empty value, or a value with leading or trailing spaces or control characters, is invalid.
- The whole query string may be at most 2,048 bytes and 32 parameters (
400 query_too_large). - Percent-encode values.
curl --data-urlencodedoes it for you, and so doesURLSearchParams.
Time#
- Every timestamp, in requests and responses, is a Unix millisecond integer (UTC). Names are
timestamp,*_timestamp,start_time,end_timeand*_time(a bar's start). Never a string, never seconds. start_timeis inclusive andend_timeis exclusive.- Native 64-bit values that can exceed 2^53 (tick counts, nanosecond order keys) are returned as strings so JavaScript clients do not lose precision. The field descriptions say which.
- Dates are
YYYY-MM-DD. Adateis the exchange-local trading date (America/New_York). For futures and for overnight option sessions the trading date is the date the session belongs to: an overnight session that runs the evening before and the morning of 2026-10-16 is trading date 2026-10-16.
Sessions#
All times are Eastern Time. /v1/market/sessions, /v1/futures/sessions, /v1/options/sessions and /v1/market/calendar return the windows for a date, including holidays and early closes.
| Market | Session | Hours (ET) |
|---|---|---|
| Options | Regular, rth | 09:30 to 16:15 for index and ETF options |
| Options | Overnight, gth | 20:15 the evening before to 09:25 |
| Options | Curb | 16:15 to 17:00 |
| Futures | Globex | 18:00 to 17:00 |
| Stocks | Pre-market, regular, after-hours | From 04:00; 09:30 to 16:00; until 20:00 |
Option contracts#
An option contract is identified by four parameters, required on every contract-level endpoint (/v1/options/contract/...):
| Parameter | Meaning |
|---|---|
underlying_symbol | The option root: SPXW (weekly and daily, PM-settled SPX options), SPX (monthly, AM-settled), NDXP, RUTW, XSP, QQQ, SPY and so on. SPX and SPXW are different roots with different contracts. |
contract_type | call or put. |
strike | Dollars, for example 5800 or 5812.5 (at most three decimals). |
date_of_expiry | YYYY-MM-DD. |
Responses identify a contract with option_symbol, an OCC-style 21-character symbol: the root padded to six characters, YYMMDD, C or P, then the strike times 1,000 in eight digits (SPXW 261016C05800000). Contract rows also carry underlying_symbol, contract_type, strike and date_of_expiry as separate fields.
Aggregate option endpoints (chains, flow, exposure, volatility, open interest) take underlying_symbol and optional contract_type, date_of_expiry, min_dte and max_dte, and strike bounds. On them SPX means the SPX family (both the SPX and SPXW roots) and SPXW selects the weekly root alone. The endpoint description says how it treats a family.
Futures roots and dated contracts#
symbol is the product root (ES, NQ, CL, GC; one to three letters or digits) and contract is an exact dated contract (ESZ6: root, month code FGHJKMNQUVXZ, year). Give one of them; a request with neither is 400 missing_parameter.
- With only a root, the front month is used and every response echoes the resolved
contract. - Two-digit years (
ESZ26) are accepted and answered in the one-digit form. - Only the front month and the contracts listed by /v1/futures/contracts are served. Any other contract is
422 data_unavailable. - /v1/futures/products lists the supported products with tick size, point value, exchange and trading hours.
Indices and stocks#
symbol is a single instrument and symbols a comma-separated list, bounded per endpoint: 50 for the snapshots and 10 for /v1/indices/basis/snapshot. Indices use their plain symbols, never a feed prefix: SPX, NDX, DJI, RUT, XSP, VIX, VIX1D, VIX9D and VVIX are served, and /v1/indices/list returns the current set and which of them have a futures pair for the basis endpoints. Stock symbols are tickers such as AAPL or BRK.B.
Paths and versioning#
All paths are lowercase and kebab-case: /v1/{family}/{resource}[/{sub-resource}]. /v1 is the version. Additive changes (new endpoints, new optional parameters, new response fields) can appear in /v1 at any time, so ignore fields you do not know. A breaking change would be published under /v2 and /v1 would keep working alongside it.
Every REST endpoint is GET, with two documented exceptions because the protocols require it: POST /mcp and POST /v1/exports. Any other method on a known path answers 405 method_not_allowed with Allow: GET, and an unknown path answers 404 not_found. Both use the standard error body.