Prediction Markets Data: Kalshi + Polymarket in One Schema avatar

Prediction Markets Data: Kalshi + Polymarket in One Schema

Pricing

from $1.60 / 1,000 market outcomes

Go to Apify Store
Prediction Markets Data: Kalshi + Polymarket in One Schema

Prediction Markets Data: Kalshi + Polymarket in One Schema

Pick Kalshi, Polymarket or both, optionally filter by keyword or category, and get one flat row per outcome: probability (0-1), bid/ask, 1h/24h/7d change, volume, liquidity, close time and URL. Optional 7-day price history and changed-since-last-run mode. Official public APIs.

Pricing

from $1.60 / 1,000 market outcomes

Rating

0.0

(0)

Developer

SUNGHWAN CHO

SUNGHWAN CHO

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Choose Kalshi, Polymarket or both (optionally a keyword, category, status or minimum volume), and get one flat row per market outcome with the implied probability (0–1), best bid/ask, 1h/24h/7d price change, volume, liquidity or open interest, close time and a link to the market.

  • Both venues in the same English field names, numbers as numbers, missing values as null.
  • Open markets come highest 24-hour volume first.
  • Optional 7-day hourly price history per outcome.
  • Optional "only what changed since my last run" mode for scheduled monitoring and alerts.
  • Uses only the venues' official public, unauthenticated read APIs. No login, no browser, no proxy.

What you get

One row per outcome:

  • A single yes/no question (e.g. "Will the Fed cut rates in December?") → one row, outcome: "Yes".
  • A multi-outcome event (e.g. "Who will win the 2028 Democratic nomination?") → one row per candidate, outcome: "Gavin Newsom", …
  • A two-sided Polymarket market (e.g. a game "Ravens vs. Falcons") → one row per side.
FieldMeaning
venuepolymarket or kalshi
eventId, eventTitleEvent the market belongs to
marketId, questionKalshi market ticker / Polymarket condition id, and the market question
outcome, outcomeIdWhat this row prices (candidate, team, range or Yes); Kalshi ticker / Polymarket CLOB token id
probabilityImplied probability 0–1 (see below)
lastPrice, bestBid, bestAsk, spreadPrices on the 0–1 scale
change1h, change24h, change7dPrice change on the 0–1 scale (0.05 = +5 points)
volume24h, volumeTotal, volumeUnitVolume; volumeUnit is USD (Polymarket) or contracts (Kalshi, each contract pays $1)
liquidityPolymarket order-book liquidity in USD (null on Kalshi)
openInterestKalshi open interest in contracts (null on Polymarket)
closeTimeScheduled close, ISO 8601
status, resolvedOutcomeopen, closed, resolved, upcoming; the winning outcome once resolved
category, tagsKalshi event category; Polymarket main category and all tags
urlMarket page
previousProbability, probabilityChangeSinceLastRun, changeTypeFilled in change mode only
priceHistory[{ "time", "price" }] hourly for 7 days, when requested
scrapedAt, schemaVersionCollection time and output version

Example row:

{
"venue": "kalshi",
"eventId": "KXNEXTNATOSECGEN-99",
"eventTitle": "Who will be the next Secretary General of NATO?",
"marketId": "KXNEXTNATOSECGEN-99-KKAL",
"question": "Will Kaja Kallas be the next Secretary General of NATO?",
"outcome": "Kaja Kallas",
"outcomeId": "KXNEXTNATOSECGEN-99-KKAL",
"probability": 0.21,
"lastPrice": 0.21,
"bestBid": 0.25,
"bestAsk": 0.47,
"spread": 0.22,
"change1h": null,
"change24h": 0.088,
"change7d": null,
"volume24h": 0,
"volumeTotal": 1936.64,
"volumeUnit": "contracts",
"liquidity": null,
"openInterest": 1174.5,
"closeTime": "2099-01-08T15:00:00.000Z",
"status": "open",
"resolvedOutcome": null,
"category": "Elections",
"tags": ["Elections"],
"url": "https://kalshi.com/markets/kxnextnatosecgen",
"previousProbability": null,
"probabilityChangeSinceLastRun": null,
"changeType": null,
"priceHistory": null,
"scrapedAt": "2026-10-12T03:48:47.026Z",
"schemaVersion": 1
}

