Market-data endpoints expose trading sessions, strikes, index price history, and option-chain snapshots. Several work without authentication for the most recent completed session (the index series also covers the in-progress one); strikes and option-chain snapshots always need an account, as do the full history and 1-second resolution — see access levels.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET |
/market-data/sessions |
Available trading sessions |
GET |
/market-data/strikes/{date} |
Strikes for a date |
GET |
/market-data/historical/{date} |
Index series for a date |
GET |
/market-data/option-chain-snapshots/{timestamp} |
Chain at one moment |
GET |
/market-data/option-chain-snapshots/{startTime}/{endTime} |
Chain over a range |
GET |
/market-data/average-expected-move |
Average expected-move series |
POST |
/market-data/options-prices/{date} |
Net mid price of a custom order |
For authenticated requests the metered endpoints also carry a rate-limit cost — the sessions list and the average expected-move curve are free; see rate limits for the per-endpoint figures.
Sessions
curl -s https://api.0dtespx.com/market-data/sessions -H "Authorization: $TOKEN"
GET /market-data/sessions
Lists every known trading session, keyed by date, with its trading and data bounds. Runnable signed out — a visitor sees every session flagged restricted except the most recent completed one and today's in-progress session. Pick a date from the response for the blocks below, which each need an account.
Interactive — run this request from the docs
Returns a map keyed by date:
{
"2025-01-15": {
"start-time": "2025-01-15T14:30:00Z",
"end-time": "2025-01-15T21:00:00Z",
"data-start-time": "2025-01-15T14:31:00Z",
"data-end-time": "2025-01-15T21:00:00Z",
"current": true
}
}
start-time/end-time are the trading-session bounds; data-start-time/data-end-time are the bounds of historical data (usually a minute narrower on the open). Three optional boolean flags qualify a session: current: true marks today's in-progress session (always 1-second data for everyone); upcoming: true marks a listed session that hasn't started yet (today's date before the open); for unauthenticated callers, restricted: true marks every session except the most recent completed one and today's in-progress session — for authenticated users no session is restricted. Times are UTC; the trading day is 9:30 AM–4:00 PM ET.
Strikes
curl -s https://api.0dtespx.com/market-data/strikes/2025-01-15 -H "Authorization: $TOKEN"
# → [5800, 5805, 5810, …]
GET /market-data/strikes/{date}
Returns the day's SPX strike ladder, ascending. Needs a signed-in account. Swap in a date from the sessions map above — a date that isn't a trading session answers 404.
Interactive — run this request from the docs
Index history
curl -s "https://api.0dtespx.com/market-data/historical/2025-01-15?series=spx,vix,spxExpectedMove" \
-H "Authorization: $TOKEN"
GET /market-data/historical/{date}
Returns the session's index price series — one point per sample, carrying whichever series you request. Signed out it serves only the most recent completed session and today's in-progress one, so a fixed example date needs an account. The series toggle is off by default — leave it off for spx,spxExpectedMove, or switch it on to pick the columns. A whole session at 1-second resolution is a long response.
Interactive — run this request from the docs
Selectable series: spx, vix, spxExpectedMove, spxOTMBids, spxExtrinsic (default spx,spxExpectedMove). Each point carries a datetime, a unix timestamp, and each requested series as a decimal string. A series you don't request is omitted from the row entirely. spx is always a string when requested; vix, spxExpectedMove, spxOTMBids, and spxExtrinsic can be null for a row when the value is not yet computed (e.g. the expected move before the option chain warms up). Public (no auth) for the most recent and current sessions; sample rate is 1 second authenticated, 30 seconds unauthenticated — except the in-progress session, which is 1 second for everyone until it closes.
Option-chain snapshots
A single-timestamp snapshot (timestamp path format YYYY-MM-DDTHH:MM:SS, UTC):
curl -s https://api.0dtespx.com/market-data/option-chain-snapshots/2025-01-15T15:00:00 \
-H "Authorization: $TOKEN"
GET /market-data/option-chain-snapshots/{timestamp}
Returns the whole option chain at one instant — bid, ask and delta for every strike's call and put. Needs a signed-in account. The timestamp is UTC and must fall inside the session's data window, which starts at that session's data-start-time and ends at its data-end-time (roughly 14:30–21:00 UTC outside DST, 13:30–20:00 UTC during it; the sessions map above has the exact bounds). Anything before data-start-time answers 404. A full chain is a large response — the viewer shows the first slice with a Show all control.
Interactive — run this request from the docs
{
"call_5950": { "bid": 4.20, "ask": 4.40, "delta": 0.523 },
"put_5950": { … }
}
Keys are call_<strike> and put_<strike>. Each quote carries bid, ask, and delta (a signed decimal — the wire preserves the stored sign, so a put delta may be negative; current data emits magnitudes, so in practice values are 0..1 positive). The range form (also authenticated) returns up to 30 snapshots between two times at a 1-second interval, so the range can span at most 30 seconds; each array entry is { "timestamp", "options" }, with the same keyed map under options.
Chain availability starts at the session's data-start-time. Both forms are bounded below by it — the same instant the sessions map reports for that date, and the same one that gates opening a live session and placing a practice order. The chain is not served before it:
- A single-timestamp read below the bound returns
404. - A range that starts below the bound returns only the snapshots at or after it — the early part is dropped, not an error.
- A range lying entirely below the bound returns
404, not an empty array.
This applies to every date, historical sessions included, and it is not always "the first minute": data-start-time is usually a minute past the open, but on a session whose data begins late it can be considerably later. Read it per date from GET /market-data/sessions rather than assuming an offset from start-time.
The bound is the same one the live_option_chain WebSocket channel applies, so the two surfaces agree: while today's session is before its data-start-time, neither the channel nor these endpoints will hand you a chain.
Clamping does not change what a range costs — see rate limits.
Multi-leg order mid prices
POST /market-data/options-prices/{date} prices a custom multi-leg SPX 0DTE order (up to 4 legs) across a whole session. For every timestamp in the session's data range it returns the order's net mid price — the sum over the legs of ±quantity × (bid + ask) / 2 — with no slippage and no fees. It's the endpoint behind the order-price overlay on the research chart.
curl -s https://api.0dtespx.com/market-data/options-prices/2025-01-15 \
-H "Authorization: $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"items": [
{ "direction": "long", "side": "call", "strike": 6000, "quantity": 1 },
{ "direction": "short", "side": "call", "strike": 6010, "quantity": 1 }
]
}'
POST /market-data/options-prices/{date}
A POST that writes nothing — it prices the legs across the session and returns a series. Signed out it serves only the most recent completed session, so a fixed example date needs an account. Strikes have to exist on the date (see the strikes block above), or you get 404.
Interactive — run this request from the docs
[
{ "timestamp": "2025-01-15T14:31:00Z", "datetimeUnix": 1736951460, "price": "2.50", "effect": "debit" },
{ "timestamp": "2025-01-15T14:31:01Z", "datetimeUnix": 1736951461, "price": "2.48", "effect": "debit" }
]
Each leg has a direction (long/short), a side (call/put), an integer strike, and a quantity (1–100). price is the absolute net at two decimals; effect is debit when the order is paid for and credit when it collects premium (plot the value as negative for a credit if you want a signed line). The series is clamped to the session's data-start-time/data-end-time, and any timestamp missing a leg's quote is left out. Public (no auth) for the most recent completed session at 30-second resolution; authenticated users get every session at 1-second resolution.
Average expected move
GET /market-data/average-expected-move returns the average expected-move series ordered by second of session. Each point is { second_of_session, avg_pct_of_open }; values map to time by their own second_of_session. Public, and cached by the browser for 24 hours.
Rate limiting
Authenticated accounts meter market-data requests against a per-endpoint credit budget; unauthenticated traffic isn't rate-limited (it's confined to the most recent session instead). See rate limits for the leaky-bucket mechanism and each endpoint's cost.