# Kalshi Trades Scraper & Monitor - Large Trades, Order Book (`neverempty/kalshi-trades-monitor`) Actor

Kalshi Trades as rows: time, market, Yes and No price, contracts, USD amount and taker side. Filter by market, event, series, trade size or time. Optional order book row per market. Monitoring mode returns only trades made since the last run, such as 1,000+ contract trades.

- **URL**: https://apify.com/neverempty/kalshi-trades-monitor.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 trade returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Kalshi Trades Scraper & Monitor - Large Trades, Order Book

Get **Kalshi trades** as rows: when each trade happened, in which market, at what Yes and No price, how many contracts, how many dollars the taker paid and which side the taker took. Filter by market, event, series, trade size or time, add the current **order book** of each market, or switch on **monitoring mode** to get only the trades made since your previous run, for example every trade of 1,000 contracts or more.

It reads Kalshi's own public market-data API (the endpoints Kalshi documents as needing no API key). No login, no proxy, no browser.

### What you get

One row per trade:

| Field | Meaning |
|---|---|
| `createdTime` | When the trade was executed (UTC, milliseconds). `createdTimeRaw` keeps Kalshi's own value with microseconds. |
| `ticker`, `marketTitle`, `marketSubtitle` | The market, its question and the name of its Yes side |
| `eventTicker`, `eventTitle`, `seriesTicker`, `category` | The event and series the market belongs to |
| `yesPrice`, `noPrice` | Trade price of each side in dollars (0.14 = 14 cents; the two add up to 1) |
| `contracts` | Number of contracts (Kalshi allows fractions, for example 33.68) |
| `takerSide`, `takerBookSide` | Side the taker took (`yes` or `no`) and Kalshi's book wording for it (`bid` or `ask`) |
| `takerPrice`, `amountUsd` | Price of the taker's side, and contracts x that price = what the taker paid, before fees |
| `isBlockTrade` | True for trades matched off the book as block trades |
| `marketStatus` | Kalshi's status of the market when the row was written |
| `kalshiUrl` | Page of the market's series on kalshi.com |
| `tradeId` | Kalshi's id of the trade |

With **Add order book rows** switched on, one more row per market (`rowType: "orderbook"`):

