Data sources and limits
Every source is public and needs no key. Each has limits, and the pages state them instead of hiding them. Numbers on this page come from the committed data files (run of 2026-09-23) unless marked otherwise.
Kalshi#
- Base URL:
https://api.elections.kalshi.com/trade-api/v2. Endpoints:/series(fee type and multiplier per series, cached 6 hours),/events/fee_changes(per-event overrides, cached 30 minutes),/events?status=open&with_nested_markets=true,/markets/orderbooks. - Server-side only. Any request with an
Originheader gets 403 (checked again 2026-09-25: 200 without, 403 with). - Limits in the code: 8 requests per second, at most 1,200 events per run (
--max-events), order-book depth for up to 400 markets. - Prices are decimal dollars (
"0.0550"), not whole cents; sub-cent price steps exist. - The order book returns bids only. A YES ask is
1 − best NO bid.
Kalshi fee formula#
taker fee = ceil_to_$0.000001( 0.07 × C × P × (1 − P) × fee_multiplier ) maker fee = ceil_to_$0.000001( 0.07 × 0.25 × C × P × (1 − P) × fee_multiplier ) settlement = 0 for a simple yes/no market
C is contracts, P the price in dollars. The multiplier is read live per series, with the event override on top; it is never hard-coded. Rounding is up to the next millionth of a dollar, not to the next cent. The 0.07 constant reproduces Kalshi's published worked example exactly (1 contract at $0.055 → $0.00363825). The fee is largest at 50¢ and falls towards zero at the extremes, so the same gross spread costs far more near a coin flip. A flat fee type exists in Kalshi's enum with no published rate; the Scanner reports such a fee as unknown. Deposit, withdrawal and wire costs are not in the math.
Polymarket (runs on the GitHub runner)#
- Markets: Gamma
https://gamma-api.polymarket.com/markets/keyset, cursor paging, 500 per page (falls back to 100), open markets only. A safety ceiling of 50,000 markets stops the read; hitting it is recorded astruncatedinboard.json. The last run read 49,939 and hit it. - Order books:
POST /bookson the CLOB host in batches of 100 (hard cap 500), for the 3,000 highest-volume markets. Other markets carry no book and showunknowndepth. A batch with a bad id is split until the bad id is isolated. - CLOB host:
https://clob.polymarket.com, overridable with the environment variablePOLYMARKET_CLOB_HOST.clob-v2.polymarket.com, named in one SDK's readme, has no public DNS record. - Fees are unknown. The formula (
shares × rate × (P × (1 − P))^exponent) is from Polymarket's MIT SDK source, but no live fee schedule has been fetched, so every Polymarket fee is reported asunknown, never guessed. - Settlement time is taken from
endDate, thenendDateIso, then the event's end date, thenumaEndDate. Kalshi often has no deadline where Polymarket has one; that difference is why the settlement veto rejected every cross-venue pair in the last run. - Rate limits of Gamma and the CLOB are unknown. The code runs at 5 requests per second.
Polygon (the Terminal's tape)#
- Contract: Polymarket's CTF Exchange V2,
0xE111180000d2663c0091e4f400237545b87b996b. - RPCs: by default
polygon-bor-rpc.publicnode.com,polygon.drpc.org,1rpc.io/matic, tried in that order; public and keyless. To use your own endpoint, setPOLYGON_RPC_URL(see Use your own Polygon RPC): it is tried first, the public ones stay as the fallback, and the file and the page name it only asown RPC (POLYGON_RPC_URL), never by its URL. (The RPC URL you enter in the admin is used by the Status page's check.) - Events decoded:
OrderFilled,OrdersMatched,FeeCharged. Each fill gives side, token id, size, price (collateral ÷ tokens), fee and builder code. - Window: the job reads 40 blocks, about one minute. The window is labelled in blocks and chain time in the file and on the page, never as "24 hours".
- Large fill means the top 2% of fills by notional in that window, computed from the window itself.
- Categories: Polymarket market rows usually carry no category, so the Stack labels each market from its title and address (Categories). Markets in your hidden categories are left out of the lists; the window totals still count them.
- What the chain cannot give: the order book, best bid and ask, and depth. Polymarket's order book is off-chain. The Terminal says "No order book" on screen. A price derived from fills is a last-traded price, not an executable one.
Market titles (Gamma, runs on the GitHub runner)#
The chain knows token ids, not questions. titles.js asks Gamma for up to 300 token ids per run, 20 per request, and writes the questions into tape.json. If Gamma cannot be reached it writes titles.status: "unavailable" and no titles; the Terminal then shows shortened token ids with a note. Nothing stands in for a missing title.
Freshness#
Data is as fresh as the last refresh run. Every page shows when its file was produced ("updated 1d ago", "Snapshot from 1d ago"). Without the schedule turned on, the data stays at the last manual run.