How probability is computed

  • Polymarket: the outcome price Polymarket itself displays (outcomePrices).
  • Kalshi: the midpoint of best bid and best ask when the spread is 10 cents or less, otherwise the last traded price (the same rule Polymarket uses for its display). null if the market never traded and has no two-sided book.

Where the changes come from

  • Polymarket: the 1h/24h/7d changes Polymarket publishes for each market; missing ones are filled from price history when you turn it on.
  • Kalshi: change24h = last price − price 24 hours ago. change1h and change7d need Include 7-day price history (then all three are computed from the hourly history, against probability).

Input

FieldDefaultNotes
venuesbothpolymarket, kalshi
keywords–Any of these words in event title, question or outcome (case-insensitive)
categories–Whole-word match on category/tags, e.g. Politics, Crypto, Economics, Weather
statusopenopen, closed (resolved first, most recent first), all (open first)
maxItems100Rows per venue (1–10,000)
minVolume24h0USD on Polymarket, contracts on Kalshi
closingWithinDays–Only markets closing within N days
includePriceHistoryfalseAdds 7-day hourly priceHistory
onlyChangedSinceLastRunfalseChange mode, see below
minProbabilityChange0.01Smallest move that counts as a change (0–1 scale)
historyStoreNameprediction-markets-historyNamed key-value store that remembers the last returned probabilities

Example — top 50 crypto markets on both venues:

{ "categories": ["Crypto"], "maxItems": 50 }

Example — every 15 minutes, alert on Fed / rates markets that moved 3+ points:

{
"keywords": ["fed", "rate cut", "fomc"],
"onlyChangedSinceLastRun": true,
"minProbabilityChange": 0.03,
"historyStoreName": "fed-watch"
}

Change mode

With onlyChangedSinceLastRun, the Actor builds the same list as usual (filters + maxItems) and then returns only outcomes that are new, changed status, or moved at least minProbabilityChange since they were last returned. The comparison point only moves when a row is returned, so slow drifts are still reported once they add up. Use a different historyStoreName for each watchlist. Two runs with the same store at the same moment may report the same change twice.

Pricing

Pay per event: one market-outcome event per row saved to the dataset. Runs that save nothing (no matches, or nothing changed) cost no events; failed requests are never charged. If you set a Maximum cost per run, the Actor stops cleanly when it is reached and says so in the status message and in RUN_SUMMARY.

Run summary

The key-value store record RUN_SUMMARY (free) has per-venue status (completed, failed, budgetLimited), stopReason, markets scanned, rows matched/saved, rows unchanged (change mode) and request counts. If one venue fails, the other venue's rows are still saved; the run fails only if every venue failed.

Speed and limits

  • Polymarket returns markets sorted by 24h volume, so the Actor stops as soon as it has enough rows. Up to 5,000 open markets are scanned per run when a filter is narrow.
  • Kalshi does not sort by volume, so the Actor reads the whole open list (about 12,000 events / 120,000 markets, roughly 2–4 minutes at 256 MB) and sorts it. With status: closed, resolved (settled) markets come first, then closed-but-unresolved ones, most recently closed first; up to 2,000 events of each are scanned and Kalshi markets that never traded are skipped.
  • status: all returns open markets first and fills the rest with closed ones.
  • Requests are paced (about 2–3 per second) and well under both venues' published rate limits.
  • The Actor must run on the Apify platform. Polymarket blocks some countries; this Actor does not try to get around regional restrictions.

Notes and responsible use

  • This Actor reads public market data through official, unauthenticated read endpoints. It does not log in, trade, or access any account or personal data.
  • Kalshi's Developer Agreement and data terms and Polymarket's Terms of Use restrict how their data may be stored, redistributed and used commercially. You are responsible for making sure your use of the data complies with those terms. Not investment advice.
  • Kalshi market URLs point to the series page.
  • Cross-venue matching ("is this Kalshi market the same as that Polymarket market?") is deliberately not done: resolution rules and close times differ even when the questions look alike.