// COMPARE
Kalshi API vs Polymarket API for bot builders
Kalshi and Polymarket list overlapping events, and that's roughly where the similarity ends for a bot builder. Kalshi's API is a conventional exchange API: keys, signed requests, JSON orders. Polymarket's is a crypto-native CLOB: wallet keys, EIP-712 typed data, on-chain settlement. If you're writing one bot for both, this page is the map of everything that doesn't line up. (For the trader-level comparison — regulation, fees, liquidity — see Kalshi vs Polymarket.)
The shape of each API
Kalshi exposes REST + WebSocket at
api.elections.kalshi.com/trade-api/v2. You generate an API key in your
account settings, sign each request, and hit resources like GET /markets
and POST /portfolio/orders. One service, one auth story.
Polymarket is two services. Gamma
(gamma-api.polymarket.com) serves market metadata and prices with no
auth — ideal for research. The CLOB (clob.polymarket.com) takes
orders: EIP-712 typed-data messages signed with a wallet key, matched
off-chain by the operator, settled on-chain on Polygon.
Auth models
| Kalshi | Polymarket | |
|---|---|---|
| Credential | Exchange-issued API key | Wallet private key (L1) → derived API creds (L2) |
| Per-request | Request signing with the key | L2 creds on REST; each order is EIP-712 signed with the wallet key |
| Blast radius if leaked | Trading access (revocable at the exchange) | The funds in the wallet |
| Rotation | Reissue the key in settings | Rotating means moving funds to a new wallet |
The Polymarket model means your bot holds a key that is the money — a compromised box isn't an API incident, it's a theft. This asymmetry drives most of the custody design for trading agents; see agent custody and risk limits for AI trading agents.
ID schemes and price formats
| Kalshi | Polymarket | |
|---|---|---|
| Market ID | Human-readable ticker: FED-26SEP-T4.00 | Hex condition_id: 0x26d06d9c... |
| Outcome ID | side: "yes" / "no" on the order | Separate ERC-1155 token_id per outcome |
| Price format | Integer cents, 1–99 | Decimal, 0.01–0.99 |
| "Sell YES" | Sell on the yes side | Trade the YES token (or buy NO — a different token) |
Two traps here. First, nothing links a Kalshi ticker to the Polymarket
market for the same real-world event — cross-venue matching is manual
work or a unified ID layer. Second, the price
formats invite silent bugs: 42 is a valid Kalshi price and 0.42 a
valid Polymarket price, and sending one venue's format to the other's
range-checks can fail loudly if you're lucky and subtly if you're not.
Normalize to one internal representation at the boundary.
Placing an order, side by side
Kalshi — a signed JSON POST:
POST /trade-api/v2/portfolio/orders
{
"ticker": "FED-26SEP-T4.00",
"action": "buy",
"side": "yes",
"type": "limit",
"count": 100,
"yes_price": 42
}
Polymarket — build, sign, and post a typed-data order (via
py-clob-client):
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs
client = ClobClient(host, key=PRIVATE_KEY, chain_id=137)
client.set_api_creds(client.create_or_derive_api_creds())
order = client.create_order(OrderArgs(
token_id=YES_TOKEN_ID,
price=0.42,
size=100,
side="BUY",
))
client.post_order(order)
Same trade, different worlds: one is a request you authenticate, the other is a message you sign — cryptographically committing to price, size, and expiry before the operator ever sees it. Step-by-step walkthroughs: Kalshi API guide and Polymarket CLOB API guide.
Order lifecycle and failure semantics
On Kalshi, an order rests on the book until filled, cancelled, or expired, and the exchange reports its state transitions through the API and WebSocket fills channel — a classic exchange lifecycle.
On Polymarket, matching is off-chain but settlement is on-chain: a "matched" order still has a settlement step on Polygon. Cancels are API-level (fast in practice), but your definitive position is what's on chain. Partial fills, expirations baked into the signed order, and the gap between "matched" and "settled" all need explicit handling.
The sharpest edge is retries. Error codes, timeout behavior, and idempotency guarantees differ between the venues — retry logic written for one can double-submit on the other. Treat "did my order actually reach the book?" as a first-class state machine per venue, not an afterthought. War stories in rate limits and order types.
WebSockets and market data
Both venues offer WebSocket feeds for order books and trades, and both still make you do the classic exchange-feed work: subscribe, maintain a local book from deltas, detect gaps, resync from a REST snapshot. The channel names, message schemas, and sequencing rules differ — expect to write (or vendor) two feed handlers, not one with a config flag. For metadata-heavy work (search, screening), Polymarket's unauthenticated Gamma API is a genuine convenience Kalshi has no equivalent of.
Rate limits
Both venues enforce rate limits; neither guarantees the same numbers over time, and tiers can vary by account or access level — check the current docs rather than hardcoding numbers from a blog post (including this one). The portable engineering advice: centralize throttling per venue, back off on 429s, and never let a retry loop and a rate limiter argue with each other. Details and patterns in rate limits, order types, and websockets.
Bottom line for bot builders
| Dimension | Kalshi | Polymarket |
|---|---|---|
| Mental model | Classic exchange API | Crypto CLOB, on-chain settlement |
| Auth | API key + request signing | Wallet key + EIP-712 orders |
| IDs | Tickers | Condition IDs + token IDs |
| Prices | Cents (int) | Decimals |
| Settlement | At the exchange | USDC on Polygon |
| Key risk | Revocable credential | The key is the funds |
A read-only bot against either venue is a weekend project. A production bot
trading both — normalized IDs and prices, two auth stacks, two lifecycle
state machines, two feed handlers, per-venue throttling — is a multi-month
build you then maintain as both APIs evolve. That's the integration
Mithril packages behind one REST API and a
hosted MCP server, with unified mkt_ IDs and server-side risk limits.
Build or buy, the Python bot walkthrough
shows what the code looks like either way.
APIs change. Details above reflect public documentation as of July 2026 — always confirm against the venues' own docs before trading real money.
One API + MCP for Kalshi and Polymarket
Skip the double integration: unified market IDs, fee-aware routing, and hard server-side risk limits — live today, free during beta.