If you want to pull Kalshi market prices into your own script, spreadsheet, or dashboard, the Kalshi API is the place to start. The good news for beginners: reading public market data does not require an API key. This tutorial walks through the base URL, the main market-data endpoints, a short Python example using requests, and a plain-English overview of how authenticated requests work when you are ready for them.
Note: Everything below was checked against Kalshi's official documentation at docs.kalshi.com in October 2026. APIs change, so always confirm details in the current docs before you build on them.
What you need before you start
- Python 3 installed on your computer
- The
requestslibrary (pip install requests) - No Kalshi account or API key for the public examples in this guide
The Kalshi API base URL
Kalshi's REST API lives under a versioned path. According to the official docs, the production base URL is:
https://external-api.kalshi.com/trade-api/v2
The docs also list https://api.elections.kalshi.com/trade-api/v2 as a supported production host. For testing, Kalshi runs a separate demo environment with mock funds at https://external-api.demo.kalshi.co/trade-api/v2. Demo credentials are not shared with production, so you need a separate demo account if you want to test authenticated calls there.
Public market-data endpoints (no auth needed)
Kalshi's market data quick start uses these endpoints without any authentication headers:
| Endpoint | What it returns |
|---|---|
GET /markets |
A paginated list of markets. Filter with series_ticker, event_ticker, status, tickers, and more. limit defaults to 100 (max 1000), and a cursor is returned for the next page. |
GET /markets/{ticker} |
A single market by its ticker. |
GET /markets/{ticker}/orderbook |
Resting bids for that market. Optional depth (0 to 100; 0 returns all levels). |
GET /events/{event_ticker} |
An event and the markets inside it. |
GET /series/{series_ticker} |
Information about a series (a recurring group of events). |
Understanding tickers
Kalshi organizes data in three layers: a series (for example, a recurring daily question), an event (one specific instance of it), and markets (the individual yes/no contracts inside the event). The official quick start uses the series KXHIGHNY (daily high temperature in New York) as its example, so we will use it too.
Prices are returned as dollar strings
In the current API, market prices come back as strings in dollars with a _dollars suffix, such as yes_bid_dollars, yes_ask_dollars, no_bid_dollars, no_ask_dollars, and last_price_dollars. Sizes and volume use an _fp suffix, such as volume_fp. Convert them with float() or Decimal() before doing math.
Python example: get Kalshi market prices
This short script lists a few open markets in a series, fetches one market by ticker, and reads its orderbook. It uses only public endpoints.
import requests
BASE_URL = "https://external-api.kalshi.com/trade-api/v2"
# 1) List open markets in a series
resp = requests.get(
f"{BASE_URL}/markets",
params={"series_ticker": "KXHIGHNY", "status": "open", "limit": 5},
timeout=10,
)
resp.raise_for_status()
markets = resp.json()["markets"]
for m in markets:
print(
m["ticker"],
m.get("yes_sub_title"),
"yes bid:", m.get("yes_bid_dollars"),
"yes ask:", m.get("yes_ask_dollars"),
"last:", m.get("last_price_dollars"),
)
# 2) Get one market by ticker
ticker = markets[0]["ticker"]
market = requests.get(f"{BASE_URL}/markets/{ticker}", timeout=10).json()["market"]
print("Status:", market["status"], "Closes:", market["close_time"])
# 3) Read the orderbook (bids only)
ob = requests.get(
f"{BASE_URL}/markets/{ticker}/orderbook",
params={"depth": 5},
timeout=10,
).json()["orderbook_fp"]
yes_bids = [float(price) for price, size in ob["yes_dollars"]]
no_bids = [float(price) for price, size in ob["no_dollars"]]
if yes_bids:
print("Best YES bid:", max(yes_bids))
if no_bids:
# A NO bid at price X is equivalent to a YES ask at 1 - X
print("Implied best YES ask:", round(1 - max(no_bids), 4))
If there are no open markets in the series when you run it, markets will be empty, so add a check before indexing in real code.
Why the orderbook only shows bids
Kalshi's orderbook response returns two arrays, yes_dollars and no_dollars, and each contains bids only. Each level is a two-item array of a price and a contract count. Because a yes/no contract pays out $1 to one side, a bid to buy NO at 94 cents is economically the same as an offer to sell YES at 6 cents. That is why the script computes the implied YES ask as 1 - best NO bid. Using max() keeps it correct however the levels are sorted.
Paging through results
The /markets response includes a cursor. Pass it back as the cursor query parameter to get the next page. When it comes back empty, you have reached the end.
How Kalshi API key authentication works
Placing orders, checking balances, and viewing positions require an API key. Kalshi does not use a simple bearer token. Instead, every authenticated request is signed with a private key that stays on your computer. Per the docs:
- You create an API key in your Kalshi account and receive a Key ID plus a private key. Store the private key securely and never share it.
- Each request includes three headers:
KALSHI-ACCESS-KEY(your Key ID),KALSHI-ACCESS-TIMESTAMP(the current time in milliseconds), andKALSHI-ACCESS-SIGNATURE. - The signature is made by concatenating the timestamp, the HTTP method, and the request path (without query parameters), for example
1700000000000GET/trade-api/v2/portfolio/balance, signing that string with your private key, and base64-encoding the result. - For RSA keys, the algorithm is RSA-PSS with SHA-256 (MGF1 with SHA-256, salt length equal to the digest length). The docs also support Ed25519 keys and list them as recommended.
If you would rather not write signing code yourself, Kalshi publishes official SDKs: kalshi_python_sync and kalshi_python_async for Python, and kalshi-typescript for TypeScript. The docs note the older kalshi-python package is deprecated.
Practical tips
- Respect rate limits. Kalshi sets separate read and write limits that depend on your account tier. Avoid tight polling loops.
- Use the demo environment to test any code that places orders.
-
Handle errors with timeouts and
raise_for_status(). - Check the changelog. Field names have changed over time.
Prefer not to code it yourself? DeskBot is desktop software for Mac and Windows that connects to your own Kalshi account through Kalshi's official API, shows live 15-minute market prices, and starts in paper mode so you can test your own rules and limits first. See how DeskBot works, or start for $1 — then $19.99/month.
Trading involves risk; you can lose money. DeskBot is independent software, not affiliated with or endorsed by Kalshi.
FAQ
Do I need an API key to get Kalshi market prices?
No. Kalshi's documentation shows market data endpoints such as GET /markets and GET /markets/{ticker}/orderbook being called without authentication headers. You need a key for account actions like placing orders or checking your balance.
Is there an official Kalshi Python library?
Yes. Kalshi's SDK page lists kalshi_python_sync and kalshi_python_async on PyPI. You can also call the REST API directly with requests, as shown above.
Can I test trading code without real money?
Yes. Kalshi offers a demo environment with mock funds and separate credentials. Point your code at the demo base URL while you test.