# Kalshi Settlement Calendar & Order Book Depth (`datagrit/kalshi-settlement-calendar`) Actor

Kalshi markets ranked by when they settle, with the order book depth, spread and settlement source of each one.

- **URL**: https://apify.com/datagrit/kalshi-settlement-calendar.md
- **Developed by:** [datagrit](https://apify.com/datagrit) (community)
- **Categories:** Other, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

### What does Kalshi Settlement Calendar & Order Book Depth do?

It lists the open Kalshi prediction markets that are expected to settle inside a time window you choose, for example the next 24 hours, and returns one flat row per market: expected settlement time, hours to settle, the sources Kalshi settles on, YES bid, ask and spread, 24-hour volume, open interest and the contracts resting near the best bid and ask. It is built for traders, quants and bot builders who want a settlement calendar with liquidity attached, not a dump of every market. Export the rows as JSON, CSV or Excel, call the Actor through the Apify API, or plug it into n8n, Make and AI agents through MCP.

### What can you use the Kalshi settlement calendar for?

- **Settlement-day trading.** See every market that settles tonight or this week, sorted by the soonest expected settlement, and skip the ones nobody quotes.
- **Liquidity screening.** Filter by minimum 24h volume, minimum open interest and maximum spread in cents, then check how many contracts sit within a few cents of the best bid and ask before you size an order.
- **Resolution-source research.** Every row carries the settlement sources of its series, with links, so you can group markets by the data feed that decides them.
- **Alerts and dashboards.** Schedule the Actor every hour and feed a spreadsheet, a Slack bot or a trading script with the next markets to settle.
- **Overdue markets.** Set the lower bound of the window below zero to also list markets whose expected settlement time has passed but which have not settled yet.

### How to use the Kalshi order book and settlement filters

1. Set **Settles within (hours)** to the horizon you care about. The default is 24.
2. Optionally narrow the scope by category (Sports, Crypto, Financials, Politics, Economics, Transportation and others; a series Kalshi lists under several categories is kept when any of them matches), by series ticker or by words in the market title. Naming series is much faster than scanning the whole exchange.
3. Add liquidity filters: minimum 24h volume, minimum open interest, maximum spread. By default only markets quoted on both sides are listed.
4. Choose how to sort and how many markets to return, then run.

#### Order book depth

When **Include order book depth** is on, the Actor reads the order book of every returned market. `yesBidDepth` is the number of contracts resting within the depth window below the best YES bid, and `yesAskDepth` is the number of contracts you can buy within the window above the best YES ask. The window width is set in cents. The levels and totals cover the whole book. Turn the option off for a faster run without depth.

### Example output

| ticker | title | category | expectedSettlementTime | hoursToSettle | yesBid | yesAsk | spreadCents | volume24h | yesBidDepth | yesAskDepth |
|---|---|---|---|---|---|---|---|---|---|---|
| KXBTCD-26OCT0117-T83249.99 | Bitcoin price on Oct 1, 2026? | Crypto | 2026-10-01T21:00:00.000Z | 18.26 | 0.58 | 0.59 | 1 | 29185.23 | 16839.01 | 19022.45 |

```json
{
  "found": true,
  "ticker": "KXBTCD-26OCT0117-T83249.99",
  "eventTicker": "KXBTCD-26OCT0117",
  "seriesTicker": "KXBTCD",
  "category": "Crypto",
  "title": "Bitcoin price on Oct 1, 2026?",
  "expectedSettlementTime": "2026-10-01T21:00:00.000Z",
  "hoursToSettle": 18.26,
  "settlementSources": "CF Benchmarks",
  "yesBid": 0.58,
  "yesAsk": 0.59,
  "midPrice": 0.585,
  "spreadCents": 1,
  "volume24h": 29185.23,
  "openInterest": 17101.47,
  "yesBidDepth": 16839.01,
  "yesAskDepth": 19022.45,
  "depthWindowCents": 5,
  "sourceUrl": "https://api.elections.kalshi.com/trade-api/v2/markets/KXBTCD-26OCT0117-T83249.99",
  "scrapedAt": "2026-10-01T02:44:42.436Z"
}
```

Prices are in dollars, so 0.58 is 58 cents and reads as a 58% implied probability. Volume, open interest and depth are counted in contracts.

### How much does it cost?

You pay a small fee per run and a price per market returned, lower on paid Apify plans. Rows that only report that nothing matched are not billed and neither are duplicates. Set a maximum spend on the run and the Actor stops when it is reached. A run without named series scans the whole exchange catalog, which takes about a minute and a half; naming series or categories shortens it.

### Input

- **Settles within (hours)** and **Settles after (hours)** – the settlement window, counted from the start of the run. A negative lower bound includes overdue markets.
- **Categories**, **Series tickers**, **Title keywords** – optional scope filters.
- **Minimum 24h volume**, **Minimum open interest**, **Only two-sided quotes**, **Maximum spread (cents)** – liquidity filters.
- **Sort by** – soonest settlement, highest 24h volume, highest open interest or tightest spread.
- **Include order book depth** and **Depth window (cents)** – depth fields and the width of the window.
- **Include rules text** – adds the primary and secondary rules of every market.
- **Maximum results** – total limit of returned markets.
- **Proxy configuration** – optional; the Kalshi public API does not need one.

### Output fields

Each row contains the identifiers (`ticker`, `eventTicker`, `seriesTicker`), the series description (`seriesTitle`, `category`, `categories`, `frequency`; `categories` lists every category the series is listed under, the same membership the category filter uses), `title` and `outcome`, the timing fields (`expectedSettlementTime`, `hoursToSettle`, `closeTime`, `latestSettlementTime`, `settlementTimerSeconds`, `canCloseEarly`), the settlement sources and their URLs, the quotes (`yesBid`, `yesAsk`, `noBid`, `noAsk`, `lastPrice`, `midPrice`, `spreadCents`, sizes), the activity fields (`volume`, `volume24h`, `openInterest`), the depth fields, optional rules text, `sourceUrl` and `scrapedAt`. Fields the source does not publish are `null`. When no market matches you get one row with `found: false`, and the run status says why: the series has no open markets right now, nothing settles inside the window, the liquidity and keyword filters removed every market in the window, or Kalshi returned only combination or not-open markets. A source that stops applying its own filters (combination markets or markets that are not active in more than 1% of the scan) fails the run instead of returning rows.

### FAQ

#### Is it legal to scrape Kalshi market data?

The Actor reads only the public market data API that Kalshi provides without an account. It does not log in and does not place orders. You are responsible for using the data in line with applicable laws and the exchange's terms.

#### What does expected settlement time mean?

It is the time at which Kalshi expects the market to settle, as published for each market. Some markets close early once the outcome is decided, and a few settle later than expected, so treat it as a schedule, not a guarantee.

#### Are combo markets included?

No. Multivariate combination markets are excluded, so the rows are single-outcome markets. The Actor checks this on every row: a market that belongs to a combination ("MVE") series of the Kalshi catalog, or that carries combination fields, is skipped and counted in the run status. If Kalshi stops excluding them and they make up more than 1% of the scan, the run fails before any row is billed instead of returning combination markets. If you name a combination series in `seriesTickers` (for example `KXMVECROSSCATEGORY`), the run says so: it fails when every named series is a combination series, and otherwise skips it with a note in the run status, so you are never told that Kalshi has no markets in a series that does have combination markets.

#### How fresh is the data?

Every run reads quotes and order books live. Schedule runs as often as you need.

#### Why do some rows have empty depth fields?

The order book of a market could not be read, or depth was switched off. The run fails when no order book can be read at all, so a source change does not pass unnoticed.

#### Why did a run fail with a message about a missing field?

The run stops, and bills nothing, when Kalshi stops publishing a field that a filter, a sort or a column depends on: the expected settlement time, 24h volume, open interest or the settlement sources of the series. It also stops when a series filter is combined with a category that does not contain it, and when the source stops applying the series filter and returns markets of other series. Without this a change at the source would return rows with empty values or an empty result that looks like a filter problem.

### Related Actors

See other data Actors from the same publisher on the Store profile.

# Changelog

This Actor's version history is a separate document: https://apify.com/datagrit/kalshi-settlement-calendar/changelog.md

# Actor input Schema

## `settlesWithinHours` (type: `number`):

Keep markets whose expected settlement time is at most this many hours from now. 24 means everything that settles today and tonight; 168 is one week.

## `settlesAfterHours` (type: `number`):

Keep markets whose expected settlement time is at least this many hours from now. 0 starts at the present moment; a negative value also returns markets whose expected time has passed but which are not settled yet (for example -6).

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

Optional. Only markets of series that Kalshi lists under these categories (a series can be listed under several, so a row can show another category than the one you asked for; see the categories field), for example Sports, Crypto, Financials, Politics, Economics, Transportation, Climate and Weather, Entertainment. Case-insensitive; leave empty for all categories.

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

Optional. Only these Kalshi series, for example KXBTCD or KXNASDAQ100U. Scanning named series is much faster than scanning the whole exchange.

## `keywords` (type: `array`):

Optional. Keep markets whose market title contains at least one of these words or phrases (case-insensitive). Only the market title is searched, not the outcome or series name.

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

Keep markets with at least this many contracts traded in the last 24 hours. 0 turns the filter off.

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

Keep markets with at least this many contracts outstanding. 0 turns the filter off.

## `requireTwoSidedQuote` (type: `boolean`):

Keep only markets with a YES bid of at least 1 cent and a YES ask of at most 99 cents, so that you can actually trade both ways. Turn off to also list markets that nobody quotes.

## `maxSpreadCents` (type: `number`):

Keep markets whose YES ask minus YES bid is at most this many cents. 100 turns the filter off; any lower value also drops markets that are not quoted on both sides.

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

Order of the results before "Maximum results" is applied: soonest settlement, highest 24h volume, highest open interest or tightest spread.

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

Read the order book of every returned market and add the depth fields (contracts near the best bid and ask, levels, totals). Turn off for a faster run without depth.

## `depthCents` (type: `integer`):

Width of the window used by the depth fields: contracts resting within this many cents of the best bid, and within this many cents of the best ask.

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

Add the primary and secondary settlement rules text of every market. Makes the rows larger.

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

Stop after this many markets.

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

Optional proxy. Leave disabled: the Kalshi public API does not need one.

## Actor input object example

```json
{
  "settlesWithinHours": 24,
  "settlesAfterHours": 0,
  "categories": [],
  "seriesTickers": [],
  "keywords": [],
  "minVolume24h": 0,
  "minOpenInterest": 0,
  "requireTwoSidedQuote": true,
  "maxSpreadCents": 100,
  "sortBy": "settlement",
  "includeOrderbook": true,
  "depthCents": 5,
  "includeRules": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All extracted records as a 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 = {
    "settlesWithinHours": 24,
    "settlesAfterHours": 0,
    "categories": [],
    "seriesTickers": [],
    "keywords": [],
    "minVolume24h": 0,
    "minOpenInterest": 0,
    "requireTwoSidedQuote": true,
    "maxSpreadCents": 100,
    "sortBy": "settlement",
    "includeOrderbook": true,
    "depthCents": 5,
    "includeRules": false,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagrit/kalshi-settlement-calendar").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 = {
    "settlesWithinHours": 24,
    "settlesAfterHours": 0,
    "categories": [],
    "seriesTickers": [],
    "keywords": [],
    "minVolume24h": 0,
    "minOpenInterest": 0,
    "requireTwoSidedQuote": True,
    "maxSpreadCents": 100,
    "sortBy": "settlement",
    "includeOrderbook": True,
    "depthCents": 5,
    "includeRules": False,
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("datagrit/kalshi-settlement-calendar").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 '{
  "settlesWithinHours": 24,
  "settlesAfterHours": 0,
  "categories": [],
  "seriesTickers": [],
  "keywords": [],
  "minVolume24h": 0,
  "minOpenInterest": 0,
  "requireTwoSidedQuote": true,
  "maxSpreadCents": 100,
  "sortBy": "settlement",
  "includeOrderbook": true,
  "depthCents": 5,
  "includeRules": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call datagrit/kalshi-settlement-calendar --silent --output-dataset

```

## MCP server setup

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

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/j9DQbkmagQetKS2zV/builds/oZf50foiWVqiOdUty/openapi.json
