datagrit

datagrit › Guides › Kalshi Settlement Calendar & Order Book Depth

Guide

How to list Kalshi markets that settle in the next 24 hours with Python

Build a Kalshi settlement calendar with bid, ask, spread, volume and order book depth near the touch, filtered by liquidity, using Python or cURL.

Published 2026-10-01 · uses the Kalshi Settlement Calendar & Order Book Depth Actor

On a prediction market, time to settlement shapes how you trade. A contract that resolves tonight is a different position from one that resolves in March, and close to settlement the data feed that decides the outcome matters more than any opinion.

If you trade on Kalshi, build bots for it or study its markets, the question you keep asking is: which open markets settle in the next N hours, which of them are actually quoted, and how much can I trade near the best price? Kalshi's public API holds all the pieces. It just does not give them to you as one table.

This post shows what the API offers, the traps in combining it, and how to get a settlement calendar with liquidity attached in one call.

Where the data comes from

Kalshi exposes a public market data API at api.elections.kalshi.com/trade-api/v2 that needs no account for reading. It has markets (with quotes, volume, open interest and timing fields), a series catalog (with categories, frequency and settlement sources) and order books per market.

Building a settlement calendar on top of it involves more than one endpoint and several surprises:

Step by step

1. Define the input

Crypto and financial markets settling within the next 24 hours, with at least some activity and a spread of 3 cents or less:


{
  "settlesWithinHours": 24,
  "settlesAfterHours": 0,
  "categories": ["Crypto", "Financials"],
  "seriesTickers": [],
  "keywords": [],
  "minVolume24h": 100,
  "minOpenInterest": 0,
  "requireTwoSidedQuote": true,
  "maxSpreadCents": 3,
  "sortBy": "settlement",
  "includeOrderbook": true,
  "depthCents": 5,
  "includeRules": false,
  "maxItems": 50
}

sortBy accepts settlement, volume24h, openInterest or spread. A negative settlesAfterHours (for example -6) also lists markets whose expected settlement time has passed but which have not settled yet. Naming seriesTickers such as KXBTCD is much faster than scanning the whole exchange: a run without named series scans the full catalog, which takes about a minute and a half.

2. Run it from Python


from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "settlesWithinHours": 24,
    "seriesTickers": ["KXBTCD"],
    "maxSpreadCents": 3,
    "includeOrderbook": True,
    "depthCents": 5,
    "maxItems": 50,
}

run = client.actor("datagrit/kalshi-settlement-calendar").call(run_input=run_input)
markets = [m for m in client.dataset(run["defaultDatasetId"]).iterate_items() if m.get("found")]

for m in markets:
    print(f'{m["hoursToSettle"]:>6}h  {m["ticker"]:<32} bid {m["yesBid"]} ask {m["yesAsk"]} '
          f'depth {m["yesBidDepth"]}/{m["yesAskDepth"]}')

3. Or with cURL


curl -X POST \
  "https://api.apify.com/v2/acts/datagrit~kalshi-settlement-calendar/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"settlesWithinHours": 48, "seriesTickers": ["KXBTCD"], "maxItems": 20}'

What you get

One row per open market. Prices are in dollars (0.58 = 58 cents, read as a 58% implied probability); volume, open interest and depth are in contracts.

FieldExampleMeaning
tickerKXBTCD-26OCT0117-T83249.99Market ticker
titleBitcoin price on Oct 1, 2026?What the market asks
expectedSettlementTime2026-10-01T21:00:00.000ZWhen Kalshi expects it to settle
hoursToSettle18.26Hours from run start; negative = overdue
settlementSourcesCF BenchmarksWho decides the outcome
yesBid / yesAsk0.58 / 0.59Best YES quotes
spreadCents1Ask minus bid in cents
volume24h29185.23Contracts traded in 24 hours
openInterest17101.47Contracts outstanding
yesBidDepth / yesAskDepth16839.01 / 19022.45Contracts within depthCents of the touch

Rows also carry seriesTicker, seriesTitle, category, categories, frequency, outcome, closeTime, latestSettlementTime, canCloseEarly, settlementSourceUrls, midPrice, NO-side quotes, sizes at the touch, whole-book levels and totals, and, if requested, the rules text.

Recipes

Hourly "settling next" sheet

Schedule the Actor hourly with settlesWithinHours: 6 and sortBy: "settlement", and write the dataset to Google Sheets through an Apify integration or a short script. The sheet always shows what resolves next, with the spread and depth needed to judge whether it is tradable.

Liquidity screen before sizing an order


import pandas as pd

df = pd.DataFrame(markets)
tradable = df[(df["spreadCents"] <= 2) & (df["yesAskDepth"] >= 500)]
print(tradable.sort_values("hoursToSettle")[["ticker", "hoursToSettle", "midPrice", "spreadCents", "yesAskDepth"]])

yesAskDepth counts contracts you can buy within the depth window above the best ask, so it is a direct answer to "can I get 500 contracts without walking the book more than 5 cents?".

Grouping by settlement source

Run with a one-week window (settlesWithinHours: 168), then group by settlementSources. That shows which data feeds (for example CF Benchmarks for the Bitcoin series) decide the most markets this week, which helps when you build source-specific models or alerts.

Limitations

Wrapping up

A settlement-sorted view with depth near the touch is a small thing that saves a lot of glue code; pricing is pay per result, the Actor is on Apify, and every field is described in the documentation.

Try Kalshi Settlement Calendar & Order Book Depth on ApifyActor documentation

More guides