Rizon

Learn

Kalshi API in Python: read markets, sign requests, place orders and use the demo

Kalshi's API in Python: read markets and order books with no key, sign requests with Ed25519, place an order, and test on the demo with mock funds.

3 min read
  • kalshi
  • api
  • python
  • developers
  • bots

Short answer: Market data at https://external-api.kalshi.com/trade-api/v2 needs no key. Orders need a request signed with your private key. To test, use the demo, which has its own keys and mock funds, at https://external-api.demo.kalshi.co/trade-api/v2.

We ran the read code below on Nov 5, 2026. We ran the signing code with a throwaway key, and the demo answered "could not authenticate" as it should. We didn't place an order, because that needs an account. Kalshi's own samples use plain requests and cryptography, so we do too.

Read markets and an order book

import requests

BASE = "https://external-api.kalshi.com/trade-api/v2"

markets = requests.get(f"{BASE}/markets", params={"series_ticker": "KXNFLTOTAL", "status": "open", "limit": 3}).json()["markets"]
for market in markets:
    print(market["ticker"], market["yes_bid_dollars"], market["yes_ask_dollars"])

ticker = markets[0]["ticker"]
book = requests.get(f"{BASE}/markets/{ticker}/orderbook").json()["orderbook_fp"]

best_yes_bid = max(float(price) for price, size in book["yes_dollars"])
best_no_bid = max(float(price) for price, size in book["no_dollars"])
print("bid", best_yes_bid, "ask", round(1 - best_no_bid, 4))

Kalshi's book lists only bids, for Yes and for No. A No bid at 96¢ is the same as a Yes ask at 4¢, so the Yes ask is 1 minus the best No bid. Prices and sizes arrive as strings.

Older examples use api.elections.kalshi.com. It still answered on Nov 5, but the docs now show external-api.kalshi.com.

Sign a request

Each private request carries three headers: your key ID, a millisecond timestamp and a signature. You sign the timestamp, the method and the path, without its query string. Kalshi recommends Ed25519 keys, and RSA-PSS also works.

import base64
import os
import time

import requests
from cryptography.hazmat.primitives import serialization

BASE = "https://external-api.demo.kalshi.co"
KEY_ID = os.environ["KALSHI_KEY_ID"]
with open(os.environ["KALSHI_KEY_FILE"], "rb") as f:
    private_key = serialization.load_pem_private_key(f.read(), password=None)

def signed(method: str, path: str) -> dict:
    timestamp = str(int(time.time() * 1000))
    message = timestamp + method + path.split("?")[0]
    signature = base64.b64encode(private_key.sign(message.encode())).decode()
    return {
        "KALSHI-ACCESS-KEY": KEY_ID,
        "KALSHI-ACCESS-TIMESTAMP": timestamp,
        "KALSHI-ACCESS-SIGNATURE": signature,
    }

path = "/trade-api/v2/portfolio/balance"
print(requests.get(BASE + path, headers=signed("GET", path)).json())

Kalshi shows the private key once, when you create it, so save it then. The demo and production have separate accounts and separate keys.

Place an order

The current order endpoint takes bid or ask on the Yes side, with prices and sizes as strings:

import uuid

path = "/trade-api/v2/portfolio/events/orders"
order = {
    "ticker": ticker,
    "client_order_id": str(uuid.uuid4()),
    "side": "bid",
    "count": "10.00",
    "price": "0.5600",
    "time_in_force": "good_till_canceled",
    "self_trade_prevention_type": "taker_at_cross",
    "post_only": True,
}
print(requests.post(BASE + path, headers=signed("POST", path), json=order).json())

client_order_id lets you spot a duplicate if a request times out and you send it again. time_in_force can also be fill_or_kill or immediate_or_cancel, and to make an order expire you set expiration_time. The demo has different tickers from production, so read a market from the host you're trading on.

Rate limits

Kalshi's limits are budgets of tokens per second, and most requests cost 10 tokens.

TierRead (tokens a second)Write (tokens a second)Reads a secondWrites a second
Basic2001002010
Advanced3003003030
Expert6006006060

Basic comes with sign-up, and Advanced is one call to an upgrade endpoint. Higher tiers depend on your share of trading volume.

Fees

The taker fee is 0.07 × contracts × price × (1 − price), rounded up to the cent. Makers pay nothing by default, though some markets charge them. The fee calculator works it out at any price. The fee is only part of what a trade costs, because you also pay the spread.

Test your bot

The demo is the place to test your signing and your orders. Kalshi warns that its prices and behavior "may not be reflective of those in real markets", so it can't tell you whether your strategy has an edge. To run a quoting bot against live-moving prices with practice money and no sign-up, try Rizon's API, or compare the options in where to test a trading bot without real money. It's a different contract, so it tests your logic rather than Kalshi's matching.

FAQ

Do I need a key to read Kalshi's market data?

No. Series, events, markets and order books are public. The WebSocket needs a signed connection, even for market data.

Does Kalshi have a demo API?

Yes, at https://external-api.demo.kalshi.co/trade-api/v2, with mock funds and its own sign-up.

Why does the order book only show bids?

Because Yes and No mirror each other. An offer to sell Yes at 57¢ is the same as a bid for No at 43¢, so Kalshi lists both as bids.

Is there an official Kalshi Python SDK?

The kalshi-python package exists on PyPI, but the current release we found is about a year old and uses the older order format, and we couldn't confirm who maintains it. The docs' samples work without it.

Which key type should I use?

Ed25519, which Kalshi recommends. Use RSA only if your client can't do anything else.

More from Learn

  1. Polymarket API in Python: read markets, stream books and place orders

    Use Polymarket's API in Python with polymarket-client. Read markets and order books with no key, stream prices, place limit orders and avoid the old clients.

    3 min read
    • polymarket
    • api
    • python
    • developers
    • bots
  2. How to build a trading bot with Claude Code, and test it without risking money

    A prompt that builds a working market maker in minutes, a free place to run it on a real order book, and a straight answer on whether it will make money.

    4 min read
    • claude
    • bots
    • api
    • developers
  3. A quant project for your resume: build a market maker on a live order book

    The project that shows what trading firms test for. Build a market maker, run it on a live book with paper money, and measure where its money went.

    4 min read
    • quant
    • market-making
    • career
    • bots