Short answer: A level 2 order book lists the price levels on each side of a market with the total quantity resting at each; level 1 is only the best bid and ask, and level 3 lists individual orders. Crypto exchanges publish level 2 data free, mostly with depth caps: per documentation read 6 November 2026, Binance's REST snapshot stops at 5,000 levels a side and Kraken's at 500. Free to fetch is not free to use, and US stock depth is a paid license.
Documentation was read on 6 November 2026 (Istanbul time); public endpoints were called between 21:37 and 22:19 UTC on 5 November 2026. Outputs show counts, IDs and sizes, not prices, because several venues restrict displaying their data.
This is market data mechanics, not a trading signal, and automated trading can lose money. Which platforms you may use depends on your jurisdiction and each platform's terms. For readers in Turkey: Article 99/A of Capital Markets Law No. 6362 treats activity by foreign crypto-asset platforms directed at Turkish residents as unauthorized.
What is a level 2 order book? L1, L2 and L3 compared
Level 2 is the aggregated view: one row per price, holding the total quantity of all orders resting there.
| Level | One row is | What it does not show |
|---|---|---|
| Level 1 (top of book) | Best bid and best ask with their sizes | Everything behind the best prices |
| Level 2 (market by price) | A price and its total quantity; Coinbase and OKX add an order count | Which orders form a level, queue position |
| Level 3 (market by order) | One resting order: ID, price and size | What the venue omits, such as hidden iceberg quantity in Kraken's level3 channel |
In US stocks "Level 2" is also a product name: Nasdaq's price list carries Nasdaq Level 2 next to TotalView. Bybit's API book excludes Retail Price Improvement (RPI) orders.
Free level 2 data: what crypto exchange APIs give
All five exchanges below publish level 2 data without an API key, but each caps depth, speed or both, and per-order feeds mostly need a login.
| Exchange | REST snapshot | WebSocket | Level 3 | Measured |
|---|---|---|---|---|
| Binance Spot | /api/v3/depth: default 100, maximum 5,000 a side; weight 5 to 250 | Top 5, 10 or 20 levels, or diffs; every 1,000 or 100 ms | No per-order stream documented | 5,000 a side in 320 KB; limit=5001 gave 5,000 |
| Coinbase Exchange | Level 1, 2 (whole book) or 3 (every order); abusive level 3 polling can get access limited or blocked | level2 needs authentication; level2_batch (50 ms batches) does not | REST level 3 worked without a key; level3 and full channels need authentication | Level 2: 39,653 levels, 1.04 MB; level 3: 106,270 orders, 6.5 MB |
| Kraken Spot | count 1 to 500, default 100 | Depth 10, 25, 100, 500 or 1,000; CRC32 checksum of the top 10 | level3 WebSocket with a token, or private REST Level3 with an API key | count 501, 1000 and 0 gave 100 a side, no error |
| OKX | books up to 400 a side (40 requests per 2 s); books-full up to 5,000 (10 per 2 s) | books: 400 levels, changes every 100 ms; tick-by-tick 50 and 400 levels only from the VIP4 fee tier up | None found; rows carry an order count | books-full: 5,000 a side, 286 KB, plus a seqId its response table omits; sz=5001 gave error 51000 |
| Bybit | orderbook: 1 to 1,000 (spot, linear, inverse); full_orderbook: up to 10,000 a side | Depth 1, 50, 200 or 1,000, every 10 to 200 ms, plus full-depth deltas | None on the order book pages | Spot: 1,000 a side, 45 KB; full_orderbook: spot 10,000 a side, 449 KB; linear 27,788 bids, 38,683 asks |
Kraken also answers an unknown pair with HTTP 200 and an error list, so check both the level count and the error field. A level count is not a price distance: in the run below, 100 Binance levels reached 0.02% to 0.03% from the mid and 5,000 levels about 1.0% to 1.6%.
Depth snapshot vs diff stream: keeping level 2 current
A snapshot is the book at one update ID; a diff stream sends only changed levels with their new totals, and a zero quantity removes the level.
- Snapshot polling: stateless, but each call costs weight, 250 for 5,000 Binance levels (see the Binance API rate limit guide), and you see nothing between calls.
- Partial-depth stream: Binance's
@depth20or OKX'sbooks5push a fresh top-N picture: nothing to reconcile, nothing beyond N. - Snapshot plus diffs: the way to hold a deep live book: buffer events, fetch a snapshot, drop events with
uat or below itslastUpdateId, apply the rest in order.
Compare quantities as numbers: in a 5-second capture of Binance's btcusdt@depth@100ms stream at 21:41 UTC on 5 November 2026 (50 events, 1,115 level changes, no ID gaps), removals read "0.00000000", which a test for "0" misses. Beyond the snapshot's 5,000 levels, Binance warns, you learn quantities only when they change. Full tested code is in how to keep a local order book from WebSocket streams; stream limits are in the Binance WebSocket guide.
Order book sequence numbers and gap recovery
Each venue gives an ID or checksum that proves no update was missed; on a gap, discard the book and start from a new snapshot.
| Exchange | Field | Rule |
|---|---|---|
| Binance | U and u; lastUpdateId | U above your book's ID + 1 means missed events: restart |
| Coinbase | sequence | Replay queued messages, discarding those at or below the snapshot's sequence |
| Kraken | CRC32 checksum of the top 10 levels | A mismatch means the local book is wrong |
| OKX | seqId and prevSeqId | prevSeqId is the previous message's ID; the old checksum is fixed at 0 |
| Bybit | u and seq | A new snapshot, or u = 1 after a service restart, replaces the book |
Kraken's level3 page adds a trap: price levels that fall outside your subscribed depth get no delete event, so truncate the book after every update.
Fetch a level 2 snapshot in Python: tested on public endpoints
The script reads Binance and Coinbase snapshots without a key and validates them.
from decimal import Decimal, InvalidOperation
import requests
def get_json(url, **params):
r = requests.get(url, params=params, headers={"User-Agent": "Mozilla/5.0"}, timeout=10)
if not (r.status_code == 200 and "json" in r.headers.get("Content-Type", "")):
raise RuntimeError(f"HTTP {r.status_code}: {r.text[:60]}") # status before fields
return r.json(), len(r.content)
def prices(rows):
out = []
for row in rows:
try:
px, qty = Decimal(row[0]), Decimal(row[1]) # no silent inf or 0.0
except (InvalidOperation, IndexError, TypeError):
raise ValueError(f"unreadable level {row}") from None
if not (px.is_finite() and qty.is_finite() and px > 0 and qty > 0):
raise ValueError(f"bad level {row}")
out.append(px)
return out
def check(bids, asks, per_order=False, auction=False):
worse = (lambda a, b: a < b) if per_order else (lambda a, b: a <= b) # L3 repeats prices
if not bids or not asks or any(worse(a, b) for a, b in zip(bids, bids[1:])) \
or any(worse(b, a) for a, b in zip(asks, asks[1:])):
raise ValueError("empty or unsorted side")
if bids[0] >= asks[0] and not auction: # auctions may cross
raise ValueError("crossed or locked book")
return (bids[0] + asks[0]) / 2
def binance(limit):
b, size = get_json("https://data-api.binance.vision/api/v3/depth", symbol="BTCUSDT", limit=limit)
bids, asks = prices(b.get("bids", [])), prices(b.get("asks", []))
mid = check(bids, asks)
print(f"Binance limit={limit}: {len(bids)}+{len(asks)} levels, id {b.get('lastUpdateId')}, "
f"{size:,} bytes, reach -{(mid - bids[-1]) / mid:.2%} +{(asks[-1] - mid) / mid:.2%}")
def coinbase(level):
b, size = get_json("https://api.exchange.coinbase.com/products/BTC-USD/book", level=level)
bids, asks = b.get("bids", []), b.get("asks", [])
check(prices(bids), prices(asks), level == 3, bool(b.get("auction_mode")))
rows = bids + asks # row[2]: order count (level 2), order ID (level 3)
orders = sum(int(r[2]) for r in rows) if level == 2 else len(rows)
print(f"Coinbase level={level}: {len(rows):,} rows, {orders:,} orders, "
f"sequence {b.get('sequence')}, {size:,} bytes")
for limit in (100, 5000):
binance(limit)
for level in (2, 3):
coinbase(level)
Output at 21:54 UTC on 5 November 2026 (Python 3.11, requests 2.31):
Binance limit=100: 100+100 levels, id 102382301659, 6,447 bytes, reach -0.02% +0.03%
Binance limit=5000: 5000+5000 levels, id 102382303007, 320,052 bytes, reach -0.96% +1.63%
Coinbase level=2: 39,653 rows, 106,248 orders, sequence 138879234515, 1,037,802 bytes
Coinbase level=3: 106,270 rows, 106,270 orders, sequence 138879236664, 6,530,642 bytes
- Coinbase's level 2 order counts summed to 106,248; level 3, 2,149 sequence numbers later, listed 106,270 orders in a body 6.3 times larger: level 2's count column is level 3 compressed.
Decimalkeeps"1e-400"positive wherefloatgives0.0; NaN, infinity, zero, negative and unreadable values raise errors (in diff events, zero means delete).- A crossed book can be legitimate: OKX's docs say the best ask may sit below the best bid during pre-open, and Coinbase returns
auction_mode. - Also tested: HTTP 400 and HTML 404 responses, short rows,
Noneand text prices, locked and unsorted books.
For execution cost, walk the levels as in slippage from the order book or use the slippage calculator; the order book imbalance formula covers a depth ratio without any claim about prices.
Is level 2 data free to use? Exchange data terms
Free to download is not free to use in a product.
| Exchange | What the terms say |
|---|---|
| OKX | API Agreement section 9.4 (updated 28 July 2026): own personal, non-commercial trading only; publishing, display or redistribution needs written consent, public endpoints included; no commercial model training |
| Kraken | Legacy API introduction: prior permission for any non-personal commercial use of public endpoint data |
| Binance | Historical files on data.binance.vision: non-commercial only (dataset terms updated 26 August 2026). Live API data: not verified (its Terms of Use page did not render) |
| Coinbase, Bybit | Not verified (Coinbase's terms page returned HTTP 403 on 6 November 2026) |
Take legal advice before showing a venue's data to others or reselling it. Archived depth is rarer than trade files and has its own terms; see crypto tick data sources and licenses. For integration work in general, see Fincode's market data pipelines page; naming Binance, Coinbase, Kraken, OKX or Bybit here does not mean Fincode integrates them or has built on them.
Stock level 2 data cost: Nasdaq TotalView and NYSE OpenBook
US stock depth-of-book data is licensed by each exchange per user per month, with separate fees for firms that take a datafeed, redistribute it or use it in machines.
| Product and fee | 2026 |
|---|---|
| Nasdaq TotalView, non-professional | $15.00 |
| Nasdaq TotalView, professional or corporate | $84.00 |
| NYSE OpenBook, non-professional | $15.00 |
| NYSE OpenBook, professional, per device | $60.00 |
| NYSE OpenBook access fee, datafeed delivery | $5,000.00 |
| NYSE OpenBook redistribution fee | $3,000.00 |
| NYSE OpenBook non-display, per category | $6,000.00 |
Both lists set 2027 professional rates: $86.00 for Nasdaq TotalView and $64.00 for NYSE OpenBook ($70.00 in 2028); non-professional fees stay at $15.00.
Hypothetical example. An internal tool shows NYSE OpenBook to 3 professional users in 2026: 3 x $60.00 = $180.00 a month. A direct datafeed adds the $5,000.00 access fee, and machine use at least one $6,000.00 non-display category: $11,180.00 a month before vendor charges.
Each exchange's agreements define who is non-professional, and brokers and vendors resell these feeds at prices not checked here. See the stock market data API guide for licensing and the Borsa Istanbul market data guide for that exchange's data fees.
Frequently asked questions
Is level 2 data free?
For crypto, most exchanges publish level 2 books without a key, capped in depth and speed, though some terms limit commercial use. US stock depth is paid: Nasdaq's price list sets TotalView at $15.00 a month for a non-professional subscriber in 2026.
How many levels does the Binance order book API return?
Binance's REST documentation, read 6 November 2026, gives 100 by default and at most 5,000 a side. A larger limit returns 5,000, and any request above 1,000 levels costs 250 weight.
Does Binance offer level 3 order book data?
Its Spot WebSocket streams page, read 6 November 2026, documents partial and diff depth streams but no per-order stream. Coinbase and Kraken document level 3 feeds and require authentication for them on WebSocket.
Why does my local order book drift from the exchange?
Usually a missed update, a zero quantity compared as text, or levels beyond the snapshot's depth; check update IDs on every event and rebuild after any gap.
Sources
- Binance Spot API documentation: REST API, order book endpoint (limit, weights) (opens in a new tab)
- Binance Spot API documentation: WebSocket Streams (partial and diff depth, local order book procedure) (opens in a new tab)
- Coinbase Exchange API: Get product book (levels 1, 2 and 3) (opens in a new tab)
- Coinbase Exchange WebSocket feed: Channels (level2, level3 and full require authentication; level2_batch does not) (opens in a new tab)
- Kraken API: Get Order Book (count 1 to 500) (opens in a new tab)
- Kraken WebSocket v2: Book (Level 2) (opens in a new tab)
- Kraken WebSocket v2: Level 3 (individual orders, token required) (opens in a new tab)
- Kraken API Center (legacy documentation): introduction, permission for commercial use of public endpoints (opens in a new tab)
- OKX API v5 documentation: order book REST endpoints and channels (books, books-full, tick-by-tick tiers, seqId) (opens in a new tab)
- OKX API Agreement, sections 9.3 and 9.4, last updated 28 July 2026 (opens in a new tab)
- Bybit V5 API: Get Orderbook (opens in a new tab)
- Bybit V5 API: Get Full Depth Orderbook (up to 10,000 levels a side, paired with the full orderbook WebSocket stream) (opens in a new tab)
- Bybit V5 API: Orderbook WebSocket stream (opens in a new tab)
- Nasdaq: US Equities Price List, monthly fees effective 2025, 2026 and 2027 (Nasdaq TotalView) (opens in a new tab)
- NYSE Proprietary Market Data Pricing Guide, 9 October 2026 (NYSE OpenBook) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.