Kalshi Historical Trades Scraper avatar

Kalshi Historical Trades Scraper

Pricing

Pay per event

Go to Apify Store
Kalshi Historical Trades Scraper

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

Stas Persiianenko

Maintained by Community

Actor 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 CHECKPOINT cursor.
  • 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?

CategoryFieldsMeaning
IdentitytradeId, tickerUnique execution and market identifiers
TimecreatedTimeUTC execution timestamp supplied by Kalshi
Quantitycount, countExactNumeric and source-exact contract quantity
PricesyesPrice, yesPriceExactExecuted yes-side dollar price
PricesnoPrice, noPriceExactExecuted no-side dollar price
AggressortakerSideSide associated with the taker
OutcometakerOutcomeSideYes/no outcome selected by the taker
BooktakerBookSideBid/ask side consumed by the taker
ClassificationisBlockTradeWhether Kalshi marks the execution as a block trade
ProvenancesourceType, sourceEndpointHistorical source and public API endpoint
PaginationpageNumberAPI page that produced the row
AuditscrapedAtTimestamp 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 tierPrice 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:

ExportCalculationEstimated 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

  1. Open Kalshi Historical Trades Scraper.
  2. Keep the prefilled ticker for a quick first test, or paste another exact Kalshi market ticker.
  3. Set optional earliest and latest execution timestamps.
  4. Choose the maximum number of trades to save.
  5. Click Start.
  6. Preview the dataset while the run is active.
  7. Export the result as JSON, CSV, Excel, XML, or RSS.
  8. For a longer continuation, copy nextCursor from the CHECKPOINT key-value-store record into startCursor.

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

ParameterTypeDefaultDescription
tickerstringemptyExact Kalshi market ticker; normalized to uppercase
minCreatedTimeISO 8601 stringemptyInclude executions at or after this UTC instant
maxCreatedTimeISO 8601 stringemptyInclude executions at or before this UTC instant
maxItemsinteger100Maximum unique trades to save, from 1 to 1,000,000
pageSizeinteger1000Trades requested per API page, from 1 to 1,000
startCursorstringemptyResume 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 as startCursor;
  • 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:

  • countExact instead of only count;
  • yesPriceExact instead of only yesPrice;
  • noPriceExact instead of only noPrice.

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 tradeId as 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 os
from apify_client import ApifyClient
client = 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().items
print(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-scraper to 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.”

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

Combine execution rows with market metadata only when your workflow requires enrichment; keeping the raw trade tape separate makes ETL and schema evolution simpler.