Kalshi Historical Trades Scraper
Pricing
Pay per event
Kalshi Historical Trades Scraper
Export public Kalshi trade executions with exact prices, quantities, timestamps, taker sides, block flags, and resumable cursors. Filter by ticker or time, then download JSON, CSV, or Excel.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Export public Kalshi historical trades as one clean dataset row per execution.
Use market and time-window filters to build backtesting samples, study traded prices and volume, or refresh an analytics warehouseβwithout a Kalshi login or API key.
This Actor uses Kalshi's structured historical API rather than a browser, preserves exact fixed-point values, and writes a resumable cursor checkpoint after every page.
What does Kalshi Historical Trades Scraper do?
Kalshi Historical Trades Scraper downloads transaction-level records from Kalshi's public historical trade tape.
Each row represents one completed trade, not a market snapshot or an order-book level.
You can:
- π― export trades for one exact market ticker;
- π select an execution-time window;
- π¦ cap an export from one row to one million rows;
- π resume pagination from a saved cursor;
- π΅ analyze numeric yes/no prices and contract quantities;
- π¬ retain source-exact decimal strings for precise calculations;
- π€ download results as JSON, CSV, Excel, XML, or RSS through Apify.
The default input requests only ten records, so you can verify the output quickly before starting a larger backfill.
Who is Kalshi Historical Trades Scraper for?
Quantitative researchers
- Build trade-level samples for prediction-market backtests.
- Measure executed-price distributions and transaction sizes.
- Compare activity across market tickers and time windows.
Prediction-market traders
- Review historical prints for a specific settled contract.
- Identify block trades and aggressive taker behavior.
- Export transaction history into notebooks or spreadsheets.
Forecasters and academics
- Study how market participation evolves before resolution.
- Join execution records with market metadata for event research.
- Preserve reproducible source timestamps and IDs.
Data engineers and analytics teams
- Schedule recurring archive exports on Apify.
- Resume long backfills using the
CHECKPOINTcursor. - Stream clean rows into warehouses, BI tools, or object storage.
Why use this Kalshi trades scraper?
- No authentication: the public Kalshi v2 historical-trades endpoint needs no account, cookie, or API token.
- One execution per row: avoid unpacking mixed market, order-book, and trade entities.
- API-first efficiency: direct HTTP keeps runtime and memory usage low.
- Decimal safety: numeric fields are convenient for charts, while exact strings protect precision-sensitive pipelines.
- Resumable exports: every fetched page updates a key-value-store checkpoint.
- Server-side filtering: ticker and timestamps are sent to Kalshi rather than filtered after a wasteful full download.
- Stable deduplication: trade IDs prevent duplicate rows within a run.
- Apify integrations: schedule runs, trigger webhooks, and connect datasets to thousands of apps.
Choose Kalshi Markets Scraper instead when you need contract titles, status, bid/ask, liquidity, rules, or settlement metadata rather than executions.
What Kalshi trade data can you extract?
| Category | Fields | Meaning |
|---|---|---|
| Identity | tradeId, ticker | Unique execution and market identifiers |
| Time | createdTime | UTC execution timestamp supplied by Kalshi |
| Quantity | count, countExact | Numeric and source-exact contract quantity |
| Prices | yesPrice, yesPriceExact | Executed yes-side dollar price |
| Prices | noPrice, noPriceExact | Executed no-side dollar price |
| Aggressor | takerSide | Side associated with the taker |
| Outcome | takerOutcomeSide | Yes/no outcome selected by the taker |
| Book | takerBookSide | Bid/ask side consumed by the taker |
| Classification | isBlockTrade | Whether Kalshi marks the execution as a block trade |
| Provenance | sourceType, sourceEndpoint | Historical source and public API endpoint |
| Pagination | pageNumber | API page that produced the row |
| Audit | scrapedAt | Timestamp when the Actor saved the row |
Prices are dollar probabilities, typically between 0 and 1.
countExact, yesPriceExact, and noPriceExact preserve the strings returned by Kalshi, such as "53.90" or "0.4400".
How much does it cost to scrape Kalshi historical trades?
This Actor uses pay-per-event pricing.
The pre-launch price is a $0.00025 start fee plus a tiered amount for each saved trade.
| Apify tier | Price per trade |
|---|---|
| Free | $0.000035295 |
| Starter / Bronze | $0.000030691 |
| Scale / Silver | $0.000023939 |
| Business / Gold | $0.000018415 |
| Platinum | $0.000012276 |
| Diamond | $0.000010000 |
Examples at the Free-tier rate:
| Export | Calculation | Estimated charge |
|---|---|---|
| 10 trades | $0.00025 + 10 Γ $0.000035295 | $0.00060295 |
| 100 trades | $0.00025 + 100 Γ $0.000035295 | $0.00377950 |
| 1,000 trades | $0.00025 + 1,000 Γ $0.000035295 | $0.03554500 |
These formula-derived prices preserve at least 30% net margin for measured 10-trade runs and exceed 40% for a representative 100-trade run.
Your Apify plan, dataset retention, and integrations may have separate platform terms.
How to scrape Kalshi historical trades
- Open Kalshi Historical Trades Scraper.
- Keep the prefilled ticker for a quick first test, or paste another exact Kalshi market ticker.
- Set optional earliest and latest execution timestamps.
- Choose the maximum number of trades to save.
- Click Start.
- Preview the dataset while the run is active.
- Export the result as JSON, CSV, Excel, XML, or RSS.
- For a longer continuation, copy
nextCursorfrom theCHECKPOINTkey-value-store record intostartCursor.
A broad export needs only:
{"maxItems": 100,"pageSize": 100}
A market-specific export:
{"ticker": "KXNBAGAME-26MAY23NYKCLE-NYK","maxItems": 500,"pageSize": 500}
A bounded research window:
{"ticker": "KXNBAGAME-26MAY23NYKCLE-NYK","minCreatedTime": "2026-05-20T00:00:00Z","maxCreatedTime": "2026-05-24T00:00:00Z","maxItems": 10000,"pageSize": 1000}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
ticker | string | empty | Exact Kalshi market ticker; normalized to uppercase |
minCreatedTime | ISO 8601 string | empty | Include executions at or after this UTC instant |
maxCreatedTime | ISO 8601 string | empty | Include executions at or before this UTC instant |
maxItems | integer | 100 | Maximum unique trades to save, from 1 to 1,000,000 |
pageSize | integer | 1000 | Trades requested per API page, from 1 to 1,000 |
startCursor | string | empty | Resume token from a previous CHECKPOINT.nextCursor |
If both timestamps are present, minCreatedTime must not be later than maxCreatedTime.
Invalid dates and limits fail before any data request.
Output example
{"tradeId": "ca4c7de7-3606-7118-152c-9a66c804cdc3","ticker": "KXNBAGAME-26MAY23NYKCLE-NYK","createdTime": "2026-05-23T23:59:59.964931Z","count": 53.9,"countExact": "53.90","yesPrice": 0.44,"yesPriceExact": "0.4400","noPrice": 0.56,"noPriceExact": "0.5600","takerSide": "yes","takerOutcomeSide": "yes","takerBookSide": "bid","isBlockTrade": false,"sourceType": "historical","sourceEndpoint": "https://api.elections.kalshi.com/trade-api/v2/historical/trades","pageNumber": 1,"scrapedAt": "2026-07-23T02:30:00.000Z"}
Every dataset item follows the same schema.
The Actor does not mix market metadata, alerts, or error records into the trade dataset.
Cursor checkpoints and resumable backfills
After each API page, the Actor writes CHECKPOINT to the run's default key-value store.
The record contains:
completeβ whether the requested run limit or source pagination ended;nextCursorβ the cursor to provide asstartCursor;savedItemsβ rows saved during this run;pagesFetchedβ pages fetched during this run;- the ticker and time-window inputs;
updatedAtβ the latest checkpoint time.
For task-based recurring runs, the default store can persist between executions.
Copy the cursor only when you intentionally want the next archive page.
Keep the same ticker and time filters when resuming, because Kalshi cursors belong to the original query context.
Decimal precision and data types
Kalshi sends contract counts and prices as fixed-point decimal strings.
JavaScript numbers are useful for charts, filters, and ordinary calculations but are binary floating-point values.
For accounting, reproducible research, or arbitrary-precision decimal libraries, use:
countExactinstead of onlycount;yesPriceExactinstead of onlyyesPrice;noPriceExactinstead of onlynoPrice.
This dual representation avoids forcing every user into one numeric strategy.
Tips for reliable Kalshi data exports
- Start with 10β100 rows and inspect the schema before a large backfill.
- Use a ticker whenever your research concerns one contract.
- Use both time boundaries for reproducible experiments.
- Store
tradeIdas the durable deduplication key downstream. - Preserve timestamps in UTC; convert only in the presentation layer.
- Save the checkpoint outside Apify if a backfill is business-critical.
- Schedule smaller incremental windows instead of repeatedly downloading an entire archive.
- Join trades to market metadata using
ticker. - Expect the historical cutoff to move as Kalshi archives older exchange data.
Kalshi archive coverage and limitations
This Actor reads Kalshi's historical trades endpoint.
Kalshi separates archived trades from the current/live trades endpoint using a platform-managed cutoff.
Therefore:
- the newest live executions may not yet appear in this Actor;
- archive coverage and cutoff timing are controlled by Kalshi;
- a ticker with no archived trades can return an empty dataset;
- upstream fields or enum values may evolve;
- the Actor exports public executions, not private portfolio fills;
- transaction records do not include full market titles or settlement rules.
Use Kalshi Markets Scraper to enrich ticker-level market context.
Integrations for trade research workflows
Kalshi trades β Google Sheets
Schedule a market-specific export and sync rows for manual trade review, pivot tables, or lightweight volume analysis.
Kalshi trades β BigQuery or Snowflake
Use a webhook after each bounded time-window run, deduplicate by tradeId, and append new executions to a warehouse table.
Kalshi trades β Python notebook
Start the Actor through the API, load the dataset with pandas, and compute price, size, side, or block-trade distributions.
Kalshi trades β Slack or Discord
Filter exported rows downstream and alert a research channel when large or block executions occur in a tracked archive window.
Kalshi trades β Make or Zapier
Trigger a scenario when a scheduled Actor run finishes, then route CSV files or summary metrics to storage and reporting tools.
Using the Apify API with Node.js
Install the official client:
$npm install apify-client
Run the Actor and retrieve its dataset:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/kalshi-historical-trades-scraper').call({ticker: 'KXNBAGAME-26MAY23NYKCLE-NYK',maxItems: 100,pageSize: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Using the Apify API with Python
Install the client:
$pip install apify-client
Then run:
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/kalshi-historical-trades-scraper').call(run_input={'ticker': 'KXNBAGAME-26MAY23NYKCLE-NYK','maxItems': 100,'pageSize': 100,})items = client.dataset(run['defaultDatasetId']).list_items().itemsprint(items)
Using the Apify API with cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~kalshi-historical-trades-scraper/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"ticker": "KXNBAGAME-26MAY23NYKCLE-NYK","maxItems": 100,"pageSize": 100}'
After the run succeeds, request dataset items using its defaultDatasetId.
Never put an Apify token in public source code or browser-side JavaScript.
Use Kalshi Historical Trades Scraper with AI agents via MCP
This Actor can be called by AI assistants through Apify's hosted Model Context Protocol integration.
For Claude Code:
$claude mcp add --transport http apify "https://mcp.apify.com?tools=automation-lab/kalshi-historical-trades-scraper"
For Claude Desktop, Cursor, or VS Code, add:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/kalshi-historical-trades-scraper"}}}
Your client will request Apify authentication when needed.
Example prompts:
- βUse
automation-lab/kalshi-historical-trades-scraperto export 100 archived trades for ticker KXNBAGAME-26MAY23NYKCLE-NYK.β - βBuild a Kalshi execution dataset between 2026-05-20 and 2026-05-24, then summarize trade sizes by taker side.β
- βResume my Kalshi historical trade backfill from this checkpoint cursor and save 10,000 more records.β
Is it legal to scrape Kalshi historical trade data?
This Actor accesses a public data endpoint and does not bypass authentication or access private user accounts.
Public availability does not remove every legal or contractual obligation.
You are responsible for:
- following Kalshi's applicable terms and API policies;
- using data for a lawful purpose;
- avoiding attempts to identify private individuals from public records;
- respecting intellectual-property, privacy, financial, and data-retention rules in your jurisdiction;
- securing exported datasets and API credentials.
If you are unsure whether your commercial or regulated use is permitted, obtain qualified legal advice.
Troubleshooting
Why did the dataset contain no trades?
The exact ticker may have no archived executions, the time window may be outside archive coverage, or the records may still be on Kalshi's live endpoint. Remove one filter at a time and run a small test.
Why was my timestamp rejected?
Use a complete ISO 8601 timestamp such as 2026-05-23T12:30:00Z. The earliest timestamp cannot be later than the latest timestamp.
Why did a large export stop before the full archive?
Check the run status and CHECKPOINT record. If nextCursor is present, provide it as startCursor with the same ticker and time filters.
Why do numeric values have matching Exact fields?
The numeric fields are convenient for common analytics. Exact fields preserve Kalshi's fixed-point source strings for decimal-safe processing.
Frequently asked questions
Does this Actor need a Kalshi API key?
No. The Kalshi v2 historical-trades endpoint used by this Actor is publicly accessible without a Kalshi login or API key.
How fast is the scraper?
It requests up to 1,000 trades per API page and uses no browser. Small exports usually complete quickly; total runtime depends on output size, Kalshi response time, and Apify storage writes.
Does it include live trades?
No. This Actor intentionally exports Kalshi's archived historical tape from the v2 endpoint. This creates a clear, reproducible product contract and avoids silently mixing archive and live cutoff behavior.
Can it export every historical trade?
You can increase maxItems and resume with cursors, but actual availability is controlled by Kalshi's archive and API behavior. Use bounded runs for operational reliability.
How are duplicate trades handled?
Within a run, rows are deduplicated by tradeId. For multiple runs, use the same ID as the unique key in your destination.
How does this differ from Kalshi Markets Scraper?
Kalshi Markets Scraper returns one row per contract with metadata and market state. This Actor returns one row per executed transaction with quantity, prices, sides, and execution time.
Other prediction-market scrapers and tools
- Kalshi Markets Scraper β contract metadata, status, prices, liquidity, and rules.
- Kalshi Trader Social Profile Scraper β public trader profile information.
- Kalshi Market Trader Leaderboard Scraper β public market leaderboard data.
- Polymarket Markets Scraper β Polymarket contract and market data.
- Polymarket Leaderboard Scraper β ranked public Polymarket trader data.
- Polymarket Wallet Portfolio Trade History Scraper β wallet positions and transaction history.
Combine execution rows with market metadata only when your workflow requires enrichment; keeping the raw trade tape separate makes ETL and schema evolution simpler.