Kalshi Prediction Markets Scraper — Prices, Volume, Odds
Pricing
$0.80 / 1,000 market scrapeds
Kalshi Prediction Markets Scraper — Prices, Volume, Odds
Scrape every Kalshi prediction market with live yes/no prices, last trade, 24h volume, open interest and close time — joined to its event, series and category. Filter by category, status or volume. No API key, no login.
Pricing
$0.80 / 1,000 market scrapeds
Rating
0.0
(0)
Developer
Scrapers Delight
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Kalshi Prediction Markets Scraper
Every market on Kalshi — the CFTC-regulated US prediction exchange — with live yes/no prices, last trade, volume, open interest and close time, joined to the event, series and category it belongs to.
Why this one
Kalshi's own API exposes markets and events on separate endpoints, and the market records carry no category. Scrape /markets directly and you get thousands of tickers you can't group or filter by topic. This actor walks the event layer instead, so every row arrives already labelled Economics, Elections, Financials, Sports, Climate and Weather and so on — and you still get every market, because the events carry them nested.
Measured 2026-09-01: one request returned 200 events carrying 1,481 markets, and all 1,481 came back priced.
Quick start
{"categories": ["Economics", "Financials"],"tradedOnly": true,"maxItems": 0 // 0 = every matching market}
Leave categories empty to take the whole exchange.
Output
One row per market, 53 fields. Measured over 1,481 live markets on 2026-09-01: 42 fields populate on 100% of rows.
{"ticker": "KXELONMARS-99","marketTitle": "Will Elon Musk visit Mars before Aug 1, 2099?","eventTitle": "Will Elon Musk visit Mars in his lifetime?","seriesTicker": "KXELONMARS","category": "World","status": "active","marketType": "binary","yesBid": 0.10, "yesAsk": 0.12,"yesBidSize": 41.96, "yesAskSize": 391.89,"noBid": 0.88, "noAsk": 0.90,"lastPrice": 0.10, "previousPrice": 0.11,"previousYesBid": 0.10, "previousYesAsk": 0.12,"volume": 118113.87, "volume24h": 4, "openInterest": 40035.19,"liquidity": 0, "notionalValue": 1,"customStrike": { "Holder": "Klaus Iohannis" },"floorStrike": null, "capStrike": null,"priceRanges": [{ "start": "0.0000", "end": "1.0000", "step": "0.0100" }],"priceLevelStructure": "linear_cent","openTime": "...", "closeTime": "2099-08-01T04:59:00Z","expirationTime": "...", "expectedExpirationTime": "...", "latestExpirationTime": "...","createdTime": "...", "updatedTime": "...","canCloseEarly": true,"earlyCloseCondition": "This market will close and expire early if the event occurs.","settlementTimerSeconds": 1800,"result": null, "expirationValue": null,"settlementValue": null, "settlementTime": null,"marketUrl": "https://kalshi.com/markets/kxelonmars#kxelonmars-99","scrapedAt": "2026-09-01T00:00:00.000Z"}
Prices are decimal dollars per contract (0.10 = 10¢ = a 10% implied probability). Kalshi returns them as strings; this actor converts them to numbers so the dataset is arithmetic-ready.
Both sides of the book come with their resting size (yesBidSize / yesAskSize). A 2¢ spread on 5 contracts is not the same market as a 2¢ spread on 5,000, and most scrapers in this lane ship the price without the size.
Strike definition — customStrike (51% of rows) carries what the market is actually about, e.g. {"Holder": "Klaus Iohannis"} for "who will be next NATO Secretary General". floorStrike (40%) and capStrike (7%) cover scalar markets. Without these a row's title alone can be ambiguous.
Fields that are intentionally sparse, because the underlying market has no value for them:
| Field | Fill | Why |
|---|---|---|
strikeType | 88% | not every market type has a strike |
earlyCloseCondition | 84% | only markets that can close early |
occurrenceDatetime | 83% | event-dated markets only |
collateralReturnType | 62% | set per event |
customStrike | 51% | markets whose strike is a named entity |
floorStrike / capStrike | 40% / 7% | scalar / ranged markets |
result, expirationValue, settlementValue, settlementTime | 5% | only settled markets resolve |
Set includeRules to add rulesPrimary, rulesSecondary and the event's settlement sources. It makes rows considerably larger, so it is off by default.
Filters
categories— event category. Live values include Economics, Elections, Politics, Financials, Sports, Climate and Weather, Science and Technology, Entertainment, World, Social.marketStatus— Kalshi's own lifecycle value (active,settled,closed…).anyreturns everything. Usesettledto pull resolved history.tradedOnly/minVolume— Kalshi lists many markets that have never traded (281 of the 1,481 in our sample). SwitchtradedOnlyon for a book of live, priced contracts only.seriesTickers/eventTickers— pin to specific questions.
Pricing
Pay per result — you only pay for markets delivered.
| Event | Price | When it fires |
|---|---|---|
market-scraped | $0.0008 | One per market pushed to the dataset |
That is $0.80 per 1,000 markets, the cheapest in this lane at time of writing (the next cheapest charges $0.99/1,000). Rows are billed through Apify's gated pushData form, so at a spend cap the run stops cleanly and you are never charged for rows you didn't receive.
Worked examples: the whole exchange at ~1,500 active markets ≈ $1.20. One category — say Financials, ~90 markets — ≈ $0.07. A daily snapshot of every traded market for a month ≈ $36.
Notes / honest limits
- No login, no API key, no anti-bot. This is Kalshi's own public trade API. A proxy is optional and off by default; add one only if you're running at high volume.
- This is market data, not a trading interface. No order placement, no portfolio, no authenticated endpoints — all of that needs your own Kalshi credentials and is out of scope.
- Order-book DEPTH is not included. You get top of book — best bid, best ask, and the size resting on each — plus the last trade and the previous quote. The full ladder is a separate per-market request and would multiply run cost; ask if you need it.
strike_date/strike_periodexist on Kalshi's event schema but came back empty on all 1,481 markets sampled, so they are deliberately not shipped rather than added as always-null columns.- Not investment advice. Prices are a snapshot at
scrapedAtand move continuously.