Venue depth
Coming: being prepared. No session is published yet, so these routes answer 404 for now; the changelog dates the first session when it is served. This page is the reference for what they will return.
stocks-venue-mbp is one venue’s book by price (market by price): every price-level change at
full depth, with nanosecond timestamps. Ask for depth=1 and the same data comes back as the
top of book after each event that changed it. Coverage will run forward from the first session
published; each night will add the newest session, and published sessions are kept.
curl -sD - "https://getmarkethistory.com/query/v1/mbp/stocks-venue-mbp/AAPL?depth=1&start=2026-11-03T14%3A30%3A00Z&limit=10000" \ -H "Authorization: Bearer $MARKET_HISTORY_KEY"from markethistory import Client
mh = Client() # reads MARKET_HISTORY_KEY
top = mh.mbp("AAPL", depth=1, start="2026-11-03T14:30:00Z", limit=10_000).to_pandas()import jsonimport os
import requests
url = "https://getmarkethistory.com/query/v1/mbp/stocks-venue-mbp/AAPL"params = {"depth": 1, "start": "2026-11-03T14:30:00Z", "limit": 10000}headers = {"Authorization": f"Bearer {os.environ['MARKET_HISTORY_KEY']}"}
rows = []while True: r = requests.get(url, params=params, headers=headers, timeout=60) r.raise_for_status() # see /docs/errors for what each status means rows += [json.loads(line) for line in r.text.splitlines() if line] print(r.headers["X-Row-Count"], "rows,", r.headers["X-Bars-Charged"], "bars") if "X-Next-Cursor" not in r.headers: break params["cursor"] = r.headers["X-Next-Cursor"]HTTP/2 200content-type: application/x-ndjsonx-row-count: 10000x-bars-charged: 1000x-next-cursor: eyJ…
{"ask_ct":2,"ask_px":348.52,"ask_sz":200,"bid_ct":1,"bid_px":348.49,"bid_sz":100,"sequence":4471022,"timestamp":"2026-11-03T14:30:00.000184211Z"}Shape and headers as served; the values are illustrative, not copied from a response.
One ticker per request. /api/v1/sources lists the dataset ids under mbp.
| Parameter | Meaning |
|---|---|
depth |
Omit for every update. 1 for the top of book (below). Any other value is a 400. |
start, end |
Event-time range (RFC 3339 or a bare date), both inclusive. Default: everything held. |
limit |
Rows per page: default 10,000, maximum 100,000. |
cursor |
X-Next-Cursor from the previous page (it belongs to one ticker and one depth). |
format |
jsonl (default), csv, json, parquet or arrow. mbt1 is bars only. |
Pages run in the venue’s sequence order. Follow X-Next-Cursor (or the Link header) until it is
absent: pages join exactly, with no row repeated or skipped, and the cursor holds no server state.
With depth=1 a page can hold fewer rows than limit, even none, when the top stays unchanged
over a long stretch: the cursor still moves on, so keep following it.
Columns: every update
Section titled “Columns: every update”| Column | Type | Meaning |
|---|---|---|
timestamp |
timestamp | matching-engine time, UTC, nanoseconds |
sequence |
integer | the venue’s message sequence number: unique, the order of record |
side |
string | B bid, A ask |
price |
float | the level’s price |
size |
integer | shares displayed at that level after the update; 0 means the level is gone |
flags |
integer | bit 0 (1): the event is complete; bit 1 (2): the book is empty before this row |
orders |
integer | orders resting at the level after the update; null before 2024-12-09 (below) |
Rows of one event share a timestamp; sequence orders them, and the event’s last row has bit 0
of flags set. To rebuild the book at any instant, start from an empty book and apply rows in
sequence order: on bit 1 empty both sides, then set the level to size (remove it at 0). Bit 1
is set on each ticker’s first row of a session.
Columns: depth=1
Section titled “Columns: depth=1”| Column | Type | Meaning |
|---|---|---|
timestamp, sequence |
the row of the event that changed the top | |
bid_px, bid_sz, bid_ct |
float/int | best bid: price, shares, orders |
ask_px, ask_sz, ask_ct |
float/int | best offer: price, shares, orders |
A row is written at the end of each event whose top of book differs from the previous row’s, so
the top in force at any instant is the last row at or before it. A side with no order is null in
its three columns; *_ct is also null where the order count is unknown. A crossed or locked book is
served as the venue published it.
orders and *_ct come from the venue’s order-level feed, which exists from 2024-12-09; before
that they are null. Where the order-level book disagrees with the level’s displayed size, the count
is null rather than a guess.
The same bars as everything else: 10 rows are 1 bar, at either depth. A page rounds up to a
block of 1,000 rows (100 bars), with a minimum of 1,000; an empty page is free. X-Row-Count is
rows, X-Bars-Charged is bars. The free plan’s monthly bars pay for 1h bars only, so depth needs
bought bars.
Free sample
Section titled “Free sample”No key: /api/v1/mbp/stocks-venue-mbp/{ticker} returns the first 1,000 rows after 09:30 ET of the
newest session held (X-Preview-Limit: 1000), at either depth, in any format but mbt1. It does
not page, and start, end and cursor are a 400 there.
curl "https://getmarkethistory.com/api/v1/mbp/stocks-venue-mbp/SPY?depth=1&format=csv"