ANCHOR 163 // home
// guides

The Kalshi API, as it behaves in practice.

What the docs say, and what happened when we ran automated systems against the Kalshi API with our own capital.

// on this page · 8 sections
Kalshi is a regulated exchange for event contracts. Most builders use two parts of its API: REST for requests and orders, and a WebSocket for live data. Larger firms can also connect over FIX, an older financial messaging standard.
Each section below gives the current answer from Kalshi's documentation, checked in September 2026, then what we learned running it. Kalshi changes limits and hosts from time to time, so treat their docs as the final word on numbers.

Getting access and signing requests

Create a key

Generate a key pair in your Kalshi account settings under API Keys, or through the API itself. Kalshi keeps the public half. The private key stays on your machine.
Ed25519 keys are the recommended type. RSA keys (2048-bit) still work.

Sign every request

Each private request carries three headers: KALSHI-ACCESS-KEY (your key ID), KALSHI-ACCESS-TIMESTAMP (the time in milliseconds) and KALSHI-ACCESS-SIGNATURE. The signature covers the timestamp, the HTTP method and the path, joined together.
With an RSA key, the signature is RSA-PSS with SHA-256, and the salt length equals the digest length.

Sign the path without the query string

For a request to /trade-api/v2/portfolio/orders?limit=5, you sign /trade-api/v2/portfolio/orders only.
This is the classic first bug. Requests without parameters work, and every request with parameters fails authentication, which looks like a key problem when it is a string problem.

The WebSocket signs the same way

Opening the WebSocket connection is authenticated with the same three headers and the same signature. Write one signing function and use it in both places.

Demo and production

Two separate environments

Production REST is external-api.kalshi.com/trade-api/v2. Demo REST is external-api.demo.kalshi.co/trade-api/v2, with matching WebSocket hosts for each. Older hosts still work for backward compatibility.

Keys do not cross over

Demo keys only work against demo, and production keys only against production. A key that works in one environment and fails in the other is usually in the wrong place.

Demo tests plumbing, not fills

Demo order books are thin and move fast. When we ran there, orders kept going out and almost nothing filled.
The engine was fine. Our own slippage guard was refusing prices in a thin book, as designed. Use demo to prove signing, order flow and error handling. Judge fills in production, at the smallest size you can.

Rate limits and tiers

Limits are a token budget

Every request spends tokens from a budget that refills each second. Most requests cost 10 tokens. Reads and writes draw from separate buckets, so heavy data polling does not block your orders.
A few endpoints cost more or less. Batch cancels cost 2 tokens per order. The current list is at GET /account/endpoint_costs.

Tiers

Basic gives 200 read and 100 write tokens a second, which is about 20 reads and 10 orders at the default cost. Advanced is 300 and 300. Above that, Expert through Prestige run from 600 up to 12,000 read.
You move from Basic to Advanced by calling an upgrade endpoint. Higher tiers come automatically with trading volume.

A 429 tells you nothing

Going over the limit returns 429 Too Many Requests, with no header saying when to try again.
So your client needs its own backoff, and it should back off harder on writes than on reads. An order retried blindly in a tight loop is how a rate limit turns into a duplicate position.

Is the Kalshi API free?

There is no charge for API access. Several market-data endpoints need no key at all. Trading through the API pays the same exchange fees as trading on the site, so check Kalshi's current fee schedule before sizing anything.

Live data: WebSocket or polling

Poll for slow things

Market lists, settlements and your account balance change slowly. Polling them on a timer is simpler and spends read tokens you usually have spare.

Stream for fast things

Order books and fills move in fractions of a second. Polling them burns your read budget and still arrives late. Use the WebSocket for anything you act on.

Never fill in a missing price

WebSocket messages sometimes arrive without the price for the side you hold. Our code once fell back to the other side's price.
A NO contract bought at 1 cent got recorded at 99 cents. That produced a phantom win and a phantom loss, each many times larger than the real trade. If a field is missing, mark the record incomplete and fetch the truth from the exchange.

Reconciling fills: what the docs do not cover

Your own records will drift from the exchange's. Positions get stuck after a dropped connection, prices get recorded from the wrong side, and a restart can count a trade twice. None of it shows up as an error. It shows up as a profit number that is not real.
  1. Treat the exchange's fill and settlement records as the truth, and your database as a claim about them.
  2. Reconcile on a schedule. Anything the exchange no longer shows, close in your records, and log what happened.
  3. Base your drawdown stop on realized results only. A price you marked yourself once tripped a false halt for us.
  4. Make a halt something only a person can clear. A system that restarts itself into the same fault will do it again.
  5. Test that every limit in your config is actually enforced. We had a maximum-orders-per-hour setting that the code never read.

Where we come in

We build the operating layer on top of this API for traders and firms. That means order state that survives a disconnect, and positions reconciled to the exchange's own records. Details are on the Kalshi API integration page. We do not sell strategies or publish trading results.

Common questions

There is no charge for API access, and several market-data endpoints need no key. Trading through the API pays the same exchange fees as trading on the site.
Limits are a token budget that refills every second. Most requests cost 10 tokens, and reads and writes use separate budgets. The Basic tier gets 200 read and 100 write tokens a second; higher tiers come with an upgrade call or with trading volume. Going over returns HTTP 429 with no retry header.
Create one in your Kalshi account settings under API Keys, or through the API. Ed25519 keys are recommended; RSA keys also work. Keep the private key on your own machine.
Yes. Demo runs on its own hosts with mock funds, and its keys do not work in production. Demo order books are thin, so use it to test signing and order flow rather than fills.
Usually because the query string was included in what you signed. Sign the timestamp, the method and the path without the query parameters.