Kalshi Scraper — Prediction Markets, Prices & Volume avatar

Kalshi Scraper — Prediction Markets, Prices & Volume

Pricing

from $0.70 / 1,000 result items

Go to Apify Store
Kalshi Scraper — Prediction Markets, Prices & Volume

Kalshi Scraper — Prediction Markets, Prices & Volume

Kalshi prediction markets for AI agents: search open markets by keyword or series, get yes/no prices, bid/ask, volume, open interest, close dates and rules. Kalshi is the US CFTC-regulated exchange — complements Polymarket. No API key.

Pricing

from $0.70 / 1,000 result items

Rating

0.0

(0)

Developer

Samat Makatov

Samat Makatov

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Structured data from Kalshi, the US CFTC-regulated prediction-market exchange: search open, closed or settled markets by keyword, category, series or ticker; get Yes/No prices in cents, bid/ask, volume, open interest, close and settlement times, rules and settlement sources; optionally attach the live order book, OHLC candles and recent trades. One row per market, per event, or per series (the full 14,000-series catalogue).

No API key, no proxy, no browser — Kalshi's public trade API v2 is read without authentication. Made by Yadroo — an independent tool, not affiliated with or endorsed by Kalshi; pairs with our Polymarket actor for cross-venue comparisons.

Use cases

  • Macro odds feed — category=Economics events (Fed decision, CPI, jobs, GDP) into a model, a Slack digest or a research note.
  • Cross-venue arbitrage / calibration — run this and polymarket-markets on the same question and compare implied probabilities.
  • Watchlist monitoring — tickers=[…] with includeOrderBook on a schedule; alert on priceChange or spread.
  • Event-driven trading research — includeCandles (1m/1h/1d) and includeTrades for markets around a known catalyst.
  • Settlement datasets — status=settled with a closeFrom/closeTo window to collect results for backtests.
  • Catalogue discovery — mode=series with category or tags to find the right series tickers before automating anything.

Input

FieldTypeDefaultNotes
modemarkets | events | seriesmarketsRow granularity.
querystring—Keywords (AND, case-insensitive) matched in event/market titles, tickers and category. Kalshi has no search API: the actor scans all events of the status; with mode=markets every market of a series whose title, tags or category match counts too (e.g. bitcoin → the hourly KXBTC series).
categoryenum—One of the 20 Kalshi categories, exactly as listed in Reference; other values are refused by Apify before the run.
seriesTickerstring—e.g. KXFED, KXBTC, KXCPI (letter case does not matter). A ticker Kalshi does not have fails the run with a message instead of returning nothing.
eventTickerstring—e.g. KXFED-27APR — one event and all its markets. An unknown event fails the run with a message.
tickersstring[]—Exact market tickers (open, closed or settled), mode=markets. Overrides query, category, seriesTicker, eventTicker and status; the min*/price/close-date filters still apply. A ticker Kalshi does not know comes back as a row with found: false (billed like any row) and is named in the status message.
tagsstring[]—mode=series only: filter by series tags (e.g. Inflation), case-insensitive.
statusopen | closed | settled | unopenedopenMarket/event status.
sortByenumvolume24hvolume24h, volume, openInterest, liquidity, closeTime (soonest), openTime (newest), yesPrice, priceChange (largest absolute move vs previous price). Events can be sorted by volume24h, volume, openInterest and closeTime only, and Kalshi currently sends no liquidity figure; in those cases the run sorts by 24h volume and says so in its status. mode=series keeps the catalogue order.
maxItems (limit)1–100050Rows returned. The run also stops at your maximum cost per run.
closeFrom, closeTo, closingWithinHoursdate / integer—Close-time window: YYYY-MM-DD (UTC; a bare closeTo date counts through the end of that day) or an ISO date-time. Anything else is refused before the run. With both closeTo and closingWithinHours, the earlier end wins.
minVolume24h, minVolume, minOpenInterestinteger—Thresholds in contracts ($1 notional each).
yesPriceMin, yesPriceMax0–100 (cents)0 / 100Price band, e.g. 5–95 to drop near-certain markets.
includeCombosbooleanfalseInclude multivariate parlay markets (KXMVECROSS…), excluded by default.
includeOrderBook / orderBookDepthboolean / 1–50false / 5Resting Yes and No bids in cents + contracts, best bid/ask, spread.
includeCandles / candlePeriod / candleLookbackDaysboolean / 1m·1h·1d / 1–365false / 1h / 7OHLC (cents), volume, open interest per period + summary.
includeTrades / tradesLimitboolean / 1–1000false / 20Latest public trades.
includeRulesbooleantrueSet false to drop rules text.
fieldsstring[]—Keep only these top-level fields, in your order. The row id (ticker / eventTicker / seriesTicker by mode) and fetchedAt are always kept and come first, unless you list them elsewhere. Letter case, spaces, _ and - are forgiven (open_interest → openInterest, Volume 24h → volume24h; reported in the status); names the mode does not have are skipped with a note and a suggestion; orderBook / candles / trades need their include… switch and are skipped with a note without it; the run fails if none of the listed fields remains.

