Prediction Markets Scraper – Kalshi + Polymarket Odds & Prices
Pricing
from $0.70 / 1,000 market records
Prediction Markets Scraper – Kalshi + Polymarket Odds & Prices
Kalshi + Polymarket markets in one table: odds, bid/ask, volume, result. Price history for both (Kalshi since 2021, Polymarket since 2024), candlesticks, order book depth, trades, Polymarket comments and top holders. Politics, sports, crypto, economics, weather. Public APIs. Pay per record.
Pricing
from $0.70 / 1,000 market records
Rating
0.0
(0)
Developer
Tit Slobodjanac
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
19 days ago
Last modified
Categories
Share
Prediction Markets Scraper — Kalshi + Polymarket in one table, with price history for both, Polymarket comments and top holders
Pull live odds and settled results from Kalshi and Polymarket into one normalized dataset: question, yes/no price, best bid and ask, spread, volume, 24-hour volume, liquidity, open interest, open/close time, result and a link to the market. Filter by keyword, category, Kalshi series or Polymarket tag.
What you can attach to every Kalshi market, in plain words:
- 5-year Kalshi history (since July 2021).
lookbackDaysup to 1,825, or asettledAfter/settledBeforewindow. Beyond the live window (about three months) the actor reads Kalshi's public historical archive: every settled market with itsresultandexpirationValue. Same record format as today's markets. - Candlesticks: 1-minute, hourly or daily (
candlesticks: "1m" | "1h" | "1d"). OHLC price, yes bid/ask OHLC, volume and open interest over the market's life, for open markets and for markets settled years ago. Included in the record price. - Order book depth (top 10 levels) (
includeOrderbook). Yes and no bids on Kalshi, yes-token bids and asks on Polymarket. - Trade tape (
includeTrades). The most recent trades of each market, back to 2021 through the historical tape.
No Kalshi account, no Polymarket wallet, no API key. Data comes straight from both exchanges' public JSON APIs (Kalshi trade API v2 incl. /historical/*, Polymarket Gamma + CLOB). No login, no cookies, no browser, no proxies — which is why it is fast and why runs do not fail.
Why this one
- It works every run. No headless browser and no scraping of HTML that changes. The only failure mode is an exchange API outage, and then the run fails loudly. A filter that matches nothing ends with an empty dataset, one log line saying why, and no charge.
- One schema for both exchanges. A Kalshi contract and a Polymarket market come back with the same field names, so you can join, compare and spot price gaps without mapping two formats.
- Real markets, not parlay noise. Kalshi lists thousands of auto-generated multi-leg combinations (
KXMVE…). They are excluded by default; flipexcludeMultiLegif you want them. - Pay only for records you receive. $1 per 1,000 market records; a record is charged only after it is written to the dataset. Candles and trades ride along inside the record at no extra charge. Nothing for a run that returns nothing.
What people use it for
- Arbitrage and cross-exchange comparison — same event, two prices, one table.
- Trading research and backtests — five years of settled Kalshi markets with results, plus daily or minute candlesticks per market; Polymarket price history back to 2024 (daily whole-life in one call, hourly or minute in chunks) and the Polymarket trade tape per market. One run, no archive to build first, no subgraph.
- Dashboards and newsletters — top markets by 24-hour volume in politics, sports, crypto, economics, commodities, weather.
- 15-minute crypto and commodity markets —
KXBTC15M,KXETH15M,KXGOLD15M… with 1-minute candles and the trade tape for every 15-minute contract. - Weather markets — every Kalshi daily high/low (
KXHIGH*,KXLOW*) and hourly (KXTEMP*) temperature bracket for 50+ cities; pair with the Kalshi Weather Index actor for the settlement series itself. - Sentiment and whale watching (Polymarket) — the comment thread of an event (body, wallet, name, reactions, replies) and the largest holders of every outcome (wallet, name, shares), attached to the market row. Sort by
commentCountto start with the most discussed markets. - Alerts — schedule hourly, compare
yesPricewith the previous run, push a Slack/Discord message through an Apify integration when a market moves. - AI agents — ask "what does the market think about X?" and get numbers, not vibes.
Input
{"platforms": ["kalshi", "polymarket"],"status": "open","keywords": ["fed", "bitcoin"],"categories": ["economics", "crypto"],"minVolume": 1000,"maxItems": 500,"includeOrderbook": false}
Five years of one Kalshi series with daily candles:
{"platforms": ["kalshi"],"kalshiSeriesTickers": ["KXHIGHNY"],"status": "settled","lookbackDays": 1825,"candlesticks": "1d","maxItems": 500}
One slice of the archive (results are newest first, so aim the window):
{ "platforms": ["kalshi"], "kalshiSeriesTickers": ["KXHIGHNY"], "status": "settled", "settledAfter": "2022-06-01", "settledBefore": "2022-09-01", "candlesticks": "1d" }
| Field | What it does |
|---|---|
platforms | kalshi, polymarket or both (default both). |
status | open (live prices), settled (results) or both. |
keywords | Keep markets whose question, event title or ticker contains any keyword. |
categories | Keep markets whose category/tag contains any word: politics, sports, crypto, economics, weather, entertainment, science, companies, world… |
minVolume, minLiquidity | Drop thin or toy markets. |
maxItems | Cost cap. Default 500. |
includeOrderbook | Attach order book depth, top 10 levels per open market (+$1 per 1,000 order books, one extra call per market). |
lookbackDays | For settled Kalshi markets: how far back by close time (default 7, max 1,825 = 5 years). Past the live window the public /historical archive is used automatically. |
settledAfter, settledBefore | Explicit settled window by close time (ISO date or unix seconds). settledAfter overrides lookbackDays. |
candlesticks | none (default), 1m, 1h or 1d. Attaches a candles array to every Kalshi record. |
maxCandlesPerMarket | Cap per record, default 5,000 (one API call). The most recent candles are kept; candlesTruncated says when more existed. 1-minute candles on long-lived markets are large: a month is ~43,000 candles, a year ~525,000. Use 1h or 1d for markets that live longer than a few days, or set candlesFrom / candlesTo. |
candlesFrom, candlesTo | Optional candle window (ISO date or unix seconds); default is the market's open to close. |
includeTrades, maxTradesPerMarket | Attach the most recent trades (default cap 1,000) as a trades array; tradesTruncated says when more existed. |
excludeMultiLeg | Hide Kalshi parlay combinations (default on). |
kalshiSeriesTickers | Exact tickers (KXBTC, KXFED, KXNBA) or prefixes with *: KXHIGH* = every daily-high temperature city, KXLOW* = every daily-low city (pair with categories: ["weather"] to skip the Lowe's earnings series KXLOW). |
polymarketTagIds | Raw tag IDs from gamma-api.polymarket.com/tags when you need a precise tag. |
language | en, es or pt: Kalshi market titles and rules in Spanish or Portuguese. |
archiveDatasetName | Also append every record to a named dataset in your account. Schedule the run and the dataset becomes a price history (useful for Polymarket, which has no public archive). No extra charge. |
When several Kalshi series are requested, the record cap is shared out across them (leftover budget from short series flows to the next), so a nine-series run does not spend everything on the first two. A categories filter on Kalshi scans exactly the series in that category (weather → 367 series, commodities → 81), so small categories are never missed. Very large categories (sports, ~3,600 series) fall back to the generic scan; add kalshiSeriesTickers such as KXNBA* to narrow.
Most-discussed Polymarket markets with their comment threads and top holders:
{"platforms": ["polymarket"],"status": "open","polymarketSortBy": "commentCount","includeComments": true,"maxCommentsPerEvent": 500,"includeHolders": true,"maxHoldersPerOutcome": 20,"maxItems": 100}
Output
One row per market:
{"platform": "polymarket","id": "4000248","ticker": "lol-hle1-t1-2026-09-02","question": "LoL: Hanwha Life Esports vs T1 (BO5) - LCK Playoffs","eventTitle": "LoL: Hanwha Life Esports vs T1 (BO5) - LCK Playoffs","category": "Esports","status": "open","outcomes": ["Hanwha Life Esports", "T1"],"outcomePrices": [0.565, 0.435],"yesPrice": 0.565,"noPrice": 0.435,"yesBid": 0.56,"yesAsk": 0.57,"lastPrice": 0.56,"spread": 0.01,"volume": 2009194.56,"volume24h": 1926235.0,"liquidity": 79729.05,"openInterest": 4529841.49,"priceChange1h": 0.22,"priceChange24h": -0.08,"openTime": "2026-08-30T12:20:38Z","closeTime": "2026-09-02T14:00:00Z","result": null,"url": "https://polymarket.com/event/lol-hle1-t1-2026-09-02/lol-hle1-t1-2026-09-02","fetchedAt": "2026-09-02T11:50:00.000Z"}
Kalshi rows carry the same fields plus noBid / noAsk, eventId (event ticker), seriesId (series ticker), expirationValue (the settlement value, e.g. the observed temperature or BTC price), exchangeIndex (the Kalshi engine shard the market trades on, needed for order routing since the August 2026 re-sharding) and source (live or historical). Prices are in dollars per contract (0–1). result is yes/no on Kalshi and the winning outcome name on Polymarket. With includeOrderbook an orderbook object is added: { yesBids: [{price,size}…], noBids | yesAsks: […] }.
Polymarket rows also carry conditionId, polymarketEventId and commentCount. With includeComments the first record of each event gets comments (newest first, replies carry parentCommentId) and commentsTruncated; the event's other markets carry commentsAttachedTo (the record id that has the thread) instead of a copy:
{ "id": "3243213", "body": "…", "createdAt": "2026-09-06T18:11:45Z", "parentCommentId": null, "wallet": "0xbcd2…", "proxyWallet": "0x6241…","name": "halostryx", "pseudonym": "Flimsy-Zero", "reactionCount": 3, "reactions": { "HEART": 3 }, "reportCount": 0 }
With includeHolders each Polymarket record gets holders, the largest positions per outcome sorted by size (works for settled markets too):
{ "outcome": "No", "outcomeIndex": 1, "wallet": "0xa5ef…", "name": null, "pseudonym": "Unequaled-Shingle", "shares": 3243375.35, "verified": false, "token": "1063…" }
With candlesticks each record gets candles (oldest first), candleInterval and candlesTruncated. Kalshi candles are full OHLC:
{ "t": "2022-08-05T04:00:00.000Z", "ts": 1659672000, "open": 0.61, "high": 0.71, "low": 0.59, "close": 0.69, "mean": 0.6474,"yesBid": { "open": 0.2, "high": 0.69, "low": 0.2, "close": 0.67 }, "yesAsk": { "open": 1, "high": 1, "low": 0.61, "close": 0.69 },"volume": 581, "openInterest": 425 }
t is the end of the candle period. Kalshi only returns periods with activity, so a quiet market has fewer candles than its life span suggests. Polymarket candles are the yes-token price series from the CLOB, so only close is filled: { "t": "2026-07-20T00:00:24.000Z", "ts": 1784505624, "close": 0.9995 }. Daily history covers the market's whole life (back to 2024) in one call; hourly and 1-minute history is fetched in 15-day windows newest first until maxCandlesPerMarket. With includeTrades each record gets trades (newest first). Kalshi: { t, yesPrice, noPrice, count, takerSide, isBlockTrade, tradeId }. Polymarket: { t, side, outcome, price, size, wallet, name, pseudonym, txHash } from the public Data API (fills, not orders; up to 10,000 per market).
Run it from code
curl -X POST "https://api.apify.com/v2/acts/gratified_ashram~prediction-markets-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"platforms":["kalshi","polymarket"],"categories":["politics"],"maxItems":200}'
Works the same from the Apify JavaScript/Python clients, Make, Zapier, n8n, or on a schedule in the Console.
FAQ
Do I need a Kalshi or Polymarket account? No. Both expose public market-data APIs; nothing here trades or logs in.
How fresh are the prices? As fresh as the exchange API at the moment of the run — typically seconds. Schedule the run as often as you like.
Can I get historical price series? Yes, for Kalshi: set lookbackDays up to 1,825 (or settledAfter/settledBefore) and candlesticks to 1m, 1h or 1d. Kalshi's live API serves about three months; older settled markets, their candlesticks and trades come from Kalshi's public historical archive, which starts in July 2021, and the actor switches between the two automatically. For Polymarket the same candlesticks input returns the yes-token price series from the public CLOB: daily for the market's whole life (back to 2024) in one call, hourly or 1-minute in 15-day windows. For anything the exchanges do not keep (order-book depth over time), set archiveDatasetName and schedule the run so every run appends to one dataset in your account.
Can I get order-book history? Neither exchange keeps past order books, and a settled Kalshi market returns an empty book. What is public is the per-minute best bid/ask: candlesticks: "1m" on Kalshi returns yesBid and yesAsk open/high/low/close for every minute back to 2021, plus the full trade tape with includeTrades. For full depth at millisecond resolution use a dedicated recorder (kalshibacktest.com or Predexon sell it); this actor gives you the live top-10 book with includeOrderbook and lets you archive snapshots on a schedule.
How long does a history run take? One API call per market for the list plus one per market for candles (or one per 5,000 candles). 500 markets with daily candles is about two minutes.
Why is Kalshi's category sometimes empty? Categories come from the series list; a brand-new series may not be in it yet.
Pricing
$1.00 per 1,000 market records, plus $1.00 per 1,000 order books when you ask for depth. Candlesticks, trades, Polymarket comments and top holders are part of the record, not a separate charge. Platform usage is included. A run that returns no records costs nothing.
Found it useful? A short review on the Actor page helps others find it. Missing a field or an exchange? Open an issue on the Issues tab.