# Kalshi Markets Scraper - Prediction Market Prices & Odds (`confidential_gnat/kalshi-markets-scraper`) Actor

Scrapes Kalshi prediction markets: yes/no prices, implied probability, spread, volume, open interest, close times, rules, series tags and optional orderbook and recent trades. Search by keyword, category, series, event or Kalshi URL.

- **URL**: https://apify.com/confidential_gnat/kalshi-markets-scraper.md
- **Developed by:** [ActorFlow](https://apify.com/confidential_gnat) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

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 Markets Scraper - Prediction Market Prices & Odds

**Scrape prediction markets from Kalshi (kalshi.com)**: yes/no bid and ask prices, **implied probability**, spread, last price, volume, 24h volume, open interest, close and expiration times, resolution rules, category, series tags and, optionally, the live **orderbook** and recent **trades**. Export the results as **JSON, CSV or Excel**, or call the actor as an **API**. Paste a Kalshi market or category URL, or type a keyword, press Start, and get clean **Kalshi odds data**.

**Target website:** [kalshi.com](https://kalshi.com)

### ✨ Features of this Kalshi markets scraper

- **Prediction market extraction** — every market of an event with prices in dollars, implied probability, spread, volume, open interest, dates, rules and settlement sources.
- **Search by keyword, category, series or event** — match event and market titles (for example *bitcoin*, *fed*, *trump*), pick a category such as Politics or Crypto, or pass Kalshi series and event tickers.
- **Status and volume filters** — open, closed, settled or any events, and a minimum traded volume.
- **Orderbook and trades** — optional yes/no bid levels with quantities and the most recent trades of each market.
- **Pagination support** — keeps paging through all Kalshi events until Max items is reached.
- **Incremental runs, no repeat charges** — with a cache project name, markets you already scraped are skipped, so scheduled runs return only newly listed markets.
- **Proxy support** — optional Apify Proxy, off by default.
- **No browser required** — plain HTTP requests keep runs fast and cheap.

### 🚀 How to scrape Kalshi markets in 5 steps

1. [Sign up](https://apify.com/sign-up) for a free Apify account — includes **$5 monthly credit**.
2. Open the actor page and click **Try for free**.
3. Fill in the **Input** fields (a Kalshi URL, keyword, category, series or event ticker is required).
4. Click **Start** and wait for the run to complete.
5. Download results from the **Output** tab in JSON, CSV, or Excel format.

You can also run this actor via the [Apify API](https://docs.apify.com/api/v2) or integrate it directly into your workflows using [Zapier](https://zapier.com/apps/apify), [Make](https://www.make.com/), or [n8n](https://n8n.io/).

### 💰 Kalshi scraper pricing

This actor uses **pay-per-result** billing: you pay for each market saved to the dataset.

- New Apify accounts include **$5 of free monthly credit**.
- The actor uses plain HTTP requests, so it costs significantly less to run than browser-based scrapers.
- The proxy is disabled by default; leaving it off keeps runs cheapest.
- Markets skipped by the cache are not charged.

### 🔧 Kalshi scraper input configuration

| Field | Type | Required | Default | Description |
| ----- | ---- | -------- | ------- | ----------- |
| Kalshi URLs (`startUrls`) | array | — | `kalshi.com/category/crypto` (prefill) | Kalshi market pages or category pages. |
| Search keywords (`searchQueries`) | array | — | — | Keywords matched against event and market titles. Each keyword is a separate search. |
| Cache project name (`cacheProjectName`) | string | — | — | Same name on every run returns only new markets; cached markets are skipped and not charged. Records get `changeType: new`. |
| Max markets per search (`maxItems`) | integer | — | `5` | Maximum markets saved for each URL, keyword, category, series or event. |
| Categories (`categories`) | array | — | — | Kalshi categories, for example Politics, Economics, Crypto, Sports, Climate and Weather. |
| Series tickers (`seriesTickers`) | array | — | — | Series tickers such as `KXFED` or `KXHIGHNY`. |
| Event tickers (`eventTickers`) | array | — | — | Event tickers such as `KXELONMARS-99`. |
| Event status (`status`) | string | — | `open` | `open`, `closed`, `settled` or `any`. Does not apply to event tickers. |
| Minimum volume (`minVolume`) | integer | — | `0` | Skip markets with lower total traded volume (contracts). |
| Include orderbook (`includeOrderbook`) | boolean | — | `false` | Add yes/no bid levels with quantities. One extra request per market. |
| Orderbook depth (`orderbookDepth`) | integer | — | `10` | Price levels per side; 0 returns all. |
| Recent trades per market (`tradesLimit`) | integer | — | `0` | Add up to this many latest trades (max 1000). 0 turns it off. |
| Max concurrency (`maxConcurrency`) | integer | — | `5` | Parallel requests (Kalshi allows about 20 per second). |
| Proxy configuration (`proxyConfiguration`) | object | — | no proxy | Works without a proxy. |

![Kalshi markets scraper input form with the Start URLs and Max items fields marked 1 and 2](https://i.postimg.cc/yYwVS71k/image.png)

The numbered markers in the screenshot show the two fields most runs need:

1. **Start URLs** — paste a Kalshi series, event or category page.
2. **Max items** — how many markets to save for each URL.

**Supported URL types:**

- Series: `https://kalshi.com/markets/kxelonmars`
- Event: `https://kalshi.com/markets/kxelonmars/elon-mars/kxelonmars-99`
- Category: `https://kalshi.com/category/crypto`

### 📦 Kalshi scraper output data

Each market is one dataset item with the fields `id`, `ticker`, `eventTicker`, `seriesTicker`, `title`, `subtitle`, `yesSubTitle`, `noSubTitle`, `eventTitle`, `eventSubtitle`, `seriesTitle`, `category`, `tags`, `frequency`, `marketType`, `status`, `result`, `yesBid`, `yesAsk`, `noBid`, `noAsk`, `lastPrice`, `previousPrice`, `impliedProbability`, `spread`, `yesBidSize`, `yesAskSize`, `volume`, `volume24h`, `openInterest`, `notionalValue`, `strikeType`, `floorStrike`, `capStrike`, `mutuallyExclusive`, `canCloseEarly`, `createdTime`, `openTime`, `closeTime`, `expectedExpirationTime`, `expirationTime`, `latestExpirationTime`, `occurrenceTime`, `updatedTime`, `settlementValue`, `expirationValue`, `earlyCloseCondition`, `rulesPrimary`, `rulesSecondary`, `settlementSources`, `contractUrl`, `url`, `scrapedAt`, plus `orderbook` and `recentTrades` when switched on and `changeType` when caching is on. Prices are in US dollars (0 to 1, equal to the probability), volumes and open interest in contracts. The dataset has **1 view**, **Overview**, a table of ticker, market, outcome, category, status, prices, probability, volume, open interest, close time and page link.

`occurrenceTime` is when the real-world event happens, `expirationValue` is the value the market settled on (for example the Bitcoin price), and `earlyCloseCondition` describes when the market can close early.

`impliedProbability` is the midpoint of the yes bid and ask when both sides are quoted, otherwise the last traded price.

**Output at a glance:**

| Market | Yes bid | Yes ask | Probability | Volume | Closes |
| ------ | ------- | ------- | ----------- | ------ | ------ |
| [Bitcoin above $130,000 by Oct 29, 2026](https://kalshi.com/markets/kxbtcprice/will-bitcoin-hit-price-target-by-date/kxbtcprice-130000) | 0.00 | 0.03 | 0.03 | 1,136 | 2026-10-29 |
| [Bitcoin above $130,000 by Nov 26, 2026](https://kalshi.com/markets/kxbtcprice/will-bitcoin-hit-price-target-by-date/kxbtcprice-130000) | 0.01 | 0.02 | 0.015 | 4,528 | 2026-11-26 |
| [Bitcoin above $130,000 by Dec 24, 2026](https://kalshi.com/markets/kxbtcprice/will-bitcoin-hit-price-target-by-date/kxbtcprice-130000) | 0.02 | 0.07 | 0.045 | 1,945 | 2026-12-24 |
| [Bitcoin above $130,000 by Jan 21, 2027](https://kalshi.com/markets/kxbtcprice/will-bitcoin-hit-price-target-by-date/kxbtcprice-130000) | 0.02 | 0.07 | 0.045 | 1,643 | 2027-01-21 |
| [Bitcoin above $130,000 by Feb 18, 2027](https://kalshi.com/markets/kxbtcprice/will-bitcoin-hit-price-target-by-date/kxbtcprice-130000) | 0.03 | 0.10 | 0.065 | 274 | 2027-02-18 |

**Sample output (raw JSON):**

```json
[
    {
        "id": "KXBTCPRICE-130000-26OCT29",
        "ticker": "KXBTCPRICE-130000-26OCT29",
        "eventTicker": "KXBTCPRICE-130000",
        "seriesTicker": "KXBTCPRICE",
        "title": "Will Bitcoin be above $130,000 by Oct 29, 2026 at 10:00 AM ET?",
        "subtitle": "By Oct 29, 2026",
        "yesSubTitle": "By Oct 29, 2026",
        "noSubTitle": "By Oct 29, 2026",
        "eventTitle": "When will Bitcoin cross $130k?",
        "eventSubtitle": "When will Bitcoin cross $130k?",
        "seriesTitle": "will Bitcoin hit price target by date",
        "category": "Crypto",
        "tags": [
            "Bitcoin",
            "Crypto",
            "BTC"
        ],
        "frequency": "one_off",
        "marketType": "binary",
        "status": "active",
        "result": null,
        "yesBid": 0,
        "yesAsk": 0.03,
        "noBid": 0.97,
        "noAsk": 1,
        "lastPrice": 0.03,
        "previousPrice": 0.03,
        "impliedProbability": 0.03,
        "spread": 0.03,
        "yesBidSize": 0,
        "yesAskSize": 3000,
        "volume": 1136.34,
        "volume24h": 554,
        "openInterest": 1026.34,
        "notionalValue": 1,
        "strikeType": "greater",
        "floorStrike": 130000,
        "capStrike": null,
        "mutuallyExclusive": false,
        "canCloseEarly": true,
        "createdTime": "2026-09-22T18:25:49.693726Z",
        "openTime": "2026-09-22T19:00:00Z",
        "closeTime": "2026-10-29T14:00:00Z",
        "expectedExpirationTime": "2027-07-08T14:00:00Z",
        "expirationTime": "2026-11-28T14:00:00Z",
        "latestExpirationTime": "2026-11-28T14:00:00Z",
        "occurrenceTime": "2026-10-29T14:00:00Z",
        "updatedTime": "2026-09-22T19:00:01.239547Z",
        "settlementValue": null,
        "expirationValue": null,
        "earlyCloseCondition": "This market will close and expire early if Bitcoin crosses the specified price threshold.",
        "rulesPrimary": "If the Bitcoin spot price according to the CF Bitcoin Real-Time Index is above $130000 starting Sep 22, 2026 and before Oct 29, 2026 at 10:00 AM ET, then the market resolves to Yes.",
        "rulesSecondary": "The market resolves based on the CF Bitcoin Real-Time Index (BRTI) using a trimmed mean calculation. The resolution value is calculated by taking all BRTI values for each minute from market issuance until the specified time on the target date, removing the top 20% and bottom 20% of values, then averaging the remaining 60% of values. If the BRTI crosses the threshold at any point during the measurement period (triggering early expiration), the market immediately resolves. If no data is available at the expiration time, the market resolves to No. The market can resolve early if Bitcoin definitively crosses the threshold before the target date and time.",
        "settlementSources": [
            "CF Benchmarks"
        ],
        "contractUrl": "https://assets.kalshi.com/regulatory/product-certifications/BTCPRICE.pdf",
        "url": "https://kalshi.com/markets/kxbtcprice/will-bitcoin-hit-price-target-by-date/kxbtcprice-130000",
        "scrapedAt": "2026-10-15T16:22:31.801Z"
    }
]
```

With **Include orderbook** and **Recent trades** switched on, each item also gets:

```json
{
    "orderbook": { "yes": [{ "price": 0.07, "quantity": 2219.66 }, { "price": 0.08, "quantity": 512.38 }], "no": [{ "price": 0.87, "quantity": 1989.3 }, { "price": 0.88, "quantity": 11.48 }] },
    "recentTrades": [{ "tradeId": "313f39f0-39fc-a54e-215b-14314652dac4", "createdTime": "2026-10-15T06:37:43.773176Z", "takerSide": "yes", "yesPrice": 0.11, "noPrice": 0.89, "count": 2 }]
}
```

### 🐍 How to scrape Kalshi with Python, JavaScript or the API

Run the actor programmatically with the official Apify clients. Replace `<YOUR_API_TOKEN>` with the token from your [Apify Console](https://console.apify.com/account/integrations).

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run = client.actor("confidential_gnat/kalshi-markets-scraper").call(run_input={
    "searchQueries": ["bitcoin"],
    "maxItems": 20,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript** (`npm install apify-client`):

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

const run = await client.actor('confidential_gnat/kalshi-markets-scraper').call({
    searchQueries: ['bitcoin'],
    maxItems: 20,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**cURL** — start a run and wait for the dataset:

```bash
curl -X POST "https://api.apify.com/v2/acts/confidential_gnat~kalshi-markets-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries": ["bitcoin"], "maxItems": 20}'
```

### 💡 What you can use Kalshi market data for

- Tracking market-implied probabilities for elections, Fed decisions, inflation, weather or crypto prices
- Arbitrage and comparison against Polymarket, sportsbooks or other prediction markets
- Building time series of odds, volume and open interest with scheduled runs
- Feeding forecasting models, dashboards and news alerts with crowd probabilities
- Finding newly listed markets every day with the cache

Traders, quant researchers, journalists, data scientists and forecasting teams in finance, media and politics typically use this data.

### ⚠️ Kalshi scraper limitations and known issues

- **Keyword and category searches scan all events** — Kalshi has no server-side text or category search, so the actor pages through all events (about 15,000 open events, roughly 75 pages) and filters titles and categories. Rare keywords can take up to a minute; series and event tickers are fastest.
- **Combo (parlay) markets** — multivariate combo markets are not included.
- **Market page link** — `url` is built from the series, its title and the event ticker; Kalshi routes by the tickers, so the slug may differ from the one on the site.
- **Open events list only active markets** — with status `open`, markets of an open event that are already closed are skipped; use `any` to keep them.

### ❓ Kalshi scraper FAQ

#### Can I scrape Kalshi legally?

The actor only reads public market data that Kalshi publishes for everyone, without logging in or touching any account. Scraping publicly available data is generally considered lawful (see *hiQ Labs v. LinkedIn*), but you are responsible for complying with Kalshi's Terms of Service and applicable laws.

#### What data does the Kalshi scraper return?

Every market has its ticker, titles, category, series tags, yes/no bid and ask, last price, implied probability, spread, volume, open interest, dates, result and rules. Turn on **Include orderbook** for bid levels and **Recent trades per market** for the latest trades.

#### How many Kalshi markets can I scrape from one search?

`maxItems` limits the number of markets **per URL, keyword, category, series or event**, not for the whole run. There is no depth limit: the actor pages through every Kalshi event until Max items is reached.

#### Do I need a proxy to scrape kalshi.com?

No. The actor works without a proxy by default, which keeps runs cheapest. Turn on Apify Proxy only if you get blocked.

#### How do I scrape Kalshi odds with Python?

Use the Python example above: call the actor with `ApifyClient`, then iterate over the dataset items of the finished run.

#### Can I run this Kalshi scraper on a schedule?

Yes. Use Apify Schedules to record odds over time. Set a **Cache project name** if you only want newly listed markets: markets already saved under that name are skipped, not charged, and new ones get `changeType: new`.

#### What formats can I export Kalshi data in?

JSON, CSV, Excel, XML and RSS, either from the **Output** tab or through the Apify API.

#### Why does a keyword search take longer than a series search?

Kalshi offers no text search for events, so the actor reads all events page by page and keeps the matching ones. Use series or event tickers when you know them for the fastest runs.

### 🔗 Other actors you may find useful

| Scraper | Description |
| ------- | ----------- |
| [🎲 Action Network Odds & Public Betting Scraper](https://apify.com/confidential_gnat/action-network-odds-scraper) | Sportsbook odds, public betting splits, line movement and sharp-money signals from Action Network. |
| [📉 Nasdaq Short Interest Scraper](https://apify.com/confidential_gnat/nasdaq-short-interest-scraper) | Short interest history for any Nasdaq-listed stock or ETF: settlement date, short shares and days to cover. |
| [📰 Google News AI Scraper](https://apify.com/confidential_gnat/google-news-ai-scraper) | Google News articles by keyword, with optional full article text and AI summaries. |
| [💬 Sentiment Analysis Using Jev](https://apify.com/confidential_gnat/sentiment-analysis) | Classifies texts as positive, negative, neutral or mixed, or into your own custom labels. |
| [✍️ Substack Scraper](https://apify.com/confidential_gnat/substack-newsletter-scraper) | Substack posts and comments by keyword, publication or post URL: title, author, date and full text. |

### 💬 Support & contact

If you encounter any issues or have questions, please [open an issue](https://apify.com/confidential_gnat/kalshi-markets-scraper/issues/open) or reach out via the [Apify Community Forum](https://community.apify.com/).

You can also find more of our actors on the [Actor Flow](https://apify.com/confidential_gnat) page.

# Actor input Schema

## `startUrls` (type: `array`):

Kalshi market pages (for example https://kalshi.com/markets/kxelonmars or https://kalshi.com/markets/kxelonmars/elon-mars/kxelonmars-99) or category pages (for example https://kalshi.com/category/crypto).

## `searchQueries` (type: `array`):

Keywords matched against event and market titles, for example bitcoin, fed or election. Each keyword is a separate search.

## `cacheProjectName` (type: `string`):

Use the same name on each scheduled run to get only new markets. Markets already scraped under this name are skipped and not charged, and they do not count towards Max items. Each record gets changeType: new.

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

Maximum markets saved for each URL, keyword, category, series or event.

## `categories` (type: `array`):

Kalshi categories, for example Politics, Economics, Crypto, Sports, Climate and Weather, Financials, Entertainment, Science and Technology.

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

Series tickers, for example KXFED or KXHIGHNY. All events of the series are scraped.

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

Event tickers, for example KXELONMARS-99. All markets of the event are scraped.

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

Only events with this status. Does not apply to event tickers.

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

Skip markets with lower total traded volume. 0 keeps all markets.

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

Add the current yes/no bid levels (price and quantity) of each market. One extra request per market.

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

Price levels per side when the orderbook is included. 0 returns all levels.

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

Add up to this many most recent trades of each market (max 1000). 0 turns it off.

## `proxyConfiguration` (type: `object`):

Kalshi works without a proxy. Enable Apify Proxy only if you get blocked.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://kalshi.com/category/crypto"
    }
  ],
  "maxItems": 5,
  "status": "open",
  "minVolume": 0,
  "includeOrderbook": false,
  "orderbookDepth": 10,
  "tradesLimit": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (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 = {
    "startUrls": [
        {
            "url": "https://kalshi.com/category/crypto"
        }
    ],
    "maxItems": 5,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("confidential_gnat/kalshi-markets-scraper").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 = {
    "startUrls": [{ "url": "https://kalshi.com/category/crypto" }],
    "maxItems": 5,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("confidential_gnat/kalshi-markets-scraper").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 '{
  "startUrls": [
    {
      "url": "https://kalshi.com/category/crypto"
    }
  ],
  "maxItems": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call confidential_gnat/kalshi-markets-scraper --silent --output-dataset

```

## MCP server setup

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

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/eZkdHl13Xr38491Ry/builds/BS6HgEywqHTaO8HWu/openapi.json
