# Kalshi Scraper — Prediction Markets, Prices & Volume (`yadroo/kalshi-markets`) Actor

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.

- **URL**: https://apify.com/yadroo/kalshi-markets.md
- **Developed by:** [Samat Makatov](https://apify.com/yadroo) (community)
- **Categories:** AI, News, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 result items

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 Scraper — Prediction Markets, Prices, Order Books & Candles

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; pairs with our [Polymarket actor](https://apify.com/yadroo/polymarket-markets) 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

| Field | Type | Default | Notes |
|---|---|---|---|
| `mode` | `markets` | `events` | `series` | `markets` | Row granularity. |
| `query` | string | — | Keywords (AND, case-insensitive) matched in event/market titles, tickers and category. Kalshi has no search API: the actor matches series titles/tags first (fetches those series directly), then scans events. |
| `category` | enum | — | One of the 20 Kalshi categories (see Reference); case-insensitive, unambiguous partials accepted. |
| `seriesTicker` | string | — | e.g. `KXFED`, `KXBTC`, `KXCPI`. |
| `eventTicker` | string | — | e.g. `KXFED-27APR` — one event and all its markets. |
| `tickers` | string\[] | — | Exact market tickers (any status); overrides everything else. |
| `tags` | string\[] | — | `mode=series` only: filter by series tags (e.g. `Inflation`). |
| `status` | `open` | `closed` | `settled` | `unopened` | `open` | Market/event status. |
| `sortBy` | enum | `volume24h` | `volume24h`, `volume`, `openInterest`, `liquidity`, `closeTime` (soonest), `openTime` (newest), `yesPrice`, `priceChange` (largest absolute move vs previous price). |
| `maxItems` (`limit`) | 1–1000 | `50` | Rows returned. |
| `closeFrom`, `closeTo`, `closingWithinHours` | date / integer | — | Close-time window. |
| `minVolume24h`, `minVolume`, `minOpenInterest` | integer | — | Thresholds in contracts ($1 notional each). |
| `yesPriceMin`, `yesPriceMax` | 0–100 (cents) | `0` / `100` | Price band, e.g. 5–95 to drop near-certain markets. |
| `includeCombos` | boolean | `false` | Include multivariate parlay markets (`KXMVECROSS…`), excluded by default. |
| `includeOrderBook` / `orderBookDepth` | boolean / 1–50 | `false` / `5` | Resting Yes and No bids in cents + contracts, best bid/ask, spread. |
| `includeCandles` / `candlePeriod` / `candleLookbackDays` | boolean / `1m`·`1h`·`1d` / 1–365 | `false` / `1h` / `7` | OHLC (cents), volume, open interest per period + summary. |
| `includeTrades` / `tradesLimit` | boolean / 1–1000 | `false` / `20` | Latest public trades. |
| `includeRules` | boolean | `true` | Set `false` to drop rules text. |
| `fields` | string\[] | — | Keep only these top-level fields (ids and `fetchedAt` always kept). |

### Reference

#### Categories (`category`) — series count, 2026-09

| Category | Series | Category | Series |
|---|---|---|---|
| Sports | 3,638 | Companies | 176 |
| Entertainment | 2,537 | World | 143 |
| Politics | 2,307 | Health | 96 |
| Elections | 1,735 | Commodities | 81 |
| Financials | 959 | Social | 52 |
| Economics | 780 | Transportation | 38 |
| Mentions | 442 | Exotics | 14 |
| Climate and Weather | 389 | AI | 5 |
| Science and Technology | 333 | Business | 1 |
| Crypto | 273 | Education | 1 |

#### Statuses

| `status` | Event filter sent to Kalshi | Market statuses kept |
|---|---|---|
| `open` | `open` | `active` |
| `closed` | `closed` | `closed`, `determined` |
| `settled` | `settled` | `settled`, `finalized` |
| `unopened` | `unopened` | `initialized`, `unopened` |

#### 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)**

```json
{}
```

**Economics odds table**

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

**Fed watchlist with order book, daily candles and trades**

```json
{ "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**

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

**Biggest movers with real liquidity**

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

**Settled Politics markets of Q3 2026 for a backtest**

```json
{ "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**

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

### Output

`mode=markets`, one item per contract (trimmed):

```json
{
  "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"
}
```

| Field | Meaning |
|---|---|
| `yesPrice` / `noPrice` | Best ask for Yes / No in cents (what you'd pay); falls back to last trade. `impliedProbability` = `yesPrice`. |
| `yesBid`/`yesAsk`/`noBid`/`noAsk`/`spread` | Top of book in cents. |
| `lastPrice` / `previousPrice` / `priceChange` | Last trade vs Kalshi's previous reference price. |
| `volume`, `volume24h`, `openInterest` | Contracts ($1 each). `liquidity` is Kalshi's dollar figure. |
| `strikeType` / `floorStrike` / `capStrike` | For numeric ranges (`greater`, `less`, `between`, `custom`). |
| `result` | `yes` / `no` once settled, else `null`. |
| `settlementSources`, `rulesPrimary/Secondary` | What resolves the market. |
| `orderBook` | Kalshi books only list bids; `bestYesAsk` = 100 − best No bid. |

`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)**

```bash
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`)**

```js
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`)**

```python
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.

### 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 endpoint. A keyword first selects matching series (up to 60, fetched precisely), then the actor scans open events (~14,000 as of 2026-09, up to 20,000) — a full scan takes 30–45 s. `category` alone always needs the full scan; add `seriesTicker` or `query` for speed.
- **Rate limits** — Kalshi's public tier allows ~20 reads/s; the actor stays far below it and backs off on 429/5xx. Unreachable API fails after 4 attempts instead of looping.
- **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**. Related actors: [polymarket-markets](https://apify.com/yadroo/polymarket-markets), [us-treasury-yields](https://apify.com/yadroo/us-treasury-yields), [fx-rates](https://apify.com/yadroo/fx-rates), [google-news-search](https://apify.com/yadroo/google-news-search).

# Actor input Schema

## `mode` (type: `string`):

`markets`: one row per tradable contract (e.g. 'Fed funds rate ≥ 4.25% after Apr 2027 meeting'). `events`: one row per event grouping its contracts (odds table). `series`: the Kalshi catalogue (14,000 series) with category, tags, frequency and settlement sources — use it to discover tickers.

## `query` (type: `string`):

Keywords (all must match, case-insensitive) in event title/subtitle, market title, category, series and event tickers. Kalshi has no search API, so the actor scans events (≤ 12,000) and filters locally.

## `category` (type: `string`):

Kalshi category (as on kalshi.com). Case-insensitive; partial values like 'climate' are accepted when unambiguous.

## `seriesTicker` (type: `string`):

Restrict to one series, e.g. KXFED (Fed decision), KXBTC (Bitcoin hourly), KXCPI, KXNBA. Discover tickers with mode=series.

## `eventTicker` (type: `string`):

One event and all its markets, e.g. KXFED-27APR. Overrides query/category.

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

Exact market tickers to fetch (any status), e.g. \['KXFED-27APR-T4.25']. Cheapest way to monitor a watchlist. Overrides everything else.

## `tags` (type: `array`):

Filter series by Kalshi tags, e.g. \['Inflation','Interest Rates']. Case-insensitive. See README for the tag list.

## `status` (type: `string`):

Market/event status. Ignored when `tickers` is set.

## `sortBy` (type: `string`):

Ordering of results.

## `maxItems` (type: `integer`):

Maximum rows to return. Billing is per item.

## `limit` (type: `integer`):

Deprecated — same as maxItems (maxItems wins).

## `closeFrom` (type: `string`):

Only markets whose trading close time is on/after this date (ISO).

## `closeTo` (type: `string`):

Only markets closing on/before this date.

## `closingWithinHours` (type: `integer`):

Shortcut for closeTo = now + N hours.

## `minVolume24h` (type: `integer`):

Drop markets with less 24h volume (Kalshi counts contracts, $1 notional each).

## `minVolume` (type: `integer`):

Drop markets with less lifetime volume.

## `minOpenInterest` (type: `integer`):

Drop thin markets.

## `yesPriceMin` (type: `integer`):

E.g. 5 excludes markets priced under 5¢.

## `yesPriceMax` (type: `integer`):

E.g. 95 excludes near-certain markets.

## `includeCombos` (type: `boolean`):

Kalshi's multivariate combo markets (KXMVECROSS…) are excluded by default — they are synthetic parlays, not standalone questions.

## `includeOrderBook` (type: `boolean`):

Adds `orderBook`: resting Yes and No bids (cents, contracts), best bid/ask and spread. One extra request per market.

## `orderBookDepth` (type: `integer`):

Levels per side.

## `includeCandles` (type: `boolean`):

Adds `candles` (OHLC in cents, volume, open interest per period) plus first/last/min/max/change summary.

## `candlePeriod` (type: `string`):

Candle size. Kalshi supports exactly these three.

## `candleLookbackDays` (type: `integer`):

How far back to fetch candles.

## `includeTrades` (type: `boolean`):

Adds `trades`: latest public trades (time, yes/no price in cents, contracts, taker side).

## `tradesLimit` (type: `integer`):

How many recent trades to include.

## `includeRules` (type: `boolean`):

Set false to drop `rulesPrimary`/`rulesSecondary` and keep rows compact.

## `fields` (type: `array`):

Keep only the listed top-level fields (ticker/eventTicker/seriesTicker id and fetchedAt are always kept).

## Actor input object example

```json
{
  "mode": "markets",
  "query": "Fed",
  "status": "open",
  "sortBy": "volume24h",
  "maxItems": 50,
  "includeCombos": false,
  "includeOrderBook": false,
  "orderBookDepth": 5,
  "includeCandles": false,
  "candlePeriod": "1h",
  "candleLookbackDays": 7,
  "includeTrades": false,
  "tradesLimit": 20,
  "includeRules": true
}
```

# Actor output Schema

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

No description

# 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 = {
    "query": "Fed"
};

// Run the Actor and wait for it to finish
const run = await client.actor("yadroo/kalshi-markets").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 = { "query": "Fed" }

# Run the Actor and wait for it to finish
run = client.actor("yadroo/kalshi-markets").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 '{
  "query": "Fed"
}' |
apify call yadroo/kalshi-markets --silent --output-dataset

```

## MCP server setup

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

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/QAqAsgurPBI3feRQ6/builds/jrau84pfExKEKjtdV/openapi.json
