Kalshi Scraper · Event Contracts, Markets, Prices & Volume
Pricing
from $1.30 / 1,000 kalshi prediction market records
Kalshi Scraper · Event Contracts, Markets, Prices & Volume
Scrape Kalshi prediction markets, event contracts, option pricing, order book quotes, trading volume, open interest, and resolution rules. Export structured JSON, CSV, or Excel data.
Pricing
from $1.30 / 1,000 kalshi prediction market records
Rating
0.0
(0)
Developer
Tarek Etman
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
6 days ago
Last modified
Categories
Share

Kalshi Scraper · Event Contracts, Markets, Prices & Volume
Kalshi Scraper extracts public prediction markets, event contracts, option pricing, bid/ask order book quotes, 24-hour and total trading volume, open interest, and official resolution rules from Kalshi. Built for quantitative traders, financial analysts, policy researchers, and automated AI data pipelines requiring structured market intelligence.
Maintained by reapX. Every row cites the Apify run that produced it — nothing is inferred, modelled or filled in, and a field absent from the source is absent from the row. The extracted archive for this source is browsable at reapx.dev/data/kalshi-scraper/ and mirrored as an open dataset on Hugging Face and Kaggle. Questions: reapxdev@proton.me
Features & Use Cases
- Quantitative Forecasting: Collect real-time probability estimates for Federal Reserve rate cuts, inflation prints, and election outcomes.
- Order Book & Pricing Analysis: Monitor spread mechanics (
yesBidDollarsvsyesAskDollars) and liquidity depth across prediction markets. - Historical Event Research: Extract settled contracts with verified outcomes (
result) to benchmark market forecast accuracy. - Automated Datasets: Feed live prediction data directly into financial dashboards, machine learning models, or LLM agent prompts.
⬇️ Input
Every field is described here exactly as the Actor reads it. Run it with the prefilled input and it returns real rows without any further configuration.
| Field | Type | Required | Prefilled | What it does |
|---|---|---|---|---|
category | string | no | - | Filter Kalshi prediction markets by market category topic (e.g. Financials, Elections, Economics, Politics, Sports, Crypto). |
status | string | no | - | Filter contracts by lifecycle status, using the exchange's own filter vocabulary: open, closed, settled, unopened. |
seriesTicker | string | no | - | Filter prediction markets by specific Kalshi Series Ticker code (e.g. KXFED, KXNFLWINS, KXELONMARS, KXTSLAA). |
eventTicker | string | no | - | Return every contract belonging to one Kalshi event (e.g. KXFEDDECISION-26SEP). An event is the question; each contract under it is one outcome or strike, so this is how you get a whole... |
tickers | string | no | - | Extract specific prediction market tickers by exact ticker identifier code (e.g. KXFED-24DEC31-T1.5). |
minCloseTs | integer | no | - | Filter markets closing on or after this Unix epoch timestamp in seconds (e.g. 1767225600 for Jan 1, 2026). |
maxCloseTs | integer | no | - | Filter markets closing on or before this Unix epoch timestamp in seconds (e.g. 1798761600 for Jan 1, 2027). |
maxMarkets | integer | no | 200 | Maximum number of Kalshi prediction market contract records to scrape and output. |
What empty means, and what a larger value costs
The two questions an input table normally does not answer. Both columns are read off this Actor's own code and its own price list.
| Field | Left empty | Turned up |
|---|---|---|
category | Leave empty to extract prediction markets across all domain categories. | Selecting a category restricts extraction focus, reducing total execution duration and compute consumption. |
status | Leave empty to include contracts at any stage of life. | The value you FILTER on and the value that comes BACK on the row are different vocabularies - a contract accepted by status=open is written to the dataset as active, and a brand... |
seriesTicker | Leave empty to include contracts from all active market series. | Specifying a series ticker isolates a single event series, resulting in faster runs and targeted dataset results. |
eventTicker | Leave empty to search by category, series or status instead. | The narrowest filter the exchange offers - a single event returns a handful of rows in one request, measured at 5 rows for the September Fed decision ladder. |
tickers | Leave empty to perform broader category or status searches. | Providing exact market tickers directly fetches matching contract records without pagination overhead. |
minCloseTs | Leave empty for no lower bound on market close date. | Setting a minimum close timestamp filters out older or past-closing prediction contracts. |
maxCloseTs | Leave empty for no upper bound on market close date. | Setting a maximum close timestamp restricts extraction to near-term or specific timeframe contracts. |
maxMarkets | No bound is applied | Each row returned is one $0.002 charge, so this field is your cost cap as well as your row cap. At the ceiling of 10,000 rows that is $20.00 at list price. |
⬆️ Output
One row per record, as JSON, CSV, Excel or XML, and through the API. Every field below is on every row this Actor writes; a field the source did not return is empty rather than guessed.
| Field | Type | What it gives you | Example |
|---|---|---|---|
slug | string | Unique URL-friendly market ticker identifier on Kalshi platform. | "KXFED-24DEC31-T1.5" |
title | string | Primary contract title or prediction question statement. | "Fed interest rate target range in December 2024?" |
subtitle | string | Outcome subtitle or candidate option detail statement. | "Target rate between 4.25% and 4.50%" |
eventTicker | string | Event container ticker symbol identifying the broader event group. | "KXFED-24DEC" |
seriesTicker | string | Series ticker symbol identifying the overarching recurring market series. | "KXFED" |
marketType | string | Contract structure classification (e.g., binary, scalar, custom). | "binary" |
status | string | Lifecycle status as the exchange reports it on the row: active, initialized, closed, settled or finalized. Note this... | "open" |
category | string | Domain category topic under which the contract is cataloged. | "Financials" |
openTime | string | ISO timestamp when market trading opened. | "2024-01-15T14:00:00Z" |
closeTime | string | ISO timestamp when market trading closes. | "2024-12-31T20:00:00Z" |
expirationTime | string | ISO timestamp when the contract officially expires. | "2024-12-31T20:00:00Z" |
createdTime | string | ISO timestamp when the market contract record was created. | "2024-01-10T12:00:00Z" |
updatedTime | string | ISO timestamp when market contract record was last updated. | "2026-08-03T18:19:26Z" |
lastPriceDollars | number | Most recent executed trade price in USD (0.00 to 1.00 per contract). | 0.45 |
yesBidDollars | number | Highest current bid quote price for Yes outcome in USD. | 0.44 |
yesAskDollars | number | Lowest current offer quote price for Yes outcome in USD. | 0.46 |
noBidDollars | number | Highest current bid quote price for No outcome in USD. | 0.54 |
noAskDollars | number | Lowest current offer quote price for No outcome in USD. | 0.56 |
previousPriceDollars | number | Previous closing or reference price in USD. | 0.43 |
volume24hFp | number | Number of contract units traded in past 24 hours. | 1450.0 |
volumeFp | number | Cumulative contract unit volume traded over market lifetime. | 89200.0 |
openInterestFp | number | Total active open contract positions. | 12400.0 |
notionalValueDollars | number | Payout value per winning contract unit in USD. | 1.0 |
result | string | Official settlement result value (e.g. yes, no, or empty if unresolved). | "yes" |
canCloseEarly | boolean | Whether the market contract permits early close upon event resolution. | true |
isProvisional | boolean | Whether the contract parameters are marked provisional. | false |
strikeType | string | Classification of strike threshold structure (custom, range, threshold). | "custom" |
rulesPrimary | string | Official primary resolution rules and source agency terms. | "Official target range announced by the Federal Open Mark... |
rulesSecondary | string | Secondary resolution criteria and disclaimer terms. | "Kalshi is an FCM registered with the CFTC." |
settlementTimerSeconds | integer | Delay window in seconds applied before settlement finality. | 3600 |
sourceUrl | string | Direct canonical web page URL for this market contract on Kalshi. | "https://kalshi.com/markets/KXFED-24DEC31-T1.5" |
expectedExpirationTime | string | When the exchange expects the contract to expire, which is earlier than expirationTime whenever a market can settle... | "2026-08-05T04:40:00Z" |
Dataset views
The dataset ships with named views, so the Output tab, the API and any agent reading this Actor get the columns that matter for a job without asking for all of them.
Market Overview (?view=overview) - 9 columns: slug, title, category, status, lastPriceDollars, volumeFp, openInterestFp, closeTime, sourceUrl
| Column | Header |
|---|---|
slug | Ticker |
title | Market |
category | Category |
status | Status |
lastPriceDollars | Last Price ($) |
volumeFp | Volume |
openInterestFp | Open Interest |
closeTime | Closes |
sourceUrl | Kalshi Page |
Order Book Quotes & Pricing (?view=pricing) - 10 columns: slug, title, lastPriceDollars, yesBidDollars, yesAskDollars, noBidDollars, noAskDollars, previousPriceDollars, volume24hFp, notionalValueDollars
| Column | Header |
|---|---|
slug | Ticker |
title | Market |
lastPriceDollars | Last ($) |
yesBidDollars | Yes Bid ($) |
yesAskDollars | Yes Ask ($) |
noBidDollars | No Bid ($) |
noAskDollars | No Ask ($) |
previousPriceDollars | Previous ($) |
volume24hFp | Volume 24h |
notionalValueDollars | Notional ($) |
Contract Structure & Rules (?view=marketDetails) - 9 columns: slug, eventTicker, seriesTicker, marketType, strikeType, result, canCloseEarly, rulesPrimary, rulesSecondary
| Column | Header |
|---|---|
slug | Ticker |
eventTicker | Event |
seriesTicker | Series |
marketType | Type |
strikeType | Strike Type |
result | Result |
canCloseEarly | Can Close Early |
rulesPrimary | Primary Rule |
rulesSecondary | Secondary Rule |
Lifecycle Timestamps (?view=timing) - 8 columns: slug, status, openTime, closeTime, expectedExpirationTime, expirationTime, settlementTimerSeconds, updatedTime
| Column | Header |
|---|---|
slug | Ticker |
status | Status |
openTime | Opened |
closeTime | Closes |
expectedExpirationTime | Expected Expiry |
expirationTime | Expiry |
settlementTimerSeconds | Settlement Timer (s) |
updatedTime | Last Updated |
Fetch one directly:
GET https://api.apify.com/v2/datasets/{datasetId}/items?view=overview&format=csv
One real row
Unedited, from this Actor's own most recent successful run.
{"slug": "KXFEDDECISION-26SEP-C25","title": "Will the Federal Reserve Cut rates by 25bps at their September 2026 meeting?","subtitle": "Cut 25bps","eventTicker": "KXFEDDECISION-26SEP","seriesTicker": "KXFEDDECISION","marketType": "binary","status": "active","category": "","openTime": "2025-09-29T14:00:00Z","closeTime": "2026-09-16T17:59:00Z","expirationTime": "2026-12-16T18:01:00Z","expectedExpirationTime": "2026-09-16T18:05:00Z","createdTime": "2025-09-26T15:30:59.234134Z","updatedTime": "2026-04-09T14:06:58.042679Z","lastPriceDollars": 0.01,"yesBidDollars": 0.01,"yesAskDollars": 0.02,"noBidDollars": 0.98,"noAskDollars": 0.99,"previousPriceDollars": 0.02,"volume24hFp": 26980.43,"volumeFp": 563161.61,"openInterestFp": 526189.77,"notionalValueDollars": 1,"result": "","canCloseEarly": true,"isProvisional": false,"strikeType": "custom","rulesPrimary": "If the Federal Reserve does a Cut of 25bps on September 16, 2026, then the market resolves to Yes.","rulesSecondary": "This market is mutually exclusive. Therefore, if the Federal Reserve hikes by 50bps, the 50bps market will resolve to Yes and the 25bps market will resolve to No. Only one bucket, at maximum, can resolve to Yes. Note 4/28/25: For the markets beginning after the May meeting, if a scheduled FOMC meeting is canceled and does not occur on its scheduled date, then the strike for \"Fed maintains rate\" will resolve to Yes and all others will resolve to No.","settlementTimerSeconds": 297,"sourceUrl": "https://kalshi.com/markets/KXFEDDECISION-26SEP-C25"}
🧪 Worked examples
Every block below is an input this Actor has actually run, with the row count of the run that produced it. Copy one straight into the Console.
One event, the whole strike ladder
{"eventTicker": "KXFEDDECISION-26SEP","maxMarkets": 50}
That run returned 5 rows in 3s.
Kalshi Elections Prediction Markets
Extract active and historical election prediction contracts on Kalshi.
{"category": "Elections","maxMarkets": 200}
That run returned 200 rows.
Federal Reserve Interest Rate Markets
Extract Federal Reserve rate decision prediction market contracts.
{"seriesTicker": "KXFED","maxMarkets": 200}
That run returned 109 rows.
Active Open Financial Prediction Markets
Extract active open interest rate and financial prediction contracts.
{"category": "Financials","status": "open","maxMarkets": 200}
That run returned 200 rows.
All Currently Open Kalshi Markets
Extract active open prediction markets currently trading on Kalshi.
{"status": "open","maxMarkets": 200}
That run returned 200 rows.
Active Weather Markets Closing Late 2026
Extract open climate event contracts closing in late 2026.
{"category": "Climate and Weather","status": "open","minCloseTs": 1782864000,"maxMarkets": 200}
That run returned 200 rows.
How it works
The endpoint it calls
Plain HTTP against the source's own public API. No headless browser, no login, no key of yours:
https://api.elections.kalshi.com/trade-api/v2
The exchange's own public v2 trade API. Read-only market data needs no key and no account; nothing here touches an order, a position or a balance.
The paging it does
Cursor paging, up to 200 contracts per request, following the cursor the exchange returns until your Maximum Markets Limit is reached or a short page says the result set is exhausted.
Every filter is passed to the exchange rather than applied afterwards, so a filtered run reads only the pages it needs: category, status, series_ticker, event_ticker, an explicit list of tickers, and the min_close_ts / max_close_ts window. Prices arrive as decimal dollar strings and are converted once, on the way in, so lastPriceDollars is a number you can average without parsing.
The rate it holds
Every request is retried up to 3 times, with the wait doubling between attempts, and HTTP 429, 500, 502, 503, 504 are treated as retryable rather than fatal. Each request times out at 20s.
One request at a time, retried up to 3 times with the wait doubling between attempts, and a 400 is never retried because the exchange has already told you the query itself is wrong.
What you are charged
One market-scraped event per row written to the dataset, $0.002 at list price. Charged once per complete Kalshi prediction market contract extracted and written to the default dataset. Empty runs or unreachable API responses are never charged.
| Apify plan tier | Price per row |
|---|---|
| Free | $0.002 |
| Bronze | $0.0018 |
| Silver | $0.0015 |
| Gold | $0.0013 |
| Platinum | $0.001 |
| Diamond | $0.0008 |
Apify platform usage is absorbed, not passed on, so the row price is the whole bill.
Why the dataset is correct at every moment
Rows are written and charged one at a time, so a run stopped by your budget cap keeps everything it had already collected. Market data is a snapshot by nature: every row carries updatedTime from the exchange and the run's own timestamp, so two runs of the same task are directly comparable rather than merely similar.
⚠️ Error reference
Derived from this Actor's own exception classes and the HTTP branches in its client. The run always reports what happened in its status message, so you never need the log to know what you got.
| Raised | When | What the run does |
|---|---|---|
BadQuery | Raised when Kalshi API rejects input query parameters (HTTP 400). | Run fails with: Kalshi API rejected query parameters: |
SourceBlocked | Raised when Kalshi API is unreachable or returns severe HTTP errors (403, 5xx). | Run fails with: Kalshi API unreachable: |
HTTP statuses the client actually handles
| Status | Handling |
|---|---|
429 | Retried with backoff. The run continues if a later attempt succeeds. |
500 | Retried with backoff. The run continues if a later attempt succeeds. |
502 | Retried with backoff. The run continues if a later attempt succeeds. |
503 | Retried with backoff. The run continues if a later attempt succeeds. |
504 | Retried with backoff. The run continues if a later attempt succeeds. |
400 | The source rejected the query itself, so retrying it cannot help; the input is at fault. |
403 | The source refused the request. Treated as a block, not a bug in your input. |
What each outcome costs
| Outcome | Rows | Charged |
|---|---|---|
| Run finished | Everything the source returned for your filters | One market-scraped per row |
| Nothing matched your filters | 0 | Nothing |
| Source refused or was unreachable | Whatever was already collected | Only the rows you got |
| Budget cap reached mid-run | The rows collected before the cap | Only those rows |
Status messages this Actor can end on, verbatim from its own source:
- Run budget of $ cannot cover a single record at $
- Kalshi API rejected query parameters:
- No Kalshi prediction markets found matching criteria. Zero charged.
- Pushed
❓ FAQ
How are prices represented in the dataset?
All price fields (lastPriceDollars, yesBidDollars, yesAskDollars, noBidDollars, noAskDollars) are expressed in USD per contract unit, bounded between $0.00 and $1.00.
Does this actor require Kalshi account API keys?
No. The scraper accesses public market listings via Kalshi's unauthenticated public trade API.
How frequently is market data updated?
Data is fetched live directly from Kalshi at the moment of execution.
How many rows can one run return?
Up to 10,000, set by the maximum-results field, which is also your cost cap. Raise it for a bigger slice, or set a Max total charge on the run and the Actor will stop cleanly when it gets there.
Can I get just some of the columns?
Yes. The dataset ships named views (overview, pricing, marketDetails, timing); add ?view=<name> to the dataset items URL, or pick one in the Output tab, and you get that view's columns in JSON, CSV or Excel.
Can an agent call this?
Yes, through Apify's MCP server at https://mcp.apify.com with nothing to integrate on our side: search-actors finds it, fetch-actor-details returns the input schema above, and call-actor runs it.
Will the dataset still be there next month?
Yes. The run names its own default dataset at startup, and Apify keeps named storages past the retention window that deletes unnamed ones, so the run id in a row you cited a year ago still resolves.
Is the data complete?
It is exactly what the source returned for your filters. Nothing is inferred, modelled or filled in, and a field the source did not return is empty rather than guessed. The run's status message tells you what you got, so you never have to read the log to find out.
💬 Your feedback
Have suggestions or need custom market data fields? Reach out to the maintainers at reapxdev@proton.me.
Disclaimer: Unofficial - not affiliated with Kalshi. Collects public data only. reapx. Contact reapxdev@proton.me.