Kalshi Markets Scraper avatar

Kalshi Markets Scraper

Pricing

from $2.10 / 1,000 results

Go to Apify Store
Kalshi Markets Scraper

Kalshi Markets Scraper

Prediction markets from Kalshi's public trade API: every open event and its markets with bid/ask/last in dollars, implied probability, volume, open interest, close and expiration times, strikes and rules, by category or series. Skips the exchange's auto-minted parlay markets.

Pricing

from $2.10 / 1,000 results

Rating

0.0

(0)

Developer

Ibnu Adzim

Ibnu Adzim

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Categories

Share

Prediction markets from Kalshi, the CFTC-regulated US exchange, via its public trade API: every open event and each of its markets with Yes/No bid and ask, last price, implied probability, volume and open interest in contracts, open/close/expiration times, strikes, settlement rules, and the event's title, category and market count on every row.

HTTP only, no key, no login, no browser. One request per 200 events.

What it is for

  • Odds monitoring by category or series, on a schedule.
  • Cross-exchange comparison — pair with the Polymarket Markets Scraper on the same schedule.
  • Settlement research — status: settled returns finalized markets with their results.

Input

fieldwhat it does
categoriesPolitics, Elections, Economics, Financials, Crypto, Sports, … Empty = everything.
seriesTickerse.g. KXBTC, KXFED, KXNEWPOPE.
eventTickerse.g. KXNEWPOPE-70.
statusopen (default), closed, settled, unopened.
excludeMultivariate, minVolume, closingAfter, closingBefore, sortByFilters — see below.
includeEventRowsAlso emit one EVENT row per event.
maxItems, maxConcurrency, minRequestInterval, proxyConfigurationLimits.

Five things about this API worth knowing before you trust a run

1. /markets is 99.6% auto-minted parlays; /events is the catalogue

/markets?status=open returned 120,000+ rows without ending — 119,549 of them KXMVE… combination markets ("yes Arsenal, yes Barcelona 1st half, …") with zero volume, and the 451 real ones all brand new. A "list open markets" built on it never reaches a real question. This Actor lists through /events (13,538 open events, ends cleanly, zero parlays) and still flags and, by default, excludes any multivariate market that arrives via a series or ticker target.

2. The documented price fields are null; the values are strings next door

yes_bid: null beside yes_bid_dollars: "0.0420"; volume: null beside volume_fp: "24113.00". On every one of 125,696 markets measured. Prices here are floats in dollars (0–1), volume and open interest floats in contracts, parsed from those strings.

3. An event's status is not its markets' status

status=settled events carry markets that are still active (431 of 885 in one page); status=open events carry markets already finalized. Each market is kept only if its own status belongs to the family you asked for; the rest are counted as filteredOut.statusMismatch.

4. Some filters are honoured, some are silently ignored

min_close_ts works on /events; max_close_ts and category do not (the page comes back unchanged). So closingAfter is sent upstream, while closingBefore and categories are applied locally as the walk proceeds — which means a category walk may read many pages to find its rows; the summary reports how many events it skipped. status and limit are validated loudly upstream (HTTP 400) and refused here first.

5. Half of Kalshi is sports

Open events by category on the day this was built: Sports 6,994, Elections 3,351, Entertainment 709, Politics 643, Financials 621, Economics 552, Climate 207, Science & Tech 142, Crypto 105, … A walk with no category is mostly match markets. Every summary carries categoriesSeen.

Other things measured

  • liquidity is 0 on every market through both endpoints — a dead field upstream. It is emitted as received; openInterest is the real depth signal.
  • There is no server-side sort. sortBy orders the rows a run collected (within maxItems), not the whole exchange.
  • The API tolerated 40 unpaced requests in 11 s. Pages with nested markets are ~3.6 MB; a full open walk is 68 pages.
  • URLs are https://kalshi.com/markets/{series}/{event} in lowercase; the Actor never requests kalshi.com itself (only the API origin).

Output

  • MARKET — ticker, eventTicker, seriesTicker, title, yesSubTitle, noSubTitle, url, status, result, yesBid, yesAsk, noBid, noAsk, lastPrice, previousPrice, impliedProbability, spread, volume, volume24h, openInterest, liquidity, notionalValue, openTime, closeTime, expirationTime, hasClosed, canCloseEarly, earlyCloseCondition, marketType, strikeType, floorStrike, capStrike, customStrike, isMultivariate, rulesPrimary, eventTitle, eventCategory, eventMutuallyExclusive, eventMarketCount, eventUrl, seriesUrl.
  • EVENT (optional) — eventTicker, seriesTicker, title, category, url, mutuallyExclusive, strikeDate, settlementSources, marketCount, outcomes (ticker, label, lastPrice, volume), totalVolume, totalOpenInterest.
  • SEARCH_SUMMARY — one per target: eventsSeen, eventsReturned, marketsReturned, pagesFetched, stoppedReason, filteredOut (category, multivariate, minVolume, closingBefore, statusMismatch), categoriesSeen, closedRows, rowsWithoutQuote.
  • ERROR — invalid_input, bad_request, payload_shape_changed, fetch_failed, with detail.

Known limits

  • Snapshot prices only; order-book depth, trades and candlesticks are on other endpoints of the same API and not fetched.
  • volume24h is 0 on most markets as served by the API.