Polymarket vs Kalshi API: A Developer's Side-by-Side Guide (Auth, CLOB, WebSocket, Historical Data)

Sarah ChoyPublished May 3, 202611 min read
Polymarket vs Kalshi API: A Developer's Side-by-Side Guide (Auth, CLOB, WebSocket, Historical Data)

Polymarket and Kalshi run the same primitive — yes/no contracts on a CLOB — through completely different APIs. One demands EIP-712 signatures and a Polygon wallet; the other is a REST endpoint with optional FIX. If you're building a forecasting agent, an arbitrage bot, or a smart-money monitor, here's the side-by-side guide that should already exist.

TL;DR

  • Polymarket uses EIP-712-signed orders submitted to its CLOB on Polygon — wallet onboarding and gas fees apply.
  • Kalshi uses standard REST + WebSocket auth (email/password → token), plus an optional FIX gateway for institutional users.
  • Both expose order book, trades, and historical data, but the schema and resolution semantics differ enough that 'unified' libraries are the most-requested HN Show HN topic in this corner of crypto/quant tooling.
  • Cross-venue arbitrage between equivalent contracts is the most common build pattern (10+ open-source bots on GitHub).
  • API Pick Prediction Markets Search wraps both venues in one POST endpoint for natural-language contract discovery — 50 credits per call, ranked semantic results.

Why this article exists

If you've spent any time building on prediction markets, you know the canonical request: 'I want to query Polymarket and Kalshi from the same Python script and get back a clean list of matching contracts.' The HN comment thread on every prediction-market Show HN inevitably converges on this — there's a recurring pattern of "CCXT for prediction markets" posts, indicating the demand exists and the existing solutions don't quite hit the mark.

The difficulty is real. The two venues solve the same primitive — binary "yes/no" contracts on a central limit order book — but expose them through dramatically different APIs. Here's a working developer's view of both, side by side, with the code you actually need.

Two venues, two architectures

Polymarket

  • Chain: Polygon (USDC.e settlements)
  • Auth: EIP-712 typed-data signing with a wallet private key; no traditional bearer token
  • Order placement: signed order submitted to CLOB API; gas paid by Polymarket via meta-transactions
  • Market discovery: Gamma API (REST + JSON) for browsing active markets, plus a separate CLOB API for live order book
  • Real-time data: WebSocket stream for order book updates and trades
  • Historical data: REST endpoints for trades; daily snapshots downloadable separately

Kalshi

  • Settlement: USD via ACH and wire (US bank required)
  • Auth: email + password → bearer token, OR API key (institutional)
  • Order placement: standard authenticated REST POST to /portfolio/orders
  • Market discovery: REST endpoints for events, markets, and series; clean schema
  • Real-time data: WebSocket and FIX (institutional) for fills, order book, ticker
  • Historical data: REST endpoints for trades; market resolution and settlement data straightforward

Side by side

Architectures change. Verify rate limits, fees, and KYC requirements with each venue's docs before integration.
PolymarketKalshiAPI Pick
AuthEIP-712 signed orders + Polygon walletEmail/password → bearer; or API keyx-api-key header (read-only discovery)
SettlementUSDC on PolygonUSD bank transfer (US-only)n/a (search only)
US legalityGeofenced (not US)CFTC-regulatedn/a
Real-timeWebSocketWebSocket + FIXn/a
HistoricalREST trades + snapshotsREST trades + settlementSearch returns links to source
Best fitCrypto-native, global markets, smart-money trackingUS-regulated, election & economicsCross-venue contract discovery

Working code: hello-world on each

Polymarket: list active markets

import requests

# Gamma API — no auth required for browsing
r = requests.get(
    "https://gamma-api.polymarket.com/markets",
    params={"active": "true", "limit": 25, "order": "volume"},
)
markets = r.json()
for m in markets[:5]:
    print(m["question"], "→", m["outcomePrices"])

Polymarket: place a signed order (sketch)

