Prediction markets put a live price on questions like rate decisions, inflation prints, elections and the weather. If you are building a dashboard, a research notebook or a model, you quickly hit two problems: Kalshi and Polymarket each have their own APIs with their own field names and units, and comparing them means writing and maintaining two clients.
This guide shows how to get both into one normalized table with a small Apify Actor published by Hay Equipos called Prediction Markets Data: Kalshi and Polymarket Odds API. It reads only the exchanges' official public market data APIs. No login, no account and no personal data.
This tool provides data only. It is not betting advice or financial advice.
What the tool returns
Every row is one market with the same fields whichever exchange it came from:
- source, market ID, link, event ID and title, the question and outcome label
- category and tags, status, result, open and close times
- best Yes bid and ask, last price, and
impliedProbability - total volume, 24 hour volume,
volumeUnit, liquidity and open interest - the outcomes with their prices (and token IDs on Polymarket)
- optionally an order book snapshot and a price history series for the Yes side
Prices run from 0 to 1, so 0.62 means the market puts the Yes outcome at about 62%. impliedProbability is the midpoint of the best bid and ask when both exist, otherwise the last price (Kalshi) or the listed outcome price (Polymarket).
A row looks like this (values are illustrative, arrays shortened):
{
"source": "kalshi",
"marketId": "KXEXAMPLE-26DEC-T3.0",
"eventTitle": "Example: inflation above 3.0% in December?",
"question": "Example: inflation above 3.0% in December?",
"outcomeLabel": "Yes",
"category": "Economics",
"status": "open",
"closeTime": "2027-01-14T13:30:00Z",
"yesBid": 0.41,
"yesAsk": 0.43,
"lastPrice": 0.42,
"impliedProbability": 0.42,
"volume": 185400,
"volumeUnit": "contracts",
"openInterest": 52310,
"orderBook": {
"side": "yes",
"bids": [{ "price": 0.41, "size": 1200 }],
"asks": [{ "price": 0.43, "size": 950 }]
},
"priceHistory": [{ "timestamp": "2026-10-01T00:00:00.000Z", "price": 0.39 }]
}
Step by step in the Apify Console
- Open the Actor from its Apify Store page and sign in to Apify Console.
- In the Input tab, choose the Exchanges: Kalshi, Polymarket or both.
- Optionally enter a Keyword (matched against the question, event title or outcome) and Categories such as Politics, Economics, Sports, Crypto or Climate and Weather.
- Pick the Market status: open, closed or settled (settled is Kalshi only).
- Set Minimum total volume and Maximum markets per exchange. Markets are sorted by total volume, highest first.
- Switch on Include order book snapshot and Include price history if you need them, and choose the depth, number of days and hourly or daily spacing.
- Click Start, then export from the Output tab as CSV, JSON or Excel.
Use Apify schedules to run it hourly or daily and build your own history.
How to call it from code
With curl:
curl -X POST "https://api.apify.com/v2/acts/pistachio_implementation~prediction-markets-data/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"sources": ["kalshi", "polymarket"], "keyword": "fed", "status": "open", "maxMarkets": 25}'
In Python, with the apify-client package:
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("pistachio_implementation/prediction-markets-data").call(
run_input={
"sources": ["kalshi", "polymarket"],
"categories": ["Economics", "Economy"],
"minVolume": 1000,
"maxMarkets": 50,
"includePriceHistory": True,
"historyDays": 30,
"historyInterval": "1d",
}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["source"], row["question"], row["impliedProbability"], row["volumeUnit"])
A full Kalshi scan can take a minute or more, so for larger pulls the Python client, which waits for the run to finish, is the safer choice.
Pricing
Pay per event, with no subscription and no charge for platform usage:
- Market record saved: $0.001 ($1 per 1,000 markets)
- Order book snapshot added: $0.001 per market
- Price history added: $0.001 per market
A daily pull of the top 100 markets on both exchanges with order books comes to about $0.40. You can cap your spend with the maximum charge setting on each run, and the Actor stops cleanly when the cap is reached.
Limits and what it does not do
- Kalshi has no server side keyword search, so the Actor scans all listing pages for the chosen status (about 65 pages and over 100,000 markets for open markets). Closed and settled history is very large, so raise Maximum listing pages per exchange to go deeper.
-
Volume units differ. Kalshi counts contracts and Polymarket counts US dollars. The
volumeUnitfield says which. - Yes side only for order books and price history (the first outcome on Polymarket). On binary markets the No side is the mirror image.
- No multi leg combo markets (parlays) from Kalshi.
-
No automatic matching across exchanges. Each exchange words its markets differently. Filter both with the same keyword and compare
question,closeTimeandimpliedProbabilityyourself. - Polymarket is blocked in some countries at the network level. Apify's servers are not affected, but if you run the Actor on your own machine in a blocked country, the Polymarket part fails while Kalshi results are still saved.
- No trading. It reads public market data. It cannot place orders and needs no account.
- Data is as published by each exchange at the time of the run.
The Actor is not affiliated with Kalshi or Polymarket. Please use the data in line with each exchange's terms.
Try it on the Apify Store: https://apify.com/pistachio_implementation/prediction-markets-data
Top comments (0)