Prediction Market Data (Polymarket + Kalshi) avatar

Prediction Market Data (Polymarket + Kalshi)

Pricing

from $1.50 / 1,000 market retrieveds

Go to Apify Store
Prediction Market Data (Polymarket + Kalshi)

Prediction Market Data (Polymarket + Kalshi)

Fetch live prediction markets from Polymarket's public Gamma API and Kalshi's public markets API. One clean record per market: question, outcomes, prices, volume, liquidity, status, and URL. No account or API key required for either source.

Pricing

from $1.50 / 1,000 market retrieveds

Rating

0.0

(0)

Developer

Inn Corp

Inn Corp

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Pull live prediction markets from Polymarket's public Gamma API and Kalshi's public markets API in one call. One clean record per market: question, outcomes with current prices, volume, liquidity, end date, status, and a working URL. Both sources are fetched with public endpoints; no account or API key required for either.

What it does

  • Give it one or both sources (polymarket, kalshi, both by default).
  • Filter by category (politics, sports, crypto, ...), by keyword against the question text, and by active-only vs. include closed/resolved.
  • Get back up to maxMarkets records, combined across sources, newest matches first within each source's own ordering.
  • Optionally pull a live top-of-book snapshot per market.

Output example

Real records from test runs.

Polymarket:

{
"source": "polymarket",
"marketId": "559651",
"question": "Xi Jinping out before 2027?",
"category": null,
"outcomes": [
{ "name": "Yes", "price": 0.0525 },
{ "name": "No", "price": 0.9475 }
],
"volume": 12639436.846033994,
"liquidity": 165893.7477,
"endDate": "2026-12-31",
"status": "active",
"url": "https://polymarket.com/event/xi-jinping-out-before-2027",
"orderBook": null,
"fetchedAt": "2026-08-25T03:42:41+00:00"
}

Kalshi, with categories: ["politics"]:

{
"source": "kalshi",
"marketId": "KXNEXTDNCCHAIR-45-FSHA",
"question": "Will Faiz Shakir be the next Chair of the Democratic National Committee?",
"category": "Politics",
"outcomes": [
{ "name": "Yes", "price": 0.0955 },
{ "name": "No", "price": 0.9045 }
],
"volume": 248.38,
"liquidity": 0.0,
"endDate": "2045-01-08T15:00:00Z",
"status": "active",
"url": "https://kalshi.com/markets/kxnextdncchair-45-fsha",
"orderBook": null,
"fetchedAt": "2026-08-25T03:35:23+00:00"
}

A settled Kalshi market, showing the definite 0/1 outcome once resolved:

{
"source": "kalshi",
"marketId": "KXG7LEADEROUT-45JAN01-GMEL",
"question": "Will Prime Minister of Italy be the first to leave office?",
"category": "World",
"outcomes": [
{ "name": "Yes", "price": 0.0 },
{ "name": "No", "price": 1.0 }
],
"status": "resolved"
}