# Full order placement requires py-order-utils + a Polygon wallet
# This is the structural sketch — not runnable without wallet setup
from py_order_utils.builders import OrderBuilder
from py_order_utils.signer import Signer

signer = Signer(private_key="0xYOUR_PRIVATE_KEY")
builder = OrderBuilder(
    exchange_address="0x...",
    chain_id=137,
    signer=signer,
)

order = builder.build_signed_order({
    "maker": signer.address(),
    "tokenId": "...",        # the yes/no token ID for the market
    "makerAmount": "1000000", # USDC.e in atomic units
    "takerAmount": "1500000",
    "side": "BUY",
    "feeRateBps": 0,
    "nonce": 0,
    "expiration": 0,         # 0 = no expiry
})

requests.post(
    "https://clob.polymarket.com/order",
    json={"order": order, "owner": signer.address(), "orderType": "GTC"},
)

Kalshi: log in and place a limit order

import requests

# Step 1 — login
r = requests.post(
    "https://api.elections.kalshi.com/trade-api/v2/login",
    json={"email": "you@example.com", "password": "..."},
).json()
token = r["token"]
headers = {"Authorization": f"Bearer {token}"}

# Step 2 — list markets in an event
r = requests.get(
    "https://api.elections.kalshi.com/trade-api/v2/markets",
    params={"event_ticker": "POTUS-2028", "limit": 25},
    headers=headers,
).json()
print(r["markets"][:5])

# Step 3 — place a limit buy on the "Yes" side at 60 cents
r = requests.post(
    "https://api.elections.kalshi.com/trade-api/v2/portfolio/orders",
    headers=headers,
    json={
        "ticker": "POTUS-2028-DEM",
        "type": "limit",
        "action": "buy",
        "side": "yes",
        "count": 100,            # 100 contracts
        "yes_price": 60,         # 60 cents
        "client_order_id": "abc123",
    },
)
print(r.json())

API Pick: natural-language discovery across both

import requests

r = requests.post(
    "https://www.apipick.com/api/search/prediction-markets",
    headers={"x-api-key": "pk_yourkey"},
    json={"query": "Federal Reserve rate cuts before end of 2026"},
)
for hit in r.json()["results"][:5]:
    print(hit["title"], "@", hit["venue"], "→", hit["url"])

# Returns ranked matches across Polymarket + Kalshi.
# 50 credits per call (~$0.05), only on HTTP 200.

Three production patterns that actually work

1. The cross-venue arbitrage bot

The most common pattern on GitHub: a curated whitelist of "this Polymarket contract resolves on the same outcome as this Kalshi contract." The bot watches both books, computes implied probability, and takes a position when the spread crosses a threshold. Examples: ImMike/polymarket-arbitrage and realfishsam/prediction-market-arbitrage-bot.

The hard part is the whitelist. "Will the Fed cut by 25 bps at the December meeting" looks the same to a human but the resolution sources and exact wording differ; an automated matcher gets it wrong often enough that real bots use human-curated mappings.

2. The smart-money monitor

Whales on Polymarket are visible on-chain. A monitor watches Polygon for large order flow on specific markets, surfaces big positions, and flags rapid price moves before headlines hit news APIs. Pair with News Search to confirm whether an apparent move is news-driven or pure speculation.

3. The forecasting feed for an LLM agent

Pulling current Polymarket / Kalshi prices into an LLM agent's context lets the model give probability-grounded answers: "current betting markets imply ~65% probability of X". This is the discovery use case API Pick covers — given a natural-language question from the agent, return ranked contracts so the agent can quote the price in its answer.