Reference

Categories (category) — series count, 2026-09

CategorySeriesCategorySeries
Sports3,638Companies176
Entertainment2,537World143
Politics2,307Health96
Elections1,735Commodities81
Financials959Social52
Economics780Transportation38
Mentions442Exotics14
Climate and Weather389AI5
Science and Technology333Business1
Crypto273Education1

Off-list values of the enum fields (mode, category, status, sortBy, candlePeriod) are refused by Apify before the run (HTTP 400, nothing is charged); use the values exactly as listed here.

Statuses

statusEvent filter sent to KalshiMarket statuses kept
openopenactive, open
closedclosedclosed, determined
settledsettledsettled, finalized
unopenedunopenedinitialized, unopened, inactive

Series frequencies (frequency in mode=series)

custom, one_off, annual, monthly, weekly, daily, hourly, fifteen_min, quarterly.

Most common series tags (tags, 230 total)

Soccer, Music, US Elections, Football, Basketball, Awards, Congress, Primaries, Music charts, Trump, KPIs, Companies, International elections, International, Movies, Rotten Tomatoes, Television, Baseball, Earnings, SCOTUS & courts, AI, Tennis, Senate, House, Product launches, Markets, Growth, Inflation, Golf, Jobs & Economy, Video games, Esports, Grammys, Oil and energy, Hurricanes, Governor, Indices, Foreign Exchange, Housing, Hockey, CEOs, Oscars, Motorsport, Daily temperature, Cricket, Interest Rates, BTC, Compute, Olympics, Fed. Run mode=series to list the rest.

Handy series tickers

KXFED / KXFEDDECISION (Fed rate), KXRATECUTCOUNT, KXCPI / KXCPIYOY, KXPAYROLLS, KXU3 (unemployment), KXGDP, KXBTC (hourly BTC), KXBTCD (daily BTC), KXETH, KXAAAGASW (US gas prices), KXHIGHNY (NYC temperature), KXOAIANTH (OpenAI vs Anthropic IPO), KXNBA, KXNFLGAME.

Examples

Most traded open markets (default)

{}

Economics odds table

{ "mode": "events", "category": "Economics", "maxItems": 30, "minOpenInterest": 1000 }

Fed watchlist with order book, daily candles and trades

{ "tickers": ["KXFED-27APR-T4.25", "KXFED-27APR-T4.00"], "includeOrderBook": true, "includeCandles": true, "candlePeriod": "1d", "candleLookbackDays": 30, "includeTrades": true, "tradesLimit": 50 }

Bitcoin markets resolving in the next 6 hours

{ "query": "bitcoin", "closingWithinHours": 6, "sortBy": "closeTime", "maxItems": 100, "includeRules": false }

Biggest movers with real liquidity

{ "sortBy": "priceChange", "minVolume24h": 500, "yesPriceMin": 5, "yesPriceMax": 95, "maxItems": 50 }

Settled Politics markets of Q3 2026 for a backtest

{ "status": "settled", "category": "Politics", "closeFrom": "2026-07-01", "closeTo": "2026-09-30", "maxItems": 1000, "fields": ["ticker", "eventTitle", "subtitle", "result", "lastPrice", "volume", "closeTime"] }