category is null on Polymarket records unless you filter by categories (Polymarket's market objects carry no native category field; see Honest limits). It is populated on Kalshi records whenever the run walked events at all, which happens whenever a category or keyword filter is set, or falls back to whatever the unfiltered event walk turned up.

Input

FieldMeaning
sourcespolymarket, kalshi, or both (default).
categoriesOptional category filter, one per line. Polymarket: checked against its live tag list. Kalshi: matched against categories seen live on events (no fixed list exists; see Honest limits).
keywordsOptional keyword filter, one per line. Case-insensitive substring match against the question text, applied on this Actor's side.
activeOnlyDefault true: only currently tradeable markets. Off also includes closed and resolved/settled markets.
maxMarketsCap on total records, combined across sources. Default 200, max 2000.
includeOrderBookOff by default. Fetches a live top-of-book snapshot per market: 2 extra calls per Polymarket market (Yes and No are separate order-book tokens), 1 per Kalshi market. Meaningfully slows a run; leave off unless you need depth, not just the current price.

Data sources and how they were verified

  • Polymarket: gamma-api.polymarket.com (markets, events, tags) and clob.polymarket.com (order book), both confirmed live to serve full market data with zero auth headers.
  • Kalshi: the documented trading-api.kalshi.com host now returns HTTP 401 with a message pointing to a new host. That new host, api.elections.kalshi.com, was confirmed live to serve markets, events, and order books with zero auth headers -- genuinely public read access, not a gap this Actor is papering over. If Kalshi ever locks that host down, this Actor is meant to fail loudly (an HTTP error in the log), not fall back to guessing.

Honest limits

  • Neither source's server-side filters are trustworthy, verified live. Polymarket's search query param and Kalshi's category query param are both silently ignored for values they don't recognize -- they quietly return the default unfiltered page instead of erroring or returning zero results. So keyword filtering always happens on this Actor's side, and category filtering is validated against live data before it's trusted: Polymarket tags one at a time against /tags/slug/{slug} (a real 200 vs. a 404), Kalshi categories against whatever actually turns up while walking events during the run.
  • Kalshi has no fixed category list. An early version of this Actor shipped one hand-sampled from live data; it was already missing "Crypto" and "Transportation" within the same test session. Rather than ship another guess, a Kalshi category filter is matched against categories seen live during the run, and a filter that matches nothing logs the categories it did see so you can adjust.
  • Kalshi's /markets endpoint is mostly synthetic combo markets. A live scan of 15,000 open Kalshi markets found only 64 that were a real, single-question market; the rest were auto-generated "multivariate" parlays across unrelated events (a market on "Bitcoin above $85k AND the Dodgers win" is not what this Actor sells). Those are filtered out unconditionally. Real markets are instead reached by walking Kalshi's events (which carry no such pollution) and pulling each event's own markets, which costs one extra call per event but is the only reliable path to clean data.
  • Kalshi keyword filtering checks the event's shared title AND each market's own title, and both directions can miss a real match. Fetching every event's markets just to check their titles is what made an unscoped keyword search against thousands of events time out during testing, so a keyword is checked against the event's own title (free, already on the page) before its markets are fetched at all -- a keyword that appears only in one specific market's title, never in the shared event title, can be missed. The reverse also happens: a keyword can match the event's shared title but appear in none of that event's individual market titles, which also returns zero results for that event. Both directions are a real limitation of doing keyword matching without fetching every event's markets unconditionally. This does not apply to Polymarket, where keyword filtering already runs against every market's own question text with no prefilter.
  • Polymarket's classic offset pagination has a real ceiling around 2,000-3,000 records, not just this Actor's own page-count cap. A rare keyword or category combined with a high maxMarkets can hit Polymarket's own API limit (it starts rejecting deep offsets) before this Actor's internal safety cap ever engages. When that happens, the run keeps whatever it already found, logs a warning, and finishes cleanly rather than erroring -- so a very rare query may return fewer markets than maxMarkets asks for, not because nothing else exists, but because Polymarket's own pagination cannot reach it with this method.
  • Kalshi market URLs are constructed, not fetched. Kalshi's website blocks scripted requests with bot protection, so https://kalshi.com/markets/{ticker} is built from Kalshi's documented routing pattern rather than confirmed by an actual page load. It was not possible to verify live.
  • Polymarket has no native category field. Its market objects carry no category or tag list; the only way to attach one is to query by a tag you already know, which is what categories does. Run without a category filter and category is null on every Polymarket record -- not omitted, genuinely unknown.
  • Prices are a live snapshot, not a guarantee. Polymarket outcome prices come straight from outcomePrices. Kalshi's Yes price is the midpoint of the live bid/ask when both are quoted, falling back to the last traded price when the book is empty, except once a market is settled, where Kalshi's own result field (a clean "yes" or "no") is used directly instead of stale quotes that would otherwise average out to a meaningless 0.5. Either way, a market can move the instant after you read it. This is public market data, not financial advice, and comes with no guarantee of real-time accuracy.

Fair pricing

Pay per market record returned (market-retrieved) and per completed fetch-and-filter operation (query-processed, charged once per source that finishes a run, success or an empty match, not on a request failure), once pay-per-event pricing is enabled. No subscription.