Common pitfalls (compiled from HN comments)

  • Polymarket EIP-712 signing — the order signature is deterministic but tooling errors are common. Use py-order-utils rather than rolling your own. Most early bot losses come from signature mismatches the API silently rejects.
  • Kalshi rate limits — documented at 100 req/sec but lower for some endpoints during busy event days (election nights, FOMC). Build retry-with-backoff into your client.
  • Polymarket gas spikes — Polygon gas can jump on big-volume days. Polymarket subsidises most order placement via meta-transactions but settlement and withdrawal are user-pays. Account for this in P&L calculations.
  • Settlement mismatches — apparent equivalents sometimes resolve differently. Always read the resolution-source clauses of both contracts before pair-trading.
  • WebSocket disconnects — both venues have routine WebSocket flaps. Reconnect logic with sequence-number replay is non-negotiable for any production bot.

Choosing fast

Best for: US-regulated trading
Kalshi. CFTC oversight, USD settlement, no crypto onboarding. The right answer for any product targeting US users.
Best for: crypto-native, global, smart-money tracking
Polymarket. Polygon-native means on-chain order flow is observable; broader event coverage especially in geopolitics, crypto, and entertainment.
Best for: cross-venue arbitrage
Both, paired. Build the bot against one (usually Kalshi for cleaner auth) first; add Polymarket once your matching logic is solid.
Best for: natural-language contract discovery in an LLM agent
API Pick Prediction Markets Search. One POST, returns ranked matches across both venues, 50 credits per call, only on success. Try it →

Where this is heading

Prediction markets are getting an unusual amount of mainstream attention right now: bigger volumes around US elections, FOMC events, sports, and AI-takeoff questions; broader integrations with news sites that surface implied probabilities; and a wave of developer tooling (Show HNs, GitHub repos) that converges on the same theme — 'someone should write CCXT for prediction markets.'

We don't think a CCXT-style unified-execution library is the right shape. The differences in auth, settlement, and regulatory regime are too deep to abstract cleanly without lying to the user. But the discovery problem — given a natural-language question, find the contracts that already exist — is solvable with semantic search, and that's what API Pick Prediction Markets Search does. Find the contract; place the order at the venue.

Frequently Asked Questions

Which venue has more contracts?

As of writing, both list tens of thousands of active markets. Polymarket skews crypto-native and global (politics, sports, crypto, current events); Kalshi is CFTC-regulated and US-focused (elections, economics, weather, sports). Volume distribution varies by category — for US elections Kalshi is typically deeper; for global politics and crypto-native questions Polymarket is.

Why do open-source 'unified' libraries keep popping up on Show HN?

Because the demand exists and nobody has solved it well. Show HN posts like 'Open-source library to unify Polymarket and Kalshi APIs' and 'dr-manhattan — CCXT for Prediction Markets' are recurring patterns. The challenge is matching equivalent contracts (same outcome, different wording) and reconciling settlement semantics. Libraries usually nail the auth wrapper but stop short of contract matching.

How do I do basic cross-venue arbitrage?

Conceptually: find two contracts that resolve on the same outcome on different venues, check the implied probabilities, take the higher-priced 'No' side and the lower-priced 'Yes' side, hold until resolution. In practice the friction is execution: Polymarket gas fees, Kalshi USD funding, partial fills, and the matching problem above. Most live arbitrage bots on GitHub run on a curated whitelist of contract-pair mappings rather than discovering them automatically.

Is Polymarket legal in the US?

Polymarket is not currently authorized for US users; access is geofenced. Kalshi is CFTC-regulated and US-legal. If you're building a product for US users, Kalshi is the only option. If you're building globally, Polymarket carries broader market coverage.

Where does API Pick fit in this stack?

API Pick Prediction Markets Search solves the 'discovery' problem: given a natural-language question (e.g. 'Fed cuts rates by year-end'), it returns ranked semantic matches across Polymarket and Kalshi contracts in one POST call. We don't replace the order-execution APIs — for placing orders you still go to each venue directly. We make finding the right market easy.

APIs used in this article

Written by
Sarah Choy
CEO, API Pick

Sarah Choy is the CEO of API Pick. She writes about building production-ready APIs for AI agents and LLM workflows.