| Field | Meaning |
|---|---|
| `bestYesBid`, `bestNoBid` | Highest resting bid on each side |
| `bestYesAsk`, `bestNoAsk` | Implied asks: a Yes ask is 1 minus the best No bid, and the other way round (Kalshi's book holds bids only) |
| `spread` | `bestYesAsk` minus `bestYesBid` |
| `yesBids`, `noBids` | The top price levels, best first, each with `price` and `contracts` |
| `yesBidContractsShown`, `yesBidUsdShown` (and the `no` pair) | Size of the returned levels in contracts and in dollars |

An empty side gives `null` for its best price, never 0.

### Typical uses

- **Follow large trades**: set *Minimum amount (USD)* to 1000 (or *Minimum contracts*), switch on monitoring mode and run it every few minutes. Each run returns only the new large trades.
- **Trade tape of one market or event**: give a market ticker or an event ticker and get its trades, newest first.
- **Flow by side**: filter on *Taker side* and *Minimum amount (USD)* to see where money is going.
- **Liquidity check**: add order book rows to see spread and depth of the markets that just traded.

### Input

- **Market / event / series tickers**: any mix. Leave all empty to read the trades of every market. Tickers are the codes in Kalshi's API, such as `KXFEDDECISION-26OCT-H0` (market), `KXFEDDECISION-26OCT` (event) or `KXFEDDECISION` (series). Lower case is accepted.
- **Minimum contracts**, **Minimum amount (USD)**, **Taker side**: filters applied to every trade.
- **Last hours**, or **Since** and **Until**: time window (UTC). *Since* includes its second, *Until* does not.
- **Maximum trade rows**: 1,000 by default.
- **Add order book rows**, **Order book levels**, **Maximum order book rows**.
- **Monitoring mode** and **Reset monitoring memory**.

#### Example: large trades of the last hour

```json
{ "minAmountUsd": 1000, "lastHours": "1", "maxResults": 500 }
```

#### Example: watch one event for new trades, with the order book

```json
{ "eventTickers": ["KXFEDDECISION-26OCT"], "monitoringMode": true, "includeOrderbook": true }
```

### Monitoring mode

Run the same input on a schedule.

- The **first run** only remembers the starting point. It returns no trade row and charges nothing.
- **Later runs** return only trades made after the previous run that match your filters, oldest first.
- A run that finds nothing new returns one free row with the status `no-new-trades-since-last-run` and charges one small scan check.
- If a run stops at *Maximum trade rows* or at the maximum charge you set, the trades it could not return are **not** marked as returned. The next run returns them.
- If Kalshi cannot be read to the remembered point, the run returns nothing, charges nothing and keeps the starting point, so the next run reads the same stretch again.
- Trades are compared by Kalshi's trade id, so several trades with the same timestamp are neither dropped nor repeated.
- The memory is kept per set of tickers and filters. A different filter starts its own memory.

### Things to know before you rely on it

- **Volume.** Across all markets Kalshi printed about 1,000 trades every 8 seconds when this was measured (October 2026, a weekday afternoon in the US). Reading every market for a whole day means millions of trades. One run reads at most 1,000,000 trades; if that is not enough to reach the start of your window or the remembered point, the run says so in a free row with `truncated: true`, and those older trades are not returned. Run monitoring more often or name markets.
- **Contracts are not dollars.** Many trades are in combination (parlay) markets, whose tickers start with `KXMVE` and whose contracts often cost a cent or less: 1,000 contracts there can be a few dollars. To follow large money, filter on *Minimum amount (USD)*; `amountUsd` is on every row.
- **Series with many markets.** A series with more than 100 markets is read from the all-markets feed and filtered, which needs a time window or monitoring mode. Without one you get a free `too-many-markets` row and nothing is read.
- **Unknown tickers** come back as free rows (`unknown-market`, `unknown-event`, `unknown-series`). Kalshi's trade endpoint answers an unknown ticker with an empty list, so this Actor checks every ticker first instead of reporting "no trades".
- **Market details.** Titles come from a second lookup. If it fails, the trade row is still returned with `marketTitle: null` and `detailsNote` says why. Event details are looked up for at most 300 events per run.
- **Old markets.** Kalshi moves long-settled markets to a historical archive; their trades are not returned here.
- **`amountUsd`** is contracts x the price of the taker's side. It is not Kalshi's fee and not the payout.
- When Kalshi refuses or cannot be read, you get a free row with the status `blocked`, `unreadable` or `incomplete`. A failure is never reported as "no trades".

### Pricing

Pay per result:

- **Trade row** returned.
- **Order book row** returned (only when you switch it on).
- **Scan check**: only for a monitoring run that compared and found nothing new.

Free: the first monitoring run, every row that explains why something was not returned, and runs that could not read Kalshi.

### Related Actors

- [Kalshi Markets Scraper](https://apify.com/neverempty/kalshi-markets-scraper): every Kalshi market with prices, volume and open interest, and a monitoring mode for price moves.
- [Kalshi Weather Markets API](https://apify.com/neverempty/kalshi-weather-markets-api): Kalshi temperature and weather markets.

### Notes

This is an unofficial tool. It is not affiliated with, endorsed by or sponsored by Kalshi. It reads public market data only: no account data, no orders, no personal information. Nothing here is trading, investment or legal advice, and the data may be delayed or incomplete. You are responsible for how you use the data and for following Kalshi's terms and the rules that apply to you.

### Thanks for using this Actor

We build these tools for people who run them every day, and we improve them from what users tell us.

- **Missing a field, or need another filter?** Tell us in the **Issues** tab. If the data is there, we add it.
- **Found a bug or a wrong value?** Post the run ID in the **Issues** tab. Wrong data is the thing we fix first.

If this Actor saved you time, a short review helps other people find it.

# Actor input Schema

## `tickers` (type: `array`):

Kalshi market tickers, one per line (for example KXFEDDECISION-26OCT-H0). Each market is checked first; a ticker Kalshi does not know comes back as a free row that says so. Leave all three ticker fields empty to read the trades of every market.

## `eventTickers` (type: `array`):

Kalshi event tickers, one per line (for example KXFEDDECISION-26OCT). Trades of every market of the event are returned.

## `seriesTickers` (type: `array`):

Kalshi series tickers, one per line (for example KXFEDDECISION or KXBTCD). Trades of every market of the series are returned. A series with more than 100 markets needs a time filter (Last hours or Since) or monitoring mode.

## `minContracts` (type: `integer`):

Only trades of at least this many contracts. Leave empty for no minimum. Contracts of combination (parlay) markets often cost under one cent, so for large trades by money use the dollar minimum below.

## `minAmountUsd` (type: `integer`):

Only trades where the taker paid at least this many dollars (contracts x the price of the taker's side), for example 1000 for large trades only. Leave empty for no minimum.

## `takerSide` (type: `string`):

Only trades where the taker took this side.

## `lastHours` (type: `string`):

Only trades made in the last this many hours (for example 1, 24 or 0.5). Use this or Since, not both. Not used in monitoring mode.

## `since` (type: `string`):

Only trades made at or after this time, for example 2026-10-05 or 2026-10-05T14:00:00Z (UTC). Not used in monitoring mode.

## `until` (type: `string`):

Only trades made before this time (UTC). Not used in monitoring mode.

## `maxResults` (type: `integer`):

Stop after this many trade rows. Without monitoring the newest trades come first; in monitoring mode the oldest new trades come first and the rest come at the next run.

## `includeOrderbook` (type: `boolean`):

Also return one row per market with the current order book: best Yes and No bid, the implied asks, the spread, the top price levels and their size. Covers the markets you named and the markets of the returned trades (in monitoring mode only the markets of the returned trades).

## `orderbookDepth` (type: `integer`):

How many price levels per side to return in an order book row.

## `maxOrderbookMarkets` (type: `integer`):

Read the order book of at most this many markets in one run.

## `monitoringMode` (type: `boolean`):

Run the same input on a schedule: the first run only remembers the starting point (no rows, no charge); every later run returns only trades made since the previous run that match the filters. Combine with a minimum amount or minimum contracts to follow large trades.

## `resetMonitoringState` (type: `boolean`):

Forget the remembered starting point for these filters and start again from now.

## Actor input object example

```json
{
  "minAmountUsd": 1000,
  "takerSide": "any",
  "lastHours": "1",
  "maxResults": 1000,
  "includeOrderbook": false,
  "orderbookDepth": 10,
  "maxOrderbookMarkets": 50,
  "monitoringMode": false,
  "resetMonitoringState": false
}
```

# Actor output Schema

## `results` (type: `string`):

One row per Kalshi trade: time, market ticker and title, event, Yes and No price, contracts, the amount the taker paid in USD, taker side and a Kalshi URL; with the order book switch, one more row per market with the best bids, implied asks, spread and top price levels. In monitoring mode only trades made since the previous run. Unknown tickers, runs with no matching trade, refusals and limits come back as free rows that say why.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "minAmountUsd": 1000,
    "lastHours": "1"
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/kalshi-trades-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "minAmountUsd": 1000,
    "lastHours": "1",
}

# Run the Actor and wait for it to finish
run = client.actor("neverempty/kalshi-trades-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "minAmountUsd": 1000,
  "lastHours": "1"
}' |
apify call neverempty/kalshi-trades-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neverempty/kalshi-trades-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/iYxbcQQ0lqfO03XJ3/builds/za1hPeWAbB72Stsne/openapi.json
