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 — recorded full bid/ask ladders on both sides for Polymarket, Kalshi, and Limitless. Not just the last trade price or top of book: each stored observation includes resting levels and sizes. 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 separate general-admission and historical-workload controls. 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).
The Desk plan also bundles realtime sports— live Polymarket & Kalshi books, sportsbook odds, scores and injuries across the major leagues. Jump to the Sports endpoints.
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", "sports": false
},
"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. |
MARKET_TICKER_REQUIRED | 400 | A Kalshi series was passed where an exact discovered market ticker is required. |
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. |
HISTORY_CONCURRENCY_LIMIT | 429 | Another snapshot or batch history request is still running for this account. |
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.
The advertised rps/rpm values are general REST admission limits, not archive-delivery rates. Historical snapshots, batches containing history reads, and other heavyweight routes use separate account-level concurrency and delivery controls. These controls apply independently of the general token bucket and do not change the plan's history window.
Explorer, Quant, and Research currently accept one historical request in flight per account. Desk accepts 2 parallel historical snapshot requests per account through its dedicated Desk query pool. An overlap returns 429 HISTORY_CONCURRENCY_LIMIT with Retry-After: 2; retry only after an active request completes. General rps/rpm values must not be used to infer historical parallelism.
| 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.
Historical query pattern
Keep no more than your confirmed history concurrency active. Use bounded start_time andend_time, cursor pagination, and limit=1000; omit include_count and request the full ladder only when needed. Add interval when a downsampled series is sufficient. DepthFeed is a metered query-access product: bulk files, offline archive delivery, database replication, and systematic archive mirroring are not included.
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 the raw stored series
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 | General rps | General rpm | Historical parallelism | Unified history | Wallet Intelligence | Crypto | Sports REST | Live sports books |
|---|---|---|---|---|---|---|---|---|---|---|
| Explorer | free | $0 | 1 | — | 1 | 7 days | 1 saved · 3 audits | BTC sample | All sports venues | REST only |
| Quant ★ | pro | $49/mo | 25 | 1,000 | 1 | 30 days | 5 saved · 10 audits | All assets + venues | All sports venues | 1 |
| Research | scale | $149/mo | 50 | 3,000 | 1 | 90 days | 10 saved · 25 audits | All assets + venues | All sports venues | 2 |
| Desk | enterprise | $399/mo | 100 | 6,000 | 2 parallel | Full archive | 20 saved · 50 audits | All; dedicated Desk historical query pool | All sports venues | 3 |
There are no Polymarket or Kalshi add-ons. Both sports venues use the same key, schema, rate limit, and history window; upgrading buys more history, throughput, and live-book concurrency.
The General rps/rpm columns describe request admission, not simultaneous archive scans. Historical query parallelism and delivery controls are separate. Desk historical reads use a dedicated Desk-only query pool isolated from regular-plan query traffic, without removing account-level controls. The pool is shared across Desk accounts and is not customer-owned or account-exclusive infrastructure.
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. - Sports — the /v3/sports/* REST surface is included on every plan; the same plan history window applies to both venues.
- History —
start_timebeyond your window →403 HISTORY_LIMIT_EXCEEDED. - Streaming — limits apply at subscribe time on /v3/stream; Quant and up stream every venue, Explorer streams Polymarket + Binance (BTC) — Kalshi and Limitless channels require a paid plan.
Health & identity
/v3/healthno authLiveness probe, no auth. Returns { status: "ok", service, time }.
/v3/whoamiYour plan, rate limits, unified history window, coin access, and sports 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 the raw stored series — 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), ?type= (window), and exact ?series= (for example KXBTC15M). For historical downloads, pass start_time and end_time here first and use the returned venue-native tickers. Do not generate Kalshi ticker ids from UTC timestamps; the venue's ticker clock convention changed historically.
/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 exact discovered market ticker — same row shape, ordered by receive time, time-windowed + cursor-paginated (include_count opt-in, max 1000). The forward-captured Kalshi book history from a paced REST polling loop. Effective cadence varies with the active market set and API limits; it uses the same historical endpoint pattern as Polymarket and Limitless /snapshots, so Kalshi depth is backtestable too. Passing a series such as KXBTC15M, or an invented historical ticker, returns an explicit discovery error instead of a misleading empty page.
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.
Binance prediction markets
Binance Wallet's Predict.fun-backed crypto prediction markets, normalized into a dedicated DepthFeed namespace. The initial catalogue covers BTC, ETH, and BNB up/down markets. Paid plans only.
/v3/binance-prediction/marketspaid planFilter with ?coin=btc, ?type=5m, or ?status=resolved. Results include the market/topic IDs, condition and token metadata, resolution, winning outcome, volume, liquidity, participant count, chain, and exchange contract.
/v3/binance-prediction/{market_id}/orderbook/latestpaid plan/v3/binance-prediction/{market_id}/snapshotspaid planLatest and historical full L2 depth. Snapshot history is forward-captured from 17 July 2026; an earlier resting book cannot be reconstructed from settlement data.
/v3/binance-prediction/{market_id}/timeseries?metric=chancepaid plan/v3/binance-prediction/{market_id}/timeseries?metric=pricepaid plan/v3/binance-prediction/{market_id}/timeseries?metric=last_tradepaid plan/v3/binance-prediction/{market_id}/tradespaid planProbability, displayed price, and last-trade samples are kept separately and begin on 17 July 2026. The trades route is reserved while historical fills are reconstructed from BNB Smart Chain logs and currently returns an empty historical dataset.
/v3/predictfun/* paths remain compatible aliases. Customers use a DepthFeed key; no Binance key or wallet pairing is required.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.
Sports
Realtime sports prediction-market data — live order-book depth on Polymarket and Kalshi, alongside sportsbook odds, live scores, and an injury feed across the major leagues (NBA, NFL, MLB, NHL, soccer, tennis, UFC, F1 and more). Both venues are included together on every tier; plans change the shared history window, throughput, and live-book concurrency. Same{ data, meta, pagination } envelope, auth, and cursor pagination as the rest of the API.
Discovering a market. Walk the funnel: /v3/sports/leagues → /v3/sports/markets?league=… → take a market's tokens[](each is one outcome's asset_id) → /v3/sports/books/{asset_id}/latest for the live book. Or start from /v3/sports/overview, which answers “what's trading now, on every venue” in one call.
/v3/sports/overviewStart here. The live cross-sport board — every tracked league with its in-progress and upcoming games, current prices, and best bid/ask per venue, in a single request.
/v3/sports/leaguesThe leagues we track, each with its game and market counts — the top of the discovery funnel.
/v3/sports/marketsSports markets across Polymarket and Kalshi. Filter with ?league= (e.g. nba, mlb, soccer); cursor-paginated like every list endpoint (?limit=, ?cursor=). Each market carries its condition_id, market_slug, outcomes, and tokens — the per-outcome asset_ids you hand to the book endpoint.
{ "data": [{
"condition_id": "0xfb53…", "market_slug": "mls-nyc-laf-…-total-2pt5",
"league": "soccer", "kind": "totals", "title": "New York City FC vs. Los Angeles FC",
"outcomes": ["Over", "Under"],
"tokens": ["45485059…", "38846626…"], // one asset_id per outcome
"game_start": "2026-11-05T00:30:00Z", "resolved": false
}], "pagination": { "next_cursor": "…", "has_more": true, "limit": 50 }, "meta": { … } }/v3/sports/books/{asset_id}/latestNewest recorded full order book for one outcome — the asset_idis a token from the market'stokens[]. Same [price, size] bid/ask ladder shape as the crypto book endpoints. For latency-sensitive live use, Quant and higher tiers can subscribe to the sports WebSocket channels below.
/v3/sports/books/{asset_id}/historyHistorical full-ladder snapshots for the outcome. Page with ?limit= and ?cursor=; bound time with ?start_time= / ?end_time= (the shorter ?from= / ?to= aliases are also accepted). Add ?interval=1m to return the latest snapshot in each epoch-aligned bucket; supported units are s, m, h, and d, from one second through one day. Omit it, or useraw / tick, for every captured change. Sports depth is forward-captured: the Polymarket archive starts 14 April 2026 and the Kalshi archive starts 12 June 2026.
Games and resolved market context
/v3/sports/{league}/gamesLive games and scores for a league (e.g. nba, nfl, soccer/eng.1), each with its linked Polymarket & Kalshi markets.
/v3/sports/games/{game_slug}The joined game document: schedule and final score, linked prediction markets and settlements, sportsbook lines, and injury context. Use the companion routes below when you need an individual high-volume layer.
/v3/sports/games/{game_slug}/markets/v3/sports/games/{game_slug}/lines/v3/sports/games/{game_slug}/box/v3/sports/games/{game_slug}/plays/v3/sports/games/{game_slug}/winprobGame markets, line movement, box scores, play-by-play, and per-play win probability.
/v3/sports/markets/{condition_id}One normalized market with venue identifiers, outcomes, token IDs, game join, and settlement state.
Players, props, and injuries
/v3/sports/{league}/playersSearch the league athlete directory and retrieve stable athlete IDs used by player-prop joins.
/v3/sports/players/{athlete_id}/v3/sports/players/{athlete_id}/injuries/v3/sports/players/{athlete_id}/box/v3/sports/players/{athlete_id}/marketsPlayer profile, injury change-log, box-score game log, and entity-resolved prediction-market props.
/v3/sports/{league}/injuriesThe live injury feed per league — the pre-game status changes that move the market.
Sportsbook odds
/v3/sports/odds/linesLive moneyline, spread, total, and prop lines across books, normalized for comparison with the market price.
/v3/sports/odds/booksThe active sportsbook catalog and source freshness.
/v3/sports/{league}/odds-historyHistorical sportsbook lines, including NFL history to 1999 and European soccer to the 2000/01 season. Bound NFL requests with season, team, from, or to. Soccer requests require a football-data season code (for example 2324) and/or team.
/v3/sports/odds/streamServer-Sent Events for changing sportsbook lines. Send Accept: text/event-stream; events pass through as they arrive and the connection remains open. Sports order books use the main DepthFeed WebSocket below.
Injury webhooks
/v3/sports/webhookspaid planRegister an HTTPS receiver with league and injury-status filters. The signing secret is shown once. Deliveries include X-DepthFeed-Event and X-DepthFeed-Signature; verify the HMAC-SHA256 signature over the exact raw request body before parsing JSON.
curl -X POST "https://api.depthfeed.com/v3/sports/webhooks" \
-H "Authorization: Bearer df_your_key" -H "Content-Type: application/json" \
-d '{"url":"https://example.com/depthfeed","leagues":["nba","nfl"],"statuses":["out","questionable"]}'/v3/sports/webhookspaid plan/v3/sports/webhooks/{sub_id}/testpaid plan/v3/sports/webhooks/{sub_id}paid planList subscriptions and delivery health, send a signed test event, or revoke a subscription.
# discover a market, then pull its live book
curl "https://api.depthfeed.com/v3/sports/markets?league=mlb&limit=1" -H "Authorization: Bearer df_your_key"
# take tokens[0] from the response, then:
curl "https://api.depthfeed.com/v3/sports/books/<asset_id>/latest" -H "Authorization: Bearer df_your_key"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 | Updates from the paced Kalshi polling loop |
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 |
book:sports:polymarket:<token_id> | Full sports ladder | Quant+: first-party, event-driven CLOB stream |
book:sports:kalshi:<ticker> | Full sports ladder | Quant+: best-effort adaptive public REST; change-only frames |
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.
Sports channels use concrete identifiers and do not support wildcards. Quant, Research, and Desk allow one, two, and three concurrent sports books respectively. Every sports frame includes the complete ladder, venue, asset_id, exchange/receive timestamps, full_ladder: true, and adeliveryfield that distinguishes event-driven Polymarket from Kalshi's adaptive REST snapshots. Kalshi's credential-free public endpoint is globally paced and backs off automatically when the upstream quota is busy. It starts with a 125ms shared polling floor; multiple active books and upstream throttling increase the actual interval.
> {"op":"subscribe","channels":[
"book:sports:polymarket:<token_id>",
"book:sports:kalshi:<market_ticker>"
]}
< {"op":"subscribed","channels":[…],"active":2}Per-plan limits
| Plan | Connections | Subscriptions | Channels |
|---|---|---|---|
| Explorer | 1 | 1 | BTC — Polymarket + Binance books + price |
| Quant | 1 | 5 | Every venue, all coins; 1 sports book |
| Research | 2 | 25 | Every venue; 2 sports books |
| Desk | 5 | 100 | Every venue + wildcards; 3 concurrent sports books |
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.
Wallet Intelligence
Wallet Intelligence is a read-only research workspace for public Polymarket wallets. Save a watchlist, discover traders from Polymarket's public leaderboard, and review public positions, recent activity, realized samples, and portfolio-level metrics in one place. It never connects a wallet, signs a transaction, or places a real order.
Next-book execution audit
For each eligible public trade, DepthFeed finds the first Polymarket book it recorded after the activity timestamp, walks the displayed ladder for the same number of shares, and reports the replay price, fillable fraction, observed delay, and signed price difference versus the public trade. The lookup window is 90 seconds. A missing match is shown as missing; it is never estimated.
Grades are mechanical: Depth remainedmeans at least 95% of the public size was displayed within 1¢ of the trader's price; Price moved means at least 95% remained but at a difference above 1¢; Size unavailable means less than 95% of the public size was displayed.
Forward paper copy
Start a paper mirror from any inspected wallet. Only public trades observed after the mirror is created are eligible: DepthFeed deduplicates each fill, applies the configured copy ratio and per-trade cap, then fills it at the next available live quote in the normal Paper Trading ledger. Cash, positions, P&L, the equity curve, circuit breaker, and settlement history appear under Paper Trading.
An optional HTTPS callback receives each successful copied fill. Its signing secret is shown once. Verify HMAC-SHA256(timestamp.body) against x-depthfeed-signature; the timestamp is sent in x-depthfeed-timestamp. Local, private-network, credential-bearing, non-HTTPS, and redirect destinations are rejected.
| Plan | Saved wallets | Audited trades per refresh | Public activity rows |
|---|---|---|---|
| Explorer | 1 | 3 | 30 |
| Quant | 5 | 10 | 100 |
| Research | 10 | 25 | 250 |
| Desk | 20 | 50 | 500 |
Interpretation limits
- A public address may be only one wallet in a trader's portfolio and does not prove identity or ownership.
- Public activity timestamps are not private order timestamps. The audit measures what DepthFeed observed after publication, not the trader's original latency.
- Only trades in DepthFeed's recorded Polymarket coverage can be matched. Unsupported or uncaptured markets are shown without an audit.
- The replay consumes displayed size mathematically; it cannot model hidden liquidity, queue priority, cancellation races, fees, or the market impact of a real follower order.
- Leaderboard rank, P&L, positions, and activity come from Polymarket's public data services and may be delayed, revised, incomplete, or temporarily unavailable.
- Wallet Intelligence and its paper mirror are research tooling—not live copy trading, investment advice, a recommendation, or a guarantee of execution.
Wallet research guides
Start with the Polymarket wallet tracker guide, then compare wallet analytics, leaderboard research, and copy-trading execution analysis.
Backtest Lab
The Backtest Lab (in your dashboard) backtests entry/exit strategies on resolved native Polymarket, directional Kalshi, and Limitless crypto markets — settlement-anchored, so every simulated trade has a known outcome. It runs on the same order-book history the API serves, within your plan's history window.
Venues and sampling
Polymarket supports 5m, 15m, 1h, 4h and 24h windows. Limitless supports captured 5m and 15m up/down contracts. Kalshi supports the captured directional 15m, 1h and 24h series; range buckets are excluded because YES does not mean UP. Kalshi defaults to one representative directional contract per event so a ladder of correlated strikes is not counted as independent evidence. Advanced users can inspect all strikes with an explicit correlation warning.
Strategies
Five built-in presets (late-favorite, spot-leads, dip-reversion, level-cross, cheap-lotto) plus a custom JavaScript editor: your script plans entries over each market's price path and runs sandboxed in a web worker — no network, hard time budget, stored locally in your browser and exportable as JSON.
Fill models
| Model | Entry price |
|---|---|
| Mid | The snapshot mid — fastest, most optimistic. |
| Mid + slippage | Mid shifted by a fixed slippage you set. |
| Book-depth VWAP | Walks the real ask ladder level by level. Missing or one-sided depth is unfillable; it never falls back to a modeled midpoint. |
Fees are included in sizing and net P&L. Polymarket and Limitless use an editable flat per-share assumption; Kalshi uses its non-linear expected-earnings formula with an editable rate and cent rounding per order.
Portable exports
Export the complete trade log as CSV, the strategy and execution assumptions as portable JSON, or a reproducible run bundle containing the exact tested sample, statistics, risk report, equity curve and trades. Exports never embed raw historical paths or order-book archives.
Position sizing
How much each trade stakes — a flat amount, or a fraction of a compounding bankroll:
| Scheme | Stake per trade |
|---|---|
| Fixed | A flat dollar amount — simple, but the only scheme that can trade a bankroll to zero. |
| Fractional | A constant fraction of your live bankroll (fixed-fractional). It compounds and can't reach zero from sizing alone. |
| Kelly | Growth-optimal f* = (q − p)/(1 − p) for a $1 binary at price p, scaled by a fractional-Kelly multiplier (half-Kelly = the standard hedge) and capped per trade. The win probability q comes from a fixed edge, a fixed win probability, or the strategy's own trailing hit rate. No edge (f* ≤ 0) ⇒ the entry is skipped. |
Risk of ruin
Every run reports a risk panel derived from its own trades: the optimal fraction your edge can support (Ralph Vince optimal-f), a recommended max (half of it), a Monte-Carlo risk of ruin (the chance the bankroll ever falls to ≤30% of its start), and an over-bettingwarning when you're staking past the growth-optimal point — where more risk buys less long-run growth. Deploying to paper auto-caps the live per-trade size at this safe fraction.
Results: trade log, win rate, ROI, Sharpe, max drawdown, the equity curve, and the risk-of-ruin panel. Paid plans can save up to 50 frozen runs (they re-render identically later, no data re-reads), and the built-in AI assistant helps write and debug strategies and interpret sizing and risk within a plan-metered allowance.
Paper trading
Paper Trading runs strategies forward on livemarkets with virtual cash. Fills, marks and settlement are all priced from DepthFeed's live order books — buys at the ask, sells at the bid, positions settle to $0/$1 automatically when the market resolves. Each strategy gets its own equity curve, positions view, and full trade log.
Three ways to trade
| Mode | How it works |
|---|---|
| Webhook | Your own system (bot, cron, notebook) POSTs buy/sell signals to a per-strategy token URL. Your logic stays yours — we do execution, accounting and charts. |
| Lab rule | Deploy a Polymarket or Kalshi Backtest Lab preset (time-window entry, level cross, dip reversion) with venue-native sides, take-profit/stop-loss, a max-open cap, and position sizing (fixed / fractional / Kelly); it's evaluated server-side against live quotes (~90s cadence). |
| Wallet copy | Mirror new public fills from an inspected Polymarket wallet with a copy ratio and per-trade cap. Results use the same paper ledger and may optionally emit signed HTTPS fill webhooks. |
Signal webhook
/paper/hook/{token}no authThe token (shown once at create/rotate) is the auth. Fills always price from the live book at signal time — a payload can never set its own price. Markets are identified by venue + market: a Kalshi ticker, or a Polymarket CLOB token id. You can trade any market on the venue, not just the ones DepthFeed records — if we don't have it locally, the fill is priced from a live read of the venue's own order book.
curl -X POST 'https://api.depthfeed.com/paper/hook/pt_your_token' \
-H 'content-type: application/json' \
-d '{
"action": "buy", # buy | sell | close
"venue": "polymarket", # polymarket | kalshi
"market": "1234567890...", # CLOB token id / Kalshi ticker
"side": "yes", # kalshi: yes|no (polymarket tokens are one-sided)
"usd": 100, # size by dollars… or "shares": 150
"client_id": "sig-0042" # optional idempotency key (safe retries)
}'{ "data": { "filled": true, "action": "buy", "price": 0.62,
"shares": 161.29, "cost_cents": 10000, "cash_cents": 990000,
"position_id": "…" } }| Error | Meaning |
|---|---|
NO_FRESH_QUOTE | No live book for that market — a bad id, or the market has closed / gone one-sided at 0/1 (settlement closes positions automatically). |
INSUFFICIENT_CASH | The order exceeds the strategy's paper cash. |
NO_POSITION | sell/close with no open lot on that market/side. |
RATE_LIMITED | Over 120 signals/min for the strategy. |
PAUSED | The strategy is paused in the dashboard. |
Circuit breaker
Each strategy has a trailing max-drawdown stop (default 60%, editable; set to 0 to disable). If live equity ever falls that far below its high-water mark, the strategy is automatically flattened at current marks and halted — a hard stop against a strategy trading itself toward zero. Resume it any time; resuming resets the high-water mark to your current equity.
Limits
Concurrent strategies per plan: Explorer 1 · Quant 5 · Research 15 · Desk 40. Up to 100 open positions per strategy; starting balance $100–$1,000,000 (default $10,000). Marks refresh on a ~90-second cadence — this is a forward-testing tracker, not an execution venue.
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, paced full-depth polling | 15m · 1h · 24h · 1w | Yes/no book, up to 100 levels/side, 7 assets; effective cadence varies with market load and API limits. |
| 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. Desk has no rolling history cap: it can query every recorded snapshot from the applicable series floor through the live feed. The floors differ because contracts and licensed capture did not begin on the same day for every asset/window combination.
Polymarket full-depth archive floors (UTC)
| Assets | 5m | 15m | 1h | 4h | 24h |
|---|---|---|---|---|---|
| BTC | 2026-02-12 | 2026-01-01 | 2026-01-01 | 2026-01-01 | 2026-01-01 |
| ETH, SOL, XRP | 2026-02-18 | 2026-01-01 | 2026-01-01 | 2026-01-01 | 2026-01-01 |
| BNB | 2026-03-13 | 2026-03-13 | 2026-03-06 | 2026-03-13 | 2026-03-07 |
| DOGE | 2026-03-13 | 2026-03-13 | 2026-03-11 | 2026-03-13 | 2026-03-11 |
| HYPE | 2026-03-13 | 2026-03-13 | 2026-03-06 | 2026-03-13 | 2026-03-07 |
These are the earliest days with recorded full ladders, not a claim that every asset/window existed before its floor. A snapshot returns the complete recorded ladder; it can legitimately contain no levels when the market itself had no resting orders at that instant.
Order-book depth is captured live and cannot be recreated after the fact. Archive access is delivered through the documented metered query surfaces; DepthFeed does not provide customer-requested reconstruction or bulk archive delivery.
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.