Kalshi API Trading: REST + WebSocket Guide
Kalshi's order book returns bids only. No asks, no midpoint field, just resting bids on both the YES and NO side of each contract. If you're building anything automated on Kalshi API trading, that one design choice is the first thing you need to internalize, because every price you compute downstream depends on decoding it correctly.
What the Kalshi API actually is
Kalshi is a CFTC-regulated Designated Contract Market, and its trading infrastructure is built the way an exchange API is built: REST endpoints for market data and order management, plus a WebSocket connection for live updates. The current base URL is https://api.elections.kalshi.com/trade-api/v2, with external-api.kalshi.com/trade-api/v2 also serving the same surface. Both host the same trade-api/v2 paths, so which one you point at is mostly a matter of preference or network routing.
Every contract on Kalshi has one YES side and one NO side, and the two always sum to $1.00. Prices run $0.01 to $0.99, and each price is a direct probability read: a YES trading at $0.63 means the market is pricing that outcome at roughly 63%. That constraint is what makes the bids-only book workable — you don't need a separate ask feed because the NO side's bids tell you everything the YES asks would.
Reading the order book
The core market-data call is GET /markets/{ticker}/orderbook. It returns resting bid quantities at each price level for both YES and NO. There's no explicit "ask" array because you derive it: a NO bid at $0.35 is mathematically the same commitment as a YES ask at $0.65 ($1.00 − $0.35). If you're used to a traditional two-sided book from equities or forex, this takes a rewrite of your book-building logic, not just a field rename — you're reconstructing a synthetic ask side from the mirrored bid side every time the book updates.
This matters most when you're computing spread or mid-price programmatically. Naively reading "bids" and assuming there's a separate asks endpoint will produce a broken or empty book. Build the YES-ask-from-NO-bid conversion once, test it against a known liquid market, and reuse it everywhere.
How to connect: step by step
- Create API credentials. Set up a Kalshi account and generate the credentials needed for authenticated requests — public market data is more open, but placing orders and reading your own account state requires authentication.
- Pick your base URL. Point your client at
api.elections.kalshi.com/trade-api/v2(or the external-api mirror) and confirm you can hit an unauthenticated markets endpoint before wiring up auth. - Pull markets and the order book. List active markets, then call the per-ticker orderbook endpoint to get live bid depth on both sides.
- Decode bids into a full book. Apply the $1-minus-price conversion so your internal book has both an effective bid and ask side for YES.
- Open the WebSocket. For anything time-sensitive — market making, arbitrage scanning, fast reaction to news — subscribe to the WebSocket feed instead of polling REST. Polling on a tight loop is both slower and the fastest way to hit rate limits.
- Place, track, and cancel orders. Authenticated order endpoints let you submit, monitor fills on, and cancel or replace resting orders as the book moves.
- Design around rate limits. Kalshi enforces rate limits on API calls, as most exchange APIs do. The practical fix is architectural: use WebSocket pushes for anything continuous, batch REST calls where the API allows it, and avoid tight polling loops on order book or market list endpoints.
REST vs. WebSocket: when to use each
| Use case | Best fit | Why |
|---|---|---|
| One-off order placement | REST | Simple request/response, no need for a persistent connection |
| Live order book tracking | WebSocket | Pushed updates avoid polling latency and rate-limit pressure |
| Portfolio/position checks | REST | Infrequent, doesn't need streaming |
| Reacting to fills in real time | WebSocket | Fill events arrive as they happen, not on your next poll |
Order types and what the API expects
Kalshi's order endpoints accept the fields you'd expect from any exchange API: ticker, side (yes/no), action (buy/sell), order type (limit or market), count, and — for limit orders — a price in cents between 1 and 99. Because prices are bounded to that $0.01–$0.99 range by contract design, your client-side validation should reject anything outside it before the API does, which saves a round trip on every malformed order during active development.
Client order IDs are worth setting explicitly rather than letting the API generate them, since a self-assigned ID lets you reconcile local order state against exchange state after a reconnect — the scenario where most home-built bots quietly desync without anyone noticing until a fill shows up that the local book didn't expect.
Test before you route real size
Every step above works the same whether you're testing against a small position or scaling up. The mistake that costs people money isn't a malformed API call — it's shipping a strategy against live capital before you've watched it run through a full session of book updates, fills, and reconnects. Paper trading the exact logic you'll deploy, on the exact data feed you'll use in production, is the cheapest insurance available before real orders go out.
Where this fits into a real workflow
A raw API connection gets you data and order placement — it doesn't get you a strategy. Most people building on Kalshi trading bots spend more time on order book reconstruction and reconnect logic than on the actual edge they're trying to capture. If your goal is faster iteration rather than maintaining your own WebSocket client, a terminal that already normalizes the Kalshi feed — book, candles, open interest — alongside other venues saves that plumbing work.
Skip the plumbing, keep the edge
PolyMarketMaker's desktop terminal pulls Kalshi market data — order-book ladder, candles, open interest — through the same interface as Polymarket and other venues, with an automated quoter that has a kill switch, dead-man switch, and drawdown auto-disarm built in. Useful whether you're testing a manual approach or prototyping something you'll eventually automate yourself against the raw API. PolyMarketMaker runs Simulation at $149/mo or Live Trading at $299/mo.
FAQ
What is the Kalshi API base URL?
The primary REST base is api.elections.kalshi.com/trade-api/v2, with external-api.kalshi.com/trade-api/v2 also in use. Both serve the same trade-api/v2 surface.
Does the Kalshi API support WebSocket streaming?
Yes. REST covers one-off requests; the WebSocket connection delivers live order book and trade updates, which is the standard way to avoid constant polling.
Why does the Kalshi order book only show bids?
The orderbook endpoint returns bids only. Because YES and NO always sum to $1, a NO bid at Y equals a YES ask at ($1 − Y), so the full book reconstructs from bids alone.
Do I need an API key to place orders on Kalshi?
Yes. Authenticated endpoints require API credentials tied to your account. Public market data is more open, but order placement and account data require authentication.
Can I build a Kalshi trading bot with this API?
Yes — REST and WebSocket together cover market data, order placement, and account state, which is the full surface an automated strategy needs, subject to Kalshi's rate limits.
For strategy ideas once your feed is live, see our Kalshi trading guide and Kalshi arbitrage mechanics. If you're comparing venues before you commit engineering time, Polymarket's API works on a different model — on-chain CLOB settlement instead of a bids-only REST book — and Kalshi's fee schedule is worth modeling into your order logic before you go live, since fees scale with how close to 50¢ you're trading.
This article is for educational purposes only and is not financial advice. Trading involves risk of loss.