Discover inflation series

{ "mode": "series", "category": "Economics", "tags": ["Inflation"], "maxItems": 100 }

Output

mode=markets, one item per contract (trimmed; with fields, ticker and fetchedAt come first, then your fields in your order):

{
"ticker": "KXFED-27APR-T4.25",
"eventTicker": "KXFED-27APR",
"seriesTicker": "KXFED",
"category": "Economics",
"eventTitle": "Fed funds rate after Apr 2027 meeting?",
"eventSubtitle": "On Apr 28, 2027",
"title": "Fed funds rate ≥ 4.25%?",
"subtitle": "4.25% or above",
"status": "active",
"marketType": "binary",
"strikeType": "greater", "floorStrike": 4.25, "capStrike": null,
"yesPrice": 44, "noPrice": 64, "impliedProbability": 44,
"yesBid": 36, "yesAsk": 44, "noBid": 56, "noAsk": 64, "spread": 8,
"lastPrice": 45, "previousPrice": 40, "priceChange": 5,
"volume": 1234.5, "volume24h": 30, "openInterest": 2054.01, "liquidity": 0,
"openTime": "2025-10-06T19:22:55Z", "closeTime": "2027-04-28T17:55:00Z", "expirationTime": "2027-05-05T18:05:00Z", "hoursToClose": 5490.2,
"canCloseEarly": true, "result": null,
"settlementSources": [{ "name": "Federal Reserve Board of Governors", "url": "https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm" }],
"rulesPrimary": "If the upper bound of the target federal funds range…",
"mutuallyExclusive": false,
"orderBook": { "bestYesBid": 36, "bestYesAsk": 44, "spread": 8, "yesBidContracts": 9, "noBidContracts": 247.56, "yesBids": [{ "priceCents": 36, "contracts": 1 }], "noBids": [{ "priceCents": 56, "contracts": 20.31 }] },
"candles": { "period": "1d", "lookbackDays": 14, "count": 14, "first": 35, "last": 45, "min": 16, "max": 45, "change": 10, "volume": 120, "candles": [{ "t": "2026-09-05T20:00:00.000Z", "open": 35, "high": 37, "low": 35, "close": 37, "volume": 30, "openInterest": 2054.01 }] },
"trades": [{ "id": "0722cf53-…", "time": "2026-09-11T14:41:03Z", "yesPrice": 44, "noPrice": 56, "contracts": 26.6, "takerSide": "yes", "isBlockTrade": false }],
"url": "https://kalshi.com/markets/kxfed/kxfed-27apr",
"sourceUrl": "https://api.elections.kalshi.com/trade-api/v2/markets/KXFED-27APR-T4.25",
"fetchedAt": "2026-09-12T23:41:38.779Z"
}
FieldMeaning
yesPrice / noPriceBest ask for Yes / No in cents (what you'd pay); falls back to last trade. impliedProbability = yesPrice.
yesBid/yesAsk/noBid/noAsk/spreadTop of book in cents.
lastPrice / previousPrice / priceChangeLast trade vs Kalshi's previous reference price.
volume, volume24h, openInterestContracts ($1 each). liquidity is Kalshi's own dollar figure; Kalshi currently sends 0 or nothing (null) for it.
strikeType / floorStrike / capStrikeFor numeric ranges (greater, less, between, custom).
resultyes / no once settled, else null.
settlementSources, rulesPrimary/SecondaryWhat resolves the market.
orderBookKalshi books only list bids; bestYesAsk = 100 − best No bid.

A tickers entry Kalshi does not know comes back as one row (billed like any row; fields does not narrow it):

{ "ticker": "NOTAREALTICKER-000", "found": false, "reason": "Kalshi returned no market for this ticker (open, closed and settled markets are all looked up): check the spelling; tickers look like KXFED-27APR-T4.25.", "sourceUrl": "https://api.elections.kalshi.com/trade-api/v2/markets/NOTAREALTICKER-000", "fetchedAt": "2026-10-02T19:11:41.830Z" }

mode=events rows: eventTicker, seriesTicker, category, title, subtitle, mutuallyExclusive, strikeDate, strikePeriod, settlementSources, marketCount, volume24h, volume, openInterest, closeTime, hoursToClose, topMarket {ticker, title, yesPrice}, markets[] {ticker, title, subtitle, status, yesPrice, yesBid, yesAsk, volume24h, openInterest, closeTime, result}, url, sourceUrl, fetchedAt.

mode=series rows: seriesTicker, title, category, tags, frequency, feeType, feeMultiplier, settlementSources, contractUrl, contractTermsUrl, additionalProhibitions, lastUpdated, url, sourceUrl, fetchedAt.

Use it from code / agents

Apify API (curl)

curl -X POST "https://api.apify.com/v2/acts/yadroo~kalshi-markets/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"mode":"events","category":"Economics","maxItems":20}'

JavaScript (apify-client)

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/kalshi-markets').call({ tickers: ['KXFED-27APR-T4.25'], includeOrderBook: true });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Python (apify-client)

from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yadroo/kalshi-markets").call(run_input={"query": "bitcoin", "closingWithinHours": 6, "sortBy": "closeTime"})
items = client.dataset(run["defaultDatasetId"]).list_items().items

MCP — connect https://mcp.apify.com and call the yadroo/kalshi-markets tool with the same JSON; the input schema is self-describing.

Pricing

Pay per event: $0.001 per run start + $0.001 per item. Default run (50 markets) ≈ $0.051; a 1,000-row settlement dataset ≈ $1.001; a 5-ticker watchlist with full enrichment ≈ $0.006. Enrichment adds requests, not per-item cost.

Store discounts: Bronze −10 %, Silver −20 %, Gold and above −30 % on the item price; the start event is the same on every plan. Platform usage is included.

Maximum cost per run is respected: the run saves only the rows your limit pays for (enrichment runs only for those), then ends with the status "Stopped at your spending limit: N rows delivered".

Limits & FAQ

  • Freshness — live at fetch time; fetchedAt on every row. Prices are top-of-book at that moment.
  • Search depth — Kalshi has no search or sort endpoint, so a markets or events run reads every event of the chosen status (~14,000 open events as of 2026-10, up to 20,000) and returns the top maxItems of everything it read — the default run {} included. A full scan of open events (~72 requests, ~130,000 markets) takes from about 10 s to 1.5 minutes, depending on how fast Kalshi answers (measured 2026-10-03). When the scan stops at its cap (possible with closed or settled), up to 60 series matching the keyword are then fetched directly. Only seriesTicker, eventTicker or tickers make the scan smaller; category, query and the filters are applied to the events read.
  • Rate limits — Kalshi's public tier allows ~20 reads/s; the actor stays far below it and backs off on 429/5xx. An unreachable API fails the run after a few retries (with the reason in the status) instead of looping.
  • Errors — enum values off the list are refused by Apify before the run starts (no charge), and so are close dates that are not dates. Inputs the actor checks itself (a price band with min > max, fields of which none can be filled, an unknown seriesTicker or eventTicker) fail the run at once with a message that names the field. Unknown tickers become found: false rows.
  • Timeouts — a run near its timeout stops starting new requests, saves the rows it has read (ranked among what was scanned), and ends SUCCEEDED with "Stopped before the run timeout: N rows saved". Markets it had no time to enrich are saved with orderBook / candles / trades = null, and the status says how many. A full scan of open events takes up to about 1.5 minutes; 1,000 markets with all three enrichments take several minutes, which the default timeout (15 min) covers.
  • Summary — every run writes a SUMMARY record (rows saved, events scanned, tickers not found, input notes, enrichment failures) and ends with a status message that says what happened.
  • Combos — KXMVECROSS… parlay markets are hidden unless includeCombos=true.
  • Prices in cents — 0–100; a yesPrice of 100 means the book is one-sided (no Yes asks) or settled-in-progress.
  • Roadmap — settlement-result history per series, cross-venue matching with Polymarket, webhook-friendly diff mode.

Made by Yadroo. Not affiliated with, endorsed by or sponsored by Kalshi; "Kalshi" is used only to name the public data source. Related actors: polymarket-markets, us-treasury-yields, fx-rates, google-news-search.