# Kalshi Scraper · Event Contracts, Markets, Prices & Volume (`reapx/kalshi-scraper`) Actor

Scrape Kalshi prediction markets, event contracts, option pricing, order book quotes, trading volume, open interest, and resolution rules. Export structured JSON, CSV, or Excel data.

- **URL**: https://apify.com/reapx/kalshi-scraper.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** Business, Other, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 1,000 kalshi prediction market records

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## Kalshi Scraper · Event Contracts, Markets, Prices & Volume

**Kalshi Scraper** extracts public prediction markets, event contracts, option pricing, bid/ask order book quotes, 24-hour and total trading volume, open interest, and official resolution rules from Kalshi. Built for quantitative traders, financial analysts, policy researchers, and automated AI data pipelines requiring structured market intelligence.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/kalshi-scraper/](https://reapx.dev/data/kalshi-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/kalshi-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/kalshi-scraper). Questions: reapxdev@proton.me

***

### Features & Use Cases

- **Quantitative Forecasting**: Collect real-time probability estimates for Federal Reserve rate cuts, inflation prints, and election outcomes.
- **Order Book & Pricing Analysis**: Monitor spread mechanics (`yesBidDollars` vs `yesAskDollars`) and liquidity depth across prediction markets.
- **Historical Event Research**: Extract settled contracts with verified outcomes (`result`) to benchmark market forecast accuracy.
- **Automated Datasets**: Feed live prediction data directly into financial dashboards, machine learning models, or LLM agent prompts.

***

### ⬇️ Input

Every field is described here exactly as the Actor reads it. Run it with the prefilled input and it returns real rows without any further configuration.

| Field | Type | Required | Prefilled | What it does |
| --- | --- | --- | --- | --- |
| `category` | string | no | - | Filter Kalshi prediction markets by market category topic (e.g. Financials, Elections, Economics, Politics, Sports, Crypto). |
| `status` | string | no | - | Filter contracts by lifecycle status, using the exchange's own filter vocabulary: open, closed, settled, unopened. |
| `seriesTicker` | string | no | - | Filter prediction markets by specific Kalshi Series Ticker code (e.g. KXFED, KXNFLWINS, KXELONMARS, KXTSLAA). |
| `eventTicker` | string | no | - | Return every contract belonging to one Kalshi event (e.g. KXFEDDECISION-26SEP). An event is the question; each contract under it is one outcome or strike, so this is how you get a whole... |
| `tickers` | string | no | - | Extract specific prediction market tickers by exact ticker identifier code (e.g. KXFED-24DEC31-T1.5). |
| `minCloseTs` | integer | no | - | Filter markets closing on or after this Unix epoch timestamp in seconds (e.g. 1767225600 for Jan 1, 2026). |
| `maxCloseTs` | integer | no | - | Filter markets closing on or before this Unix epoch timestamp in seconds (e.g. 1798761600 for Jan 1, 2027). |
| `maxMarkets` | integer | no | `200` | Maximum number of Kalshi prediction market contract records to scrape and output. |

#### What empty means, and what a larger value costs

The two questions an input table normally does not answer. Both columns are read off this Actor's own code and its own price list.

| Field | Left empty | Turned up |
| --- | --- | --- |
| `category` | Leave empty to extract prediction markets across all domain categories. | Selecting a category restricts extraction focus, reducing total execution duration and compute consumption. |
| `status` | Leave empty to include contracts at any stage of life. | The value you FILTER on and the value that comes BACK on the row are different vocabularies - a contract accepted by status=open is written to the dataset as active, and a brand... |
| `seriesTicker` | Leave empty to include contracts from all active market series. | Specifying a series ticker isolates a single event series, resulting in faster runs and targeted dataset results. |
| `eventTicker` | Leave empty to search by category, series or status instead. | The narrowest filter the exchange offers - a single event returns a handful of rows in one request, measured at 5 rows for the September Fed decision ladder. |
| `tickers` | Leave empty to perform broader category or status searches. | Providing exact market tickers directly fetches matching contract records without pagination overhead. |
| `minCloseTs` | Leave empty for no lower bound on market close date. | Setting a minimum close timestamp filters out older or past-closing prediction contracts. |
| `maxCloseTs` | Leave empty for no upper bound on market close date. | Setting a maximum close timestamp restricts extraction to near-term or specific timeframe contracts. |
| `maxMarkets` | No bound is applied | Each row returned is one **$0.002** charge, so this field is your cost cap as well as your row cap. At the ceiling of 10,000 rows that is $20.00 at list price. |

### ⬆️ Output

One row per record, as JSON, CSV, Excel or XML, and through the API. Every field below is on every row this Actor writes; a field the source did not return is empty rather than guessed.

| Field | Type | What it gives you | Example |
| --- | --- | --- | --- |
| `slug` | string | Unique URL-friendly market ticker identifier on Kalshi platform. | "KXFED-24DEC31-T1.5" |
| `title` | string | Primary contract title or prediction question statement. | "Fed interest rate target range in December 2024?" |
| `subtitle` | string | Outcome subtitle or candidate option detail statement. | "Target rate between 4.25% and 4.50%" |
| `eventTicker` | string | Event container ticker symbol identifying the broader event group. | "KXFED-24DEC" |
| `seriesTicker` | string | Series ticker symbol identifying the overarching recurring market series. | "KXFED" |
| `marketType` | string | Contract structure classification (e.g., binary, scalar, custom). | "binary" |
| `status` | string | Lifecycle status as the exchange reports it on the row: active, initialized, closed, settled or finalized. Note this... | "open" |
| `category` | string | Domain category topic under which the contract is cataloged. | "Financials" |
| `openTime` | string | ISO timestamp when market trading opened. | "2024-01-15T14:00:00Z" |
| `closeTime` | string | ISO timestamp when market trading closes. | "2024-12-31T20:00:00Z" |
| `expirationTime` | string | ISO timestamp when the contract officially expires. | "2024-12-31T20:00:00Z" |
| `createdTime` | string | ISO timestamp when the market contract record was created. | "2024-01-10T12:00:00Z" |
| `updatedTime` | string | ISO timestamp when market contract record was last updated. | "2026-08-03T18:19:26Z" |
| `lastPriceDollars` | number | Most recent executed trade price in USD (0.00 to 1.00 per contract). | 0.45 |
| `yesBidDollars` | number | Highest current bid quote price for Yes outcome in USD. | 0.44 |
| `yesAskDollars` | number | Lowest current offer quote price for Yes outcome in USD. | 0.46 |
| `noBidDollars` | number | Highest current bid quote price for No outcome in USD. | 0.54 |
| `noAskDollars` | number | Lowest current offer quote price for No outcome in USD. | 0.56 |
| `previousPriceDollars` | number | Previous closing or reference price in USD. | 0.43 |
| `volume24hFp` | number | Number of contract units traded in past 24 hours. | 1450.0 |
| `volumeFp` | number | Cumulative contract unit volume traded over market lifetime. | 89200.0 |
| `openInterestFp` | number | Total active open contract positions. | 12400.0 |
| `notionalValueDollars` | number | Payout value per winning contract unit in USD. | 1.0 |
| `result` | string | Official settlement result value (e.g. yes, no, or empty if unresolved). | "yes" |
| `canCloseEarly` | boolean | Whether the market contract permits early close upon event resolution. | true |
| `isProvisional` | boolean | Whether the contract parameters are marked provisional. | false |
| `strikeType` | string | Classification of strike threshold structure (custom, range, threshold). | "custom" |
| `rulesPrimary` | string | Official primary resolution rules and source agency terms. | "Official target range announced by the Federal Open Mark... |
| `rulesSecondary` | string | Secondary resolution criteria and disclaimer terms. | "Kalshi is an FCM registered with the CFTC." |
| `settlementTimerSeconds` | integer | Delay window in seconds applied before settlement finality. | 3600 |
| `sourceUrl` | string | Direct canonical web page URL for this market contract on Kalshi. | "https://kalshi.com/markets/KXFED-24DEC31-T1.5" |
| `expectedExpirationTime` | string | When the exchange expects the contract to expire, which is earlier than expirationTime whenever a market can settle... | "2026-08-05T04:40:00Z" |

#### Dataset views

The dataset ships with named views, so the Output tab, the API and any agent reading this Actor get the columns that matter for a job without asking for all of them.

**Market Overview** (`?view=overview`) - 9 columns: `slug`, `title`, `category`, `status`, `lastPriceDollars`, `volumeFp`, `openInterestFp`, `closeTime`, `sourceUrl`

| Column | Header |
| --- | --- |
| `slug` | Ticker |
| `title` | Market |
| `category` | Category |
| `status` | Status |
| `lastPriceDollars` | Last Price ($) |
| `volumeFp` | Volume |
| `openInterestFp` | Open Interest |
| `closeTime` | Closes |
| `sourceUrl` | Kalshi Page |

**Order Book Quotes & Pricing** (`?view=pricing`) - 10 columns: `slug`, `title`, `lastPriceDollars`, `yesBidDollars`, `yesAskDollars`, `noBidDollars`, `noAskDollars`, `previousPriceDollars`, `volume24hFp`, `notionalValueDollars`

| Column | Header |
| --- | --- |
| `slug` | Ticker |
| `title` | Market |
| `lastPriceDollars` | Last ($) |
| `yesBidDollars` | Yes Bid ($) |
| `yesAskDollars` | Yes Ask ($) |
| `noBidDollars` | No Bid ($) |
| `noAskDollars` | No Ask ($) |
| `previousPriceDollars` | Previous ($) |
| `volume24hFp` | Volume 24h |
| `notionalValueDollars` | Notional ($) |

**Contract Structure & Rules** (`?view=marketDetails`) - 9 columns: `slug`, `eventTicker`, `seriesTicker`, `marketType`, `strikeType`, `result`, `canCloseEarly`, `rulesPrimary`, `rulesSecondary`

| Column | Header |
| --- | --- |
| `slug` | Ticker |
| `eventTicker` | Event |
| `seriesTicker` | Series |
| `marketType` | Type |
| `strikeType` | Strike Type |
| `result` | Result |
| `canCloseEarly` | Can Close Early |
| `rulesPrimary` | Primary Rule |
| `rulesSecondary` | Secondary Rule |

**Lifecycle Timestamps** (`?view=timing`) - 8 columns: `slug`, `status`, `openTime`, `closeTime`, `expectedExpirationTime`, `expirationTime`, `settlementTimerSeconds`, `updatedTime`

| Column | Header |
| --- | --- |
| `slug` | Ticker |
| `status` | Status |
| `openTime` | Opened |
| `closeTime` | Closes |
| `expectedExpirationTime` | Expected Expiry |
| `expirationTime` | Expiry |
| `settlementTimerSeconds` | Settlement Timer (s) |
| `updatedTime` | Last Updated |

Fetch one directly:

```
GET https://api.apify.com/v2/datasets/{datasetId}/items?view=overview&format=csv
```

#### One real row

Unedited, from this Actor's own most recent successful run.

```json
{
  "slug": "KXFEDDECISION-26SEP-C25",
  "title": "Will the Federal Reserve Cut rates by 25bps at their September 2026 meeting?",
  "subtitle": "Cut 25bps",
  "eventTicker": "KXFEDDECISION-26SEP",
  "seriesTicker": "KXFEDDECISION",
  "marketType": "binary",
  "status": "active",
  "category": "",
  "openTime": "2025-09-29T14:00:00Z",
  "closeTime": "2026-09-16T17:59:00Z",
  "expirationTime": "2026-12-16T18:01:00Z",
  "expectedExpirationTime": "2026-09-16T18:05:00Z",
  "createdTime": "2025-09-26T15:30:59.234134Z",
  "updatedTime": "2026-04-09T14:06:58.042679Z",
  "lastPriceDollars": 0.01,
  "yesBidDollars": 0.01,
  "yesAskDollars": 0.02,
  "noBidDollars": 0.98,
  "noAskDollars": 0.99,
  "previousPriceDollars": 0.02,
  "volume24hFp": 26980.43,
  "volumeFp": 563161.61,
  "openInterestFp": 526189.77,
  "notionalValueDollars": 1,
  "result": "",
  "canCloseEarly": true,
  "isProvisional": false,
  "strikeType": "custom",
  "rulesPrimary": "If the Federal Reserve does a Cut of 25bps on September 16, 2026, then the market resolves to Yes.",
  "rulesSecondary": "This market is mutually exclusive. Therefore, if the Federal Reserve hikes by 50bps, the 50bps market will resolve to Yes and the 25bps market will resolve to No. Only one bucket, at maximum, can resolve to Yes. Note 4/28/25: For the markets beginning after the May meeting, if a scheduled FOMC meeting is canceled and does not occur on its scheduled date, then the strike for \"Fed maintains rate\" will resolve to Yes and all others will resolve to No.",
  "settlementTimerSeconds": 297,
  "sourceUrl": "https://kalshi.com/markets/KXFEDDECISION-26SEP-C25"
}
```

### 🧪 Worked examples

Every block below is an input this Actor has actually run, with the row count of the run that produced it. Copy one straight into the Console.

#### One event, the whole strike ladder

```json
{
  "eventTicker": "KXFEDDECISION-26SEP",
  "maxMarkets": 50
}
```

That run returned **5 rows** in 3s.

#### Kalshi Elections Prediction Markets

Extract active and historical election prediction contracts on Kalshi.

```json
{
  "category": "Elections",
  "maxMarkets": 200
}
```

That run returned **200 rows**.

#### Federal Reserve Interest Rate Markets

Extract Federal Reserve rate decision prediction market contracts.

```json
{
  "seriesTicker": "KXFED",
  "maxMarkets": 200
}
```

That run returned **109 rows**.

#### Active Open Financial Prediction Markets

Extract active open interest rate and financial prediction contracts.

```json
{
  "category": "Financials",
  "status": "open",
  "maxMarkets": 200
}
```

That run returned **200 rows**.

#### All Currently Open Kalshi Markets

Extract active open prediction markets currently trading on Kalshi.

```json
{
  "status": "open",
  "maxMarkets": 200
}
```

That run returned **200 rows**.

#### Active Weather Markets Closing Late 2026

Extract open climate event contracts closing in late 2026.

```json
{
  "category": "Climate and Weather",
  "status": "open",
  "minCloseTs": 1782864000,
  "maxMarkets": 200
}
```

That run returned **200 rows**.

### How it works

#### The endpoint it calls

Plain HTTP against the source's own public API. No headless browser, no login, no key of yours:

```
https://api.elections.kalshi.com/trade-api/v2
```

The exchange's own public v2 trade API. Read-only market data needs no key and no account; nothing here touches an order, a position or a balance.

#### The paging it does

Cursor paging, up to 200 contracts per request, following the `cursor` the exchange returns until your **Maximum Markets Limit** is reached or a short page says the result set is exhausted.

Every filter is passed to the exchange rather than applied afterwards, so a filtered run reads only the pages it needs: `category`, `status`, `series_ticker`, `event_ticker`, an explicit list of `tickers`, and the `min_close_ts` / `max_close_ts` window. Prices arrive as decimal dollar strings and are converted once, on the way in, so `lastPriceDollars` is a number you can average without parsing.

#### The rate it holds

Every request is retried up to **3 times**, with the wait doubling between attempts, and HTTP **429, 500, 502, 503, 504** are treated as retryable rather than fatal. Each request times out at **20s**.

One request at a time, retried up to 3 times with the wait doubling between attempts, and a 400 is never retried because the exchange has already told you the query itself is wrong.

#### What you are charged

One `market-scraped` event per row written to the dataset, $0.002 at list price. Charged once per complete Kalshi prediction market contract extracted and written to the default dataset. Empty runs or unreachable API responses are never charged.

| Apify plan tier | Price per row |
| --- | --- |
| Free | $0.002 |
| Bronze | $0.0018 |
| Silver | $0.0015 |
| Gold | $0.0013 |
| Platinum | $0.001 |
| Diamond | $0.0008 |

Apify platform usage is absorbed, not passed on, so the row price is the whole bill.

#### Why the dataset is correct at every moment

Rows are written and charged one at a time, so a run stopped by your budget cap keeps everything it had already collected. Market data is a snapshot by nature: every row carries `updatedTime` from the exchange and the run's own timestamp, so two runs of the same task are directly comparable rather than merely similar.

### ⚠️ Error reference

Derived from this Actor's own exception classes and the HTTP branches in its client. The run always reports what happened in its **status message**, so you never need the log to know what you got.

| Raised | When | What the run does |
| --- | --- | --- |
| `BadQuery` | Raised when Kalshi API rejects input query parameters (HTTP 400). | Run fails with: *Kalshi API rejected query parameters: <exc>* |
| `SourceBlocked` | Raised when Kalshi API is unreachable or returns severe HTTP errors (403, 5xx). | Run fails with: *Kalshi API unreachable: <exc>* |

#### HTTP statuses the client actually handles

| Status | Handling |
| --- | --- |
| `429` | Retried with backoff. The run continues if a later attempt succeeds. |
| `500` | Retried with backoff. The run continues if a later attempt succeeds. |
| `502` | Retried with backoff. The run continues if a later attempt succeeds. |
| `503` | Retried with backoff. The run continues if a later attempt succeeds. |
| `504` | Retried with backoff. The run continues if a later attempt succeeds. |
| `400` | The source rejected the query itself, so retrying it cannot help; the input is at fault. |
| `403` | The source refused the request. Treated as a block, not a bug in your input. |

#### What each outcome costs

| Outcome | Rows | Charged |
| --- | --- | --- |
| Run finished | Everything the source returned for your filters | One `market-scraped` per row |
| Nothing matched your filters | 0 | **Nothing** |
| Source refused or was unreachable | Whatever was already collected | Only the rows you got |
| Budget cap reached mid-run | The rows collected before the cap | Only those rows |

Status messages this Actor can end on, verbatim from its own source:

- Run budget of $ cannot cover a single record at $<record event price usd> plus start cost $<start cost>. Raise Max Total Charge to at least $\<start cost + record event price usd>.
- Kalshi API rejected query parameters: <exc>
- No Kalshi prediction markets found matching criteria. Zero charged.
- Pushed <pushed count> Kalshi market contracts, <open markets> of them open for trading right now. Charged <pushed count> at $<record event price usd> each.

### ❓ FAQ

##### How are prices represented in the dataset?

All price fields (`lastPriceDollars`, `yesBidDollars`, `yesAskDollars`, `noBidDollars`, `noAskDollars`) are expressed in USD per contract unit, bounded between `$0.00` and `$1.00`.

##### Does this actor require Kalshi account API keys?

No. The scraper accesses public market listings via Kalshi's unauthenticated public trade API.

##### How frequently is market data updated?

Data is fetched live directly from Kalshi at the moment of execution.

***

#### How many rows can one run return?

Up to 10,000, set by the maximum-results field, which is also your cost cap. Raise it for a bigger slice, or set a **Max total charge** on the run and the Actor will stop cleanly when it gets there.

#### Can I get just some of the columns?

Yes. The dataset ships named views (`overview`, `pricing`, `marketDetails`, `timing`); add `?view=<name>` to the dataset items URL, or pick one in the Output tab, and you get that view's columns in JSON, CSV or Excel.

#### Can an agent call this?

Yes, through Apify's MCP server at <https://mcp.apify.com> with nothing to integrate on our side: `search-actors` finds it, `fetch-actor-details` returns the input schema above, and `call-actor` runs it.

#### Will the dataset still be there next month?

Yes. The run names its own default dataset at startup, and Apify keeps named storages past the retention window that deletes unnamed ones, so the run id in a row you cited a year ago still resolves.

#### Is the data complete?

It is exactly what the source returned for your filters. Nothing is inferred, modelled or filled in, and a field the source did not return is empty rather than guessed. The run's status message tells you what you got, so you never have to read the log to find out.

### 💬 Your feedback

Have suggestions or need custom market data fields? Reach out to the maintainers at **reapxdev@proton.me**.

***

*Disclaimer: Unofficial - not affiliated with Kalshi. Collects public data only. reapx. Contact reapxdev@proton.me.*

# Actor input Schema

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

Filter Kalshi prediction markets by market category topic (e.g. <code>Financials</code>, <code>Elections</code>, <code>Economics</code>, <code>Politics</code>, <code>Sports</code>, <code>Crypto</code>).<br><br><b>Empty value:</b> Leave empty to extract prediction markets across all domain categories.<br><br><b>Consequence:</b> Selecting a category restricts extraction focus, reducing total execution duration and compute consumption.

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

Filter contracts by lifecycle status, using the exchange's own filter vocabulary: <code>open</code>, <code>closed</code>, <code>settled</code>, <code>unopened</code>.<br><br><b>Empty value:</b> leave empty to include contracts at any stage of life.<br><br><b>Consequence:</b> the value you FILTER on and the value that comes BACK on the row are different vocabularies - a contract accepted by <code>status=open</code> is written to the dataset as <code>active</code>, and a brand new one as <code>initialized</code>. Filter with these four; read <code>status</code> on the row for what the exchange actually calls it.

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

Filter prediction markets by specific Kalshi Series Ticker code (e.g. <code>KXFED</code>, <code>KXNFLWINS</code>, <code>KXELONMARS</code>, <code>KXTSLAA</code>).<br><br><b>Empty value:</b> Leave empty to include contracts from all active market series.<br><br><b>Consequence:</b> Specifying a series ticker isolates a single event series, resulting in faster runs and targeted dataset results.

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

Return every contract belonging to one Kalshi event (e.g. <code>KXFEDDECISION-26SEP</code>). An event is the question; each contract under it is one outcome or strike, so this is how you get a whole ladder in one run.<br><br><b>Empty value:</b> leave empty to search by category, series or status instead.<br><br><b>Consequence:</b> the narrowest filter the exchange offers - a single event returns a handful of rows in one request, measured at 5 rows for the September Fed decision ladder.

## `tickers` (type: `string`):

Extract specific prediction market tickers by exact ticker identifier code (e.g. <code>KXFED-24DEC31-T1.5</code>).<br><br><b>Empty value:</b> Leave empty to perform broader category or status searches.<br><br><b>Consequence:</b> Providing exact market tickers directly fetches matching contract records without pagination overhead.

## `minCloseTs` (type: `integer`):

Filter markets closing on or after this Unix epoch timestamp in seconds (e.g. <code>1767225600</code> for Jan 1, 2026).<br><br><b>Empty value:</b> Leave empty for no lower bound on market close date.<br><br><b>Consequence:</b> Setting a minimum close timestamp filters out older or past-closing prediction contracts.

## `maxCloseTs` (type: `integer`):

Filter markets closing on or before this Unix epoch timestamp in seconds (e.g. <code>1798761600</code> for Jan 1, 2027).<br><br><b>Empty value:</b> Leave empty for no upper bound on market close date.<br><br><b>Consequence:</b> Setting a maximum close timestamp restricts extraction to near-term or specific timeframe contracts.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `maxMarkets` (type: `integer`):

Maximum number of Kalshi prediction market contract records to scrape and output.<br><br><b>Default:</b> <code>200</code>.<br><br><b>Consequence:</b> Higher capacity limits extract larger datasets but increase execution duration and total event costs.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## Actor input object example

```json
{
  "maxMarkets": 200
}
```

# Actor output Schema

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

Every Kalshi prediction market contract extracted by this run, one item per market, written to the default dataset.

# 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 = {
    "category": "",
    "status": "",
    "seriesTicker": "",
    "eventTicker": "",
    "tickers": "",
    "maxMarkets": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/kalshi-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 = {
    "category": "",
    "status": "",
    "seriesTicker": "",
    "eventTicker": "",
    "tickers": "",
    "maxMarkets": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/kalshi-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 '{
  "category": "",
  "status": "",
  "seriesTicker": "",
  "eventTicker": "",
  "tickers": "",
  "maxMarkets": 200
}' |
apify call reapx/kalshi-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reapx/kalshi-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/MF8D8VUWFwC71mqdU/builds/BWCvBGco5bfk6gzo3/openapi.json
