API reference
Everything for the DepthFeed v3 API — authentication, every endpoint, the response contract, the data model, and the venues behind it. Base URL https://api.depthfeed.com/v3.
Contents▾
Introduction
DepthFeed is historical order-book depth for prediction markets — the full bid/ask ladder on both sides, captured tick by tick, for Polymarket, Kalshi, and Limitless. Not the last trade price, not the top of book — every resting level with its size, at every change. It is the data you need to backtest a fill against the liquidity that was actually there.
It is delivered over a metered REST API — market discovery, metadata, and latest + historical order-book snapshots, keyset-paginated with per-plan rate limits. Pull exactly the depth your strategy needs and replay it in your own stack.
Coverage spans 3 venues, 7 assets (btc · eth · sol · xrp · doge · bnb · hype) and the recurring up/down crypto markets each venue runs (5m, 15m, 1h, 4h, 24h, depending on venue).
New to evaluating data sources? The buyer’s guide covers the five criteria that decide whether prediction-market data is actually backtestable, and how DepthFeed clears each.
Quickstart
1. Create a free account and mint an API key from the dashboard. Keys look like df_… and are shown once.
2. Make your first authenticated call:
curl https://api.depthfeed.com/v3/whoami \
-H "Authorization: Bearer df_your_key_here"3. The response is a JSON envelope — your plan, limits, and history window:
{
"data": {
"user_id": "acct_…", "plan": "pro",
"rps": 25, "rpm": 1000, "history_days": 30, "coins": "all"
},
"meta": { "request_id": "req_…", "timestamp": "2026-06-07T02:27:09.532Z" }
}4. Pull the latest BTC up/down markets, then the order-book depth for one of them — see Markets and Snapshots.
Authentication
Every endpoint except /v3/health and /v3/overview requires an API key. Pass it either way — both schemes are accepted:
# Authorization header (recommended)
curl https://api.depthfeed.com/v3/btc/markets -H "Authorization: Bearer df_your_key"
# or the X-API-Key header
curl https://api.depthfeed.com/v3/btc/markets -H "X-API-Key: df_your_key"/v3/streamalso requires a key, but authenticates once at connection time — a WebSocket can’t carry a per-request header, so it accepts X-API-Key, Authorization: Bearer, or a ?api_key= query param. See Live stream.Keys are minted per account from the dashboard and carry a plan that sets your rate limit, history window, and asset/venue access. Keys are stored SHA-256-hashed at rest — the raw value is shown exactly once at creation. Revoking a key in the dashboard takes effect immediately. Quotas are per user, not per key — extra keys do not multiply your limit.
| Failure | Status | code |
|---|---|---|
| No key supplied | 401 | AUTH_MISSING |
| Unknown / revoked / malformed key | 401 | AUTH_INVALID |
| Key store temporarily unreachable | 503 | AUTH_UNAVAILABLE |
Base URL & versioning
All endpoints live under a single versioned base path:
https://api.depthfeed.com/v3TLS is required (Let's Encrypt, HTTP/2). The current API version is v3, built to PolyBackTest parity (same envelope, cursor pagination, and error-code enum) over our superset data (3 venues, 7 assets). Legacy v1/v2 namespaces are not served.
Response format
Every successful response is the same envelope:
{
"data": … , // object (single) or array (list)
"pagination": { … }, // present only on list endpoints
"meta": { "request_id": "req_…", "timestamp": "2026-06-07T02:27:09.532Z" }
}Errors share the shape, with the HTTP status set per code:
{
"error": { "code": "INVALID_COIN", "message": "…", "details": { … } },
"meta": { "request_id": "req_…", "timestamp": "…" }
}Every response — success or error — carries meta.request_id, also returned as the X-Request-Id header. Quote it in support requests.
Errors
Branch on error.code — it is stable. The HTTP status is implied by the code.
| code | HTTP | Meaning |
|---|---|---|
AUTH_MISSING | 401 | No API key on the request. |
AUTH_INVALID | 401 | Key is unknown, revoked, or malformed. |
COIN_NOT_IN_PLAN | 402 | Your plan does not include that coin (e.g. eth on Free). |
ENDPOINT_NOT_IN_PLAN | 402 | Kalshi / Limitless require a paid plan. |
HISTORY_LIMIT_EXCEEDED | 403 | start_time / timestamp is older than your plan window. |
INVALID_COIN | 400 | Coin not one of the seven supported. |
INVALID_CURSOR | 400 | Cursor is malformed. |
INVALID_TIMESTAMP | 400 | Not ms-epoch or ISO-8601. |
INVALID_INTERVAL | 400 | interval not a duration like 30s, 1m, 5m, 1h, 1d (1s–1d). |
INVALID_SLUG | 400 | Empty/invalid {slug} path segment (e.g. a missing URL variable). |
INVALID_TICKER | 400 | Empty/invalid {ticker} path segment. |
BATCH_TOO_LARGE | 400 | More than 10 sub-requests in a batch. |
BATCH_INVALID_PATH | 400 | Sub-request is not a GET /v3/ path (per-sub status). |
MARKET_NOT_FOUND | 404 | No market with that id / slug / ticker. |
SNAPSHOT_NOT_FOUND | 404 | No snapshot for the query. |
ENDPOINT_NOT_FOUND | 404 | Path matches no v3 route. |
RATE_LIMIT_BURST | 429 | Per-second burst exceeded. |
RATE_LIMIT_SUSTAINED | 429 | Per-minute sustained limit exceeded. |
INTERNAL_ERROR | 500 | Unexpected server error — retry, then contact us with the request id. |
AUTH_UNAVAILABLE | 503 | Key verification is temporarily unavailable — retry shortly. |
403 HISTORY_LIMIT_EXCEEDED carries details.max_history_days and details.oldest_allowed. 429 also sets Retry-After and the X-RateLimit-* headers.
Rate limits
Limits are a per-user token bucket with two windows: a per-second burst and a per-minute sustained cap. Exceeding either returns 429 with the matching code and a Retry-After of 1 second.
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Your per-second burst limit (rps). |
X-RateLimit-Remaining | Burst tokens left this second. |
Retry-After | Seconds to wait (set on 429). |
X-Request-Id | Echo of meta.request_id. |
See Plans & access for the rps/rpm per tier.
Pagination & filters
List endpoints use opaque keyset cursors — O(1) at any depth. Pass ?cursor= from the previous page's pagination.next_cursor; stop when has_more is false.
"pagination": {
"next_cursor": "6274…", // opaque; feed back as ?cursor=
"has_more": true,
"limit": 50,
"count": 50,
"total_count": 1284 // only when ?include_count=true
}Common query parameters
| Param | Type | Notes |
|---|---|---|
limit | int | Markets max 100, snapshots/trades max 1000. Defaults: 50 / 100. |
cursor | string | Opaque keyset cursor from the prior page. |
include_count | bool | Adds total_count (costs a COUNT — opt-in). |
start_time | ts | ms-epoch or ISO-8601. Older than your window → 403. |
end_time | ts | ms-epoch or ISO-8601. |
interval | dur | Snapshots only. Downsample to one book per bucket (latest in each): 30s, 1m, 5m, 1h … up to 1d. Omit for full resolution. |
Timestamps accept either milliseconds-since-epoch (e.g. 1780774485780) or ISO-8601 (e.g. 2026-06-07T02:27:09Z). Every value reaching the database is validated and injection-safe. The plan history window is enforced on every list/snapshot endpoint: an explicit start_time beyond the window returns 403; an omitted one is clamped to the window floor.
Downsampling with interval
By default the snapshot endpoints return every recorded book change — full event-driven resolution. When you only need a periodic sample (say one book per minute for a chart or a coarse backtest), add ?interval= and the server collapses each time bucket to a single snapshot: the most recent book in that bucket. It is far less data over the wire than fetching every tick and thinning client-side.
# one snapshot per minute instead of every change
curl "https://api.depthfeed.com/v3/btc/markets/{id}/snapshots?interval=1m&include_orderbook=true" \
-H "Authorization: Bearer df_your_key"Accepts a duration: a bare number of seconds, or a value with a unit — 30s, 1m, 5m, 15m, 1h, 4h, 1d — from 1s to 1d. Buckets are aligned to the epoch, so 1m snaps to wall-clock minute boundaries. Cursor pagination and include_count apply to the downsampled rows (total_count becomes the number of buckets). Omit it, pass raw, or pass 0 for full resolution. An unrecognised value returns 400 INVALID_INTERVAL. Works on every snapshot endpoint — Polymarket, Kalshi, Limitless, and Binance.
Plans & access
Four flat plans. The plan field returned by /v3/whoami is the raw value in the right column.
| Plan | plan | Price | rps | rpm | History | Coins | Venues | Stream |
|---|---|---|---|---|---|---|---|---|
| Explorer | free | $0 | 1 | — | 7 days | BTC only | Polymarket + Binance | 1 sub · 1 conn |
| Quant ★ | pro | $29/mo | 25 | 1,000 | 30 days | All 7 | All — incl. Kalshi + Limitless | 5 subs · 1 conn |
| Desk Lite | scale | $79/mo | 50 | 3,000 | 90 days | All 7 | All — incl. Kalshi + Limitless | 25 subs · 2 conns |
| Desk | enterprise | from $200/mo | 100 | 6,000 | Full archive | All 7 | All + dedicated infra | 100 subs · 5 conns · wildcards |
Gating is enforced server-side:
- Coins — a non-BTC coin on Free →
402 COIN_NOT_IN_PLAN. - Venues — Kalshi and Limitless on Free →
402 ENDPOINT_NOT_IN_PLAN. - History —
start_timebeyond your window →403 HISTORY_LIMIT_EXCEEDED. - Streaming — limits apply at subscribe time on /v3/stream; Quant streams Polymarket book + price channels, Desk Lite and up stream every venue.
Health & identity
/v3/healthno authLiveness probe, no auth. Returns { status: "ok", service, time }.
/v3/whoamiYour plan, rate limits, history window, and coin access — the fastest way to confirm a key works.
Markets
Polymarket up/down markets per coin, joined to settlement reference (open/close price, winner, volume). {coin} is one of btc · eth · sol · xrp · doge · bnb · hype.
/v3/{coin}/marketsFilters: type (5m/15m/1h/4h/24h), resolved (true/false), plus the common time + pagination params.
/v3/{coin}/markets/{market_id}/v3/{coin}/markets/by-slug/{slug}A single market by id or slug. Example response (per-coin price keys are dynamic, like the reference):
{ "data": {
"market_id": "2456720", "event_id": "566750",
"slug": "btc-updown-5m-1780860300", "market_type": "5m",
"start_time": "…", "end_time": "2026-06-07T19:30:00Z",
"condition_id": "0xb7ce…",
"clob_token_up": "15598…", "clob_token_down": "51823…",
"btc_price_start": null, "btc_price_end": null,
"winner": null, "final_volume": null, "final_liquidity": null, "resolved_at": null
}, "meta": { … } }*_price_*, winner, resolved_at, final_volume, and final_liquidity — are null until the market settles and the reference backfills (~12–24 h after settlement).Order-book snapshots
The order-book depth time-series for a market, with the underlying coin price stamped on each snapshot.
/v3/{coin}/markets/{market_id}/snapshotsAdd ?include_orderbook=true to get the full ladder (omitted by default for a lighter payload). Time-windowed + cursor-paginated. Add ?interval=1m (or 5m, 1h, …) to downsample to one book per bucket instead of every change — see Pagination & filters. The list response is an array with a pagination block:
{ "data": [{
"id": "1780774485780", "time": "2026-06-06 19:34:45.780",
"market_id": "2456720", "btc_price": 60606.68,
"price_up": 0.505, "price_down": 0.495,
"orderbook_up": { "bids": [[0.50, 304.25], …], "asks": [[0.51, 30.0], …] },
"orderbook_down": { "bids": [ … ], "asks": [[0.50, 304.25], …] }
}], "pagination": { … }, "meta": { … } }/v3/{coin}/markets/{market_id}/snapshots/at/{timestamp}The single snapshot closest to a timestamp (within ±2 s). {timestamp} is ms-epoch or ISO-8601. Unlike the list endpoint, data is a single object (the same row shape) with no pagination block; no match within ±2 s returns 404 SNAPSHOT_NOT_FOUND.
{ "data": {
"id": "1780774485780", "time": "2026-06-06 19:34:45.780",
"market_id": "2456720", "btc_price": 60606.68,
"price_up": 0.505, "price_down": 0.495,
"orderbook_up": { "bids": [[0.50, 304.25], …], "asks": [[0.51, 30.0], …] },
"orderbook_down": { "bids": [ … ], "asks": [[0.50, 304.25], …] }
}, "meta": { … } }Levels are [price, size]. price_up is the best-bid/ask midpoint; price_down = 1 − price_up. The orderbook_down side is derived as the binary complement of the up book (down = 1 − up, sizes preserved). The coin price is the nearest preceding tick via an ASOF join — exact for 1h/4h/24h, a labeled Binance proxy for 5m/15m.
Binance — spot & futures
The underlying-asset book and trade tape from Binance. {venue} is spot or futures. The book is 20 levels per side.
/v3/{coin}/{venue}/latest/v3/{coin}/{venue}/snapshotsLatest book / paginated book history. Each snapshot: price (mid), bids, asks, timestamp.
/v3/{coin}/{venue}/trades/v3/{coin}/{venue}/trades/latest1-second OHLCV candles with an aggressive buy/sell split — exact, 1:1 with the reference:
{ "data": [{
"id": "1780747762000", "timestamp": "2026-06-06 12:09:22.000",
"price_open": 61097.1, "price_high": 61097.1,
"price_low": 61097.09, "price_close": 61097.1,
"total_volume": 0.01667,
"aggressive_buy_volume": 0.0156, "aggressive_sell_volume": 0.00107,
"num_trades": 3
}], "pagination": { … }, "meta": { … } }Kalshi
Kalshi's crypto contracts — full yes/no depth the reference doesn't carry. Paid plans only. 21 series for all 7 assets: 15-minute KX{ASSET}15M, threshold KX{ASSET}, and directional KX{ASSET}D. The threshold and directional series each run hourly, daily, and weekly markets concurrently — market_typecarries each market's actual window.
/v3/kalshi/marketspaid planFilters: ?coin= (base asset) and ?type= (window). Each market carries market_type (15m/1h/24h/1w), derived from the market's open→close span.
/v3/kalshi/{ticker}/orderbook/latestpaid planNewest full yes/no book for a ticker. yes/no are [price, size] arrays (prices in 0–1 dollars).
{ "data": {
"ticker": "KXHYPED-26JUN0717-T73.9999", "series": "KXHYPED",
"base_asset": "hype", "market_type": "24h",
"id": "1780…", "timestamp": "…",
"yes": [[0.62, 1400], …], "no": [[0.38, 900], …]
}, "meta": { … } }/v3/kalshi/{ticker}/snapshotspaid planThe historical yes/no depth series for one ticker — same row shape, ordered by receive time, time-windowed + cursor-paginated (include_count opt-in, max 1000). The forward-captured Kalshi book history (~1.5 s poll cadence) — full parity with Polymarket and Limitless /snapshots, so Kalshi depth is backtestable too.
Comparing all three venues at once? Start from the cross-venue screener instead of stitching per-venue calls.
Limitless
Limitless Exchange — a CLOB on Base running recurring up/down crypto markets at 5m and 15m. Depth is captured live over its order-book websocket (so even the fast 5m books are recorded). Paid plans only. {slug} looks like btc-up-or-down-15-min-1780798512077.
/v3/limitless/marketspaid planCurrently-open slots. Filters: ?coin= and ?type= (5m/15m).
/v3/limitless/{slug}/orderbook/latestpaid planNewest L2 depth for a slug (bids descending, asks ascending):
{ "data": {
"slug": "btc-up-or-down-15-min-1780798512077", "condition_id": "0x…",
"base_asset": "btc", "market_type": "15m",
"id": "1780798…", "timestamp": "2026-06-07 02:27:09.532", "midpoint": 0.5,
"bids": [[0.45, 200.0], …], "asks": [[0.46, 120.0], …]
}, "meta": { … } }/v3/limitless/{slug}/snapshotspaid planThe historical depth series for one slug — same row shape, ordered by receive time, time-windowed + cursor-paginated. This is the forward-captured order-book history.
Cross-venue screener
Start here for anything cross-venue. The screener answers the core question — how is the same “up or down” market priced on Polymarket, Kalshi, and Limitless right now? — in a single request, so you never stitch the three per-venue endpoints (with their three different identifiers) together yourself. Plan-aware: on Free you see BTC + Polymarket; the Kalshi and Limitless cells fill in on a paid plan.
/v3/screenerThe grid: one cell per asset with each venue's latest “up” probability, best bid/ask, and settlement reference. A placeholder/empty book reports null rather than a meaningless 0.50.
{ "data": {
"assets": ["btc","eth","sol","xrp","doge","bnb","hype"],
"windows": ["5m","15m","1h","4h","24h"],
"cells": [{ "asset": "btc",
"polymarket": { "up": 0.735, "down": 0.265, "best_bid": 0.73, "best_ask": 0.74, "price_to_beat": 62764.0 },
"kalshi": { "up": 0.71, "down": 0.29, … },
"limitless": { "up": 0.75, "down": 0.25, "slug": "btc-up-or-down-…", … } }],
"paid": true
}, "meta": { … } }/v3/screener/{asset}/{window}Drill into one (asset, window): the full L2 book on every venue side by side (books.polymarket / books.kalshi / books.limitless), plus the underlying spot series and the settlement price_to_beat — the single call a cross-venue backtest or arb screen actually needs.
/v3/overviewno authPer-asset, cross-venue time-series overview (price segments per window) — what powers the dashboard overview chart. Public, no key required; select with ?asset=.
Batch
/v3/batchRun up to 10 GET /v3/ requests in one round-trip. Each sub-request is dispatched independently and gets its own status.
curl -X POST https://api.depthfeed.com/v3/batch \
-H "Authorization: Bearer df_your_key" -H "Content-Type: application/json" \
-d '{ "requests": [
{ "id": "a", "method": "GET", "path": "/v3/btc/markets?limit=1" },
{ "id": "b", "method": "GET", "path": "/v3/limitless/markets?type=5m&limit=1" }
] }'Returns { data: [ { id, status, body }, … ] } with an outer 200. Over 10 sub-requests → 400 BATCH_TOO_LARGE; a non-GET or non-/v3/ path gets a per-sub 400 BATCH_INVALID_PATH.
Live stream (WebSocket)
/v3/streamA WebSocket that pushes live order books and prices as they change. Frame payloads are the same JSON objects the REST snapshot endpoints return, so code written against REST transfers directly. Authenticate at connect time with the X-API-Key header, Authorization: Bearer, or — for browsers, which cannot set WebSocket headers — ?api_key=df_….
# wscat -c "wss://api.depthfeed.com/v3/stream?api_key=df_your_key"
> {"op":"subscribe","channels":["book:polymarket:btc:2510645","price:btc"]}
< {"op":"subscribed","channels":[…],"active":2}
< {"channel":"price:btc","data":{"coin":"btc","price":63560.1,…},"ts":1781300671083}
< {"channel":"book:polymarket:btc:2510645","data":{…same shape as REST snapshot…},"ts":…}Channels
| Channel | Payload | Notes |
|---|---|---|
book:polymarket:<coin>:<market_id> | REST snapshot object (with orderbooks) | Tick-level via our CLOB websocket tap |
book:kalshi:<coin>:<ticker> | Same shape as /v3/kalshi/…/snapshots rows | Follows Kalshi's ~1.5s capture cadence |
book:limitless:<coin>:<slug> | Same shape as /v3/limitless/…/snapshots rows | Push-based (socket.io tap) |
book:binance:<coin>:<spot|futures> | Same shape as /v3/…/latest | 100ms depth feed |
price:<coin> | { coin, price, source, venue, id, time } | Binance underlying, ~4 ticks/s max |
Ops: subscribe · unsubscribe (each takes {"channels":[…]}, applied atomically) and ping → pong. A trailing * market segment (e.g. book:kalshi:btc:*) subscribes a whole venue/coin — Desk plan only. Op-level problems (bad channel, over your subscription cap) come back as {"op":"error","code":…} frames and never drop the connection.
Per-plan limits
| Plan | Connections | Subscriptions | Channels |
|---|---|---|---|
| Explorer | 1 | 1 | BTC — Polymarket books + price |
| Quant | 1 | 5 | Polymarket books + prices, all coins |
| Desk Lite | 2 | 25 | Every venue |
| Desk | 5 | 100 | Every venue + wildcards |
Close codes & reconnecting
| Code | Meaning |
|---|---|
4001 | Authentication failed (missing / unknown / revoked key) |
4003 | Plan connection limit reached |
4029 | Op flooding — slow down |
1013 | Key verification temporarily unavailable — retry shortly |
The server heartbeats with protocol pings every 25s. Deploys and failovers drop connections by design — treat disconnect → reconnect with exponential backoff (250ms doubling to ~5s) and re-send your subscriptions as the normal lifecycle, not an error path.
Freshness, measured
Median capture→client delivery measured from an external client through our edge: Polymarket ≈10ms (p95 ≈30ms), Binance and Limitless sub-100ms, underlying price ≈110ms. Kalshi follows its REST capture cadence, ≈1s median. Numbers come from deploy/stream_freshness.py runs against production — we publish what we measure, nothing rounder.
Venues & coverage
Precision comes from sourcing the same upstreams the markets use, so values match by construction.
| Venue | Capture | Windows | Notes |
|---|---|---|---|
| Polymarket | CLOB websocket — every book + price-change event | 5m · 15m · 1h · 4h · 24h | Full depth, event-driven. Settlement open/close from Polymarket's own metadata. |
| Kalshi | Public REST, full-depth poll (~1.5 s) | 15m · 1h · 24h · 1w | Yes/no book, up to 100 levels/side, 7 assets; hourly ladders polled fastest. |
| Limitless | socket.io websocket (orderbookUpdate) | 5m · 15m | CLOB on Base; live push captures the fast 5m books REST can't snapshot. |
| Binance | spot + futures @depth20@100ms + @aggTrade | — | Underlying book + 1s OHLCV, the precision anchor for the up/down markets. |
All 7 assets (btc · eth · sol · xrp · doge · bnb · hype) across every venue that lists them.
Data model & schema
Timestamps are epoch-millis. exch_ts_ms = exchange time, recv_ts_ms = our receive time (the difference is capture latency). These are the fields every order-book snapshot returns over the API.
polymarket_book — full order-book snapshots
asset_id, condition_id, slug, base_asset, market_type, exch_ts_ms, recv_ts_ms, hash, bid_prices[], bid_sizes[], ask_prices[], ask_sizes[]
polymarket_changes — deltas for replay between snapshots
asset_id, condition_id, exch_ts_ms, recv_ts_ms, side, price, size
polymarket_markets — one row per token
asset_id, market_id, event_id, condition_id, slug, outcome, base_asset, market_type, clob_token_up, clob_token_down, resolution_source, start_time, end_time, first_seen_ms
polymarket_reference — settlement
slug, base_asset, market_type, start_ms, end_ms, price_to_beat, final_price, winner, final_volume, final_liquidity, resolved_at, captured_ms
binance_book — 20-level book (spot & futures)
venue, symbol, exch_ts_ms, recv_ts_ms, bid_prices[], bid_sizes[], ask_prices[], ask_sizes[]
binance_trades_1s — 1s OHLCV
venue, symbol, second_ms, open, high, low, close, volume, buy_volume, sell_volume, trades, recv_ts_ms
prices — unified underlying-price series
asset, source (binance|chainlink), venue, exch_ts_ms, price
kalshi_book / kalshi_markets
kalshi_book: ticker, series, base_asset, market_type, recv_ts_ms, yes_prices[], yes_sizes[], no_prices[], no_sizes[]
kalshi_markets: ticker, event_ticker, series, base_asset, market_type, title, status, strike, open_time, close_time, first_seen_ms
limitless_book / limitless_markets
limitless_book: slug, condition_id, base_asset, market_type, recv_ts_ms, midpoint, bid_prices[], bid_sizes[], ask_prices[], ask_sizes[]
limitless_markets: slug, condition_id, base_asset, market_type, title, status, expiration_ms, first_seen_ms
History & coverage
Every plan window is served from the live store plus the cold archive, so the full window is always available — not a forward-filling promise. Licensed historical depth extends the Polymarket and Kalshi archive back to January 2026; our own capture runs continuously on top of it.
Need a specific market or range backfilled? Desk plans get priority backfill requests — reach out on the contact page.
Code examples
Walk a market's full depth history (Python)
import requests
BASE = "https://api.depthfeed.com/v3"
H = {"Authorization": "Bearer df_your_key"}
# 1. find a market
m = requests.get(f"{BASE}/btc/markets?type=15m&limit=1", headers=H).json()["data"][0]
mid = m["market_id"]
# 2. page through its order-book snapshots
cursor, rows = None, []
while True:
q = f"{BASE}/btc/markets/{mid}/snapshots?include_orderbook=true&limit=1000"
if cursor: q += f"&cursor={cursor}"
page = requests.get(q, headers=H).json()
rows += page["data"]
if not page["pagination"]["has_more"]: break
cursor = page["pagination"]["next_cursor"]
print(len(rows), "snapshots")Latest cross-venue depth for BTC up/down (JavaScript)
const h = { Authorization: "Bearer df_your_key" };
// One call → the full BTC 15m book on all three venues at once.
// (No stitching: the screener is the cross-venue entry point.)
const res = await fetch("https://api.depthfeed.com/v3/screener/btc/15m", { headers: h }).then(r => r.json());
const { books } = res.data; // books.polymarket / books.kalshi / books.limitlessAI agents & LLMs
DepthFeed is built to be driven by agents: plain JSON over HTTPS, one Bearer key, stable error codes, and no SDK required. A machine-readable product summary lives at /llms.txt.
As a function-calling / MCP-style tool
Wrap any endpoint as a tool — the API is self-describing enough that one generic definition covers most workflows:
{
"name": "depthfeed_get",
"description": "Query DepthFeed prediction-market order-book data. Paths: /v3/{coin}/markets, /v3/{coin}/markets/{id}/snapshots, /v3/kalshi/markets, /v3/kalshi/{ticker}/snapshots, /v3/limitless/{slug}/snapshots, /v3/{coin}/{spot|futures}/latest. Coins: btc eth sol xrp doge bnb hype.",
"parameters": {
"type": "object",
"properties": { "path": { "type": "string", "description": "GET path under /v3, with query params" } },
"required": ["path"]
}
}The tool body is a single authenticated GET:
curl "https://api.depthfeed.com{path}" -H "Authorization: Bearer df_your_key"Live data in agents
The WebSocket stream uses three JSON ops (subscribe / unsubscribe / ping) and authenticates with ?api_key=where headers can't be set — trivial to drive from any runtime. Frames carry the same JSON objects as REST, so an agent's parsing code is identical for history and live.
/v3/whoamiechoes the key's plan, rate limits, and history window — call it first and self-configure instead of guessing limits.Status & changelog
What's live, newest first:
- Live streaming.
/v3/streamWebSocket — order-book and price channels on every venue, ~10ms median Polymarket delivery, plan-gated subscriptions. - Limitless venue. Markets, latest orderbook, and historical depth snapshots — with 5m + 15m captured live over the order-book websocket.
- Kalshi expanded. 21 series for all 7 assets (15-minute, threshold, and directional — the latter two running hourly/daily/weekly concurrently);
market_typeexposed and filterable. - Full v3 API. Polymarket markets + snapshots, Binance spot/futures, batch, cursor pagination, per-plan history enforcement, metered usage.
- Public HTTPS.
https://api.depthfeed.comover TLS.
Order-book depth fills forward from capture start and cannot be back-filled — history matures toward your plan window over calendar time. Questions or a backfill request? Get in touch.