API reference

Market data API

Sessions, strikes, history, and option-chain snapshots.

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.