How we count
Every figure on /data and /datais a sum over rows returned by an exchange’s own public endpoint. This page says which endpoint, in what unit, with what missing · so any number can be checked against a request you can make yourself.
Holds the order book and matches trades. Volume only exists here. Kalshi, ForecastEx, QCX, CME, Crypto.com.
Holds customer accounts and routes flow to an exchange. Robinhood, Webull, Sleeper, PrizePicks, FanDuel, DraftKings.
Robinhood’s event-contract volume is already inside Kalshi’s number. Adding them together counts the same fills twice · which is what every list that ranks brokerages alongside exchanges is doing.
| Venue | Layer | Unit | Sides counted | Refresh | Source |
|---|---|---|---|---|---|
| Kalshi | Exchange · CFTC DCM | $1-face notional | one per match | 15 min | api.elections.kalshi.com |
| Polymarket | Exchange · onchain | $1-face notional | one per match | 15 min | gamma-api.polymarket.com |
| Limitless | Exchange · onchain | cash traded | one per match | 15 min | api.limitless.exchange |
| ForecastEx | Exchange · CFTC DCM | $1-face notional | no volume published | 15 min | www.forecastex.com |
| Manifold | Play money | play units | one per match | 15 min | api.manifold.markets |
No venue documents its unit or its counting convention, so both columns above were established by reconciling each API’s volume field against its own complete trade feed. The experiments are below and can be re-run without credentials.
Kalshi and Polymarket both publish a count of $1-face contracts and render it with a dollar sign. A contract filled at $0.20 adds $1.00 to volume and $0.20 to cash. The two are not close.
The API reference defines volume_fpas “the market volume in contracts” and notional_value_dollars as $1.00. On one NFL market, volume_fp of 8,753.35 matched the summed contract count over all 290 trades exactly · while cash actually exchanged was $4,998.78, or 57%.
Every volume field in the Gamma OpenAPI spec carries a type, a nullable flag, and no description. Pulling 100% of the taker trades on five markets, volume ÷ shares was 1.0000 on all five, while volume ÷ cash ranged from 1.62× to 6.29×. Volume is a share count, and the site prints it with a $.
Sidedness · the worry that dominates the discourse · is the smaller problem, and the answer depends on which path you read. Onchain, the double-counting is real:Polymarket’s CLOB emits an OrderFilledevent per order leg, so summing them straight reports a $4.13 sale as $8.26. That is Paradigm’s December 2025 finding, and it still applies to several Dune dashboards and to Polymarket’s own subgraph collateralVolume field. (Paradigm is an investor in Kalshi, which is worth knowing when weighing it.) Via the API, it is not: /trades defaults to takerOnly=true, flipping it to false returns exactly 2.0000×, and gamma matches the one-sided half. DefiLlama divides by two to undo the onchain doubling; The Block states outright that it uses “taker notional volume”, and the two series agree within 1–2%.
The trapPolymarket-wide, volume ÷ actual taker cash is 2.47×. That looks exactly like a doubled figure. It is not · the ratio is 1 ÷ average price, and average price across the platform is $0.40. On a coin-flip market it lands on 2.0; on a longshot at $0.002 it lands on 538×. Anyone who checks this on a 50/50 market concludes double-counting and stops, which is roughly how the claim travelled.
Round trips do count twice · opening and closing are two separate matches · which is the honest reason these figures dwarf sportsbook handle, and is routinely conflated with counting both legs of one fill.
What this costs when it goes unstated: June 2026 Kalshi volume was published as $9.4B by one tracker and $31Bby another in the same week. Same venue, same month, 3.3× apart, with no methodology page on either side to say which convention produced which number.
Kalshi's API reference defines volume_fp as "the market volume in contracts" and notional_value_dollars as $1.00 per contract. On KXNFLGAME-26AUG15LARKC-KC, volume_fp = 8,753.35 matched the summed contract count over all 290 trades exactly, while cash actually exchanged was $4,998.78 · 57%. Reconciling against the trade feed, where each row is one buyer/seller match, reproduces volume_fp exactly, so a match is counted once, not twice. Round trips (open then close) do add twice, because they are two matches.
Polymarket documents nothing: every volume field in the Gamma OpenAPI spec carries a type and a nullable flag and no description. Enumerating every trade across ~300 markets, gamma `volume` divided by summed share size was 1.0000 in every set · including 80 already-closed markets, where there is no snapshot lag to hide behind · while volume/cash ranged from 0.89x to 1000x. Volume is a share count, not dollars. The UI prints that same number with a $ in front (event tn-09-house-election-winner: gamma 33,175.003 vs "$33,175 Vol." in the server-rendered HTML). Sidedness: the /trades endpoint defaults to takerOnly=true; flipping it to false returns exactly 2.0000x the shares, and gamma matches the one-sided half. A single tx resolves to one taker row plus one row per maker · the complementary "buy NO" leg does not double-count.
The API returns volume as a raw integer alongside collateralToken {symbol: USDC, decimals: 6}, and volumeFormatted is that integer scaled by 1e6 · it is denominated in collateral, not shares. DefiLlama's open-source Base adapter reads the same venue from the OrdersMatched event and takes the collateral leg, with no /2, because OrdersMatched fires once per matchOrders call rather than once per order leg.
No volume is published in any unit, so sidedness never arises. Open interest is contracts outstanding at $1 face.
All open events, crawled by event rather than market · the market feed is ~99% auto-generated multivariate parlays with no volume and no category. 24h volume additionally spans markets settled in the last 48h, deduped by ticker, because short-duration series settle 96 times a day and an open-only figure lands ~6.5x low.
Top open events by volume. Capped around 2,100 because gamma rejects offset paging past ~1,900-2,900 and its keyset endpoint is broken · next_cursor never advances. Volume is power-law distributed so the cap costs little volume, but the market count is a floor, not a total.
All active markets, 25 per page (larger page sizes are rejected). Markets carry several categories; each is attributed to its first, otherwise per-category sums exceed the venue total. Because this figure is cash and Kalshi's and Polymarket's are $1-face notional, it is the one venue whose volume is not on the same scale as the other two · it is ~0.03% of the combined total, so the mixing is disclosed rather than corrected.
All listed contracts. Publishes open interest and categories but no volume of any kind, so it cannot appear in a volume ranking despite being a real regulated exchange with real activity. Response is a Lambda envelope with doubly-encoded JSON and a page size pinned at 8, so a full pass is ~1,500 requests.
Sampled markets. Volume is MANA and never enters a dollar total.
Volume on this site means $1-face notional, not cash traded.
Kalshi's volume_fp is contracts and Polymarket's gamma volume is shares; both settle at $1 and both are printed with a dollar sign. A contract filled at $0.20 adds $1.00 to volume and $0.20 to cash. Across our sample markets taker cash was 16-62% of reported notional, so anyone reading these figures as money that changed hands is overstating by 1.6x-6x.
Every venue we track counts one side of a matched trade.
Established against each venue's own trade feed rather than assumed. The doubling people worry about is real, but it lives on the raw onchain path, not the API one: Polymarket's CLOB emits an OrderFilled event per order leg, so summing them straight · as several Dune dashboards and Polymarket's own subgraph collateralVolume field do · reports a $4.13 sale as $8.26. The gamma API and the site's own UI already report the taker half.
A venue reading 2x its cash is not evidence of double counting.
Polymarket-wide, volume divided by actual taker cash is 2.47x · which looks exactly like a doubled figure and is not. The ratio is 1/average-price: on a coin-flip market it lands on 2.0, on a longshot at $0.002 it lands on 538x. Spot-checking a 50/50 market is the single easiest way to reach the wrong conclusion here, and it is roughly how the double-counting claim spread.
Round trips count twice, and that is not double counting.
Opening and later closing a position are two separate matches, so both add volume. This is the honest reason prediction-market volume looks large next to sportsbook handle, and it is routinely conflated with counting both sides of one fill.
Distribution partners never enter a volume total.
Robinhood, Webull, Sleeper and PrizePicks are brokerages routing to a DCM. Their flow is already inside that exchange's number; adding them counts the same fills twice.
Play money is never converted to dollars.
Manifold's MANA measures real trading, but no exchange rate makes it comparable to a regulated exchange's notional.
Open interest is only summed across venues that publish it.
Kalshi reports contracts outstanding at $1 each · a maximum-payout ceiling. Polymarket reports USDC actually posted. Both are dollar-denominated live exposure, but they are not the same measurement.
Coverage caps are published, never smoothed over.
Polymarket's pagination wall and ForecastEx's missing volume are properties of their APIs, not of the market. A number that hides its own truncation is worse than a smaller honest one.
Nothing is estimated, modelled, or filled in.
Every figure is a sum over rows returned by the venue's own public endpoint, reproducible without credentials.
- Robinhood Event ContractsFCMroutes to KalshiEX, ForecastEx, Rothera
- WebullFCMroutes to KalshiEX
- Sleeper MarketsFCMroutes to KalshiEX
- PrizePicks PredictFCMroutes to KalshiEX, Polymarket
- FanDuel PredictsJV / routingroutes to CME, Crypto.com CDNA
- DraftKings PredictionsOwns Railbirdroutes to Railbird / DKeX
- UnderdogOwns Aristotleroutes to Crypto.com CDNA, Aristotle
- Fanatics MarketsRoutingroutes to Crypto.com CDNA
- Coinbase Financial MarketsFCM; DCO pendingroutes to KalshiEX
Accuracy / calibration panel
A naive calibration curve over our 41,164 settled market-days looks striking and is wrong. Same-day resolvers are convergence-poisoned (a full-day VWAP includes trading after the outcome was obvious), Kalshi strikes come in ladders where pooling across legs manufactures the effect, and the 2026 auto-generated micro-market flood dominates any pooled tail statistic. Doing this properly needs a within-ladder estimator, not a bucket chart.
A cash series alongside the notional one
Notional is a contract count; cash is what traders actually paid, and the ratio is the average traded price, which moves. Producing it properly means replaying every fill at its execution price · Kalshi and Polymarket both expose per-trade prices, so this is work rather than a blocker, but a venue-level average price would be an estimate and we do not ship estimates.
Reconciling our figures against third-party dashboards
For June 2026 the same Kalshi month was reported as $9.4B by one tracker and $31B by another, roughly 3.3x apart, and neither publishes enough methodology to say which convention produced which number. Showing a comparison table would imply we know how to reconcile them. We know why they differ · unit and sidedness · not which specific choice each one made.