Polymarket vs Kalshi: Complete API Comparison for Developers
A detailed comparison of Polymarket and Kalshi APIs for developers — covering architecture, data formats, authentication, rate limits, market coverage, and when to use each platform.
Introduction
Polymarket and Kalshi are the two largest prediction market platforms, but they take fundamentally different approaches to almost everything — regulation, currency, market structure, and critically for developers, their APIs.
If you're building an application that consumes prediction market data, choosing between Polymarket vs Kalshi (or integrating both) is one of the first decisions you'll make. This comparison covers every dimension that matters for API integration: architecture, data formats, authentication, rate limits, market coverage, and developer experience.
We'll also explain when it makes sense to skip the comparison entirely and use a unified API that normalizes both platforms into a single interface.
Platform Overview
Before diving into API specifics, here's the high-level picture:
| Feature | Polymarket | Kalshi |
|---|---|---|
| Founded | 2020 | 2021 |
| Regulation | Unregulated (crypto-native) | CFTC-regulated exchange |
| Currency | USDC (stablecoin) | USD (fiat) |
| US Access | Limited | Full |
| Primary Focus | Politics, crypto, current events | Economics, weather, politics |
| Cumulative Volume | $10B+ (2025) | $2B+ (2025) |
| Blockchain | Polygon (Ethereum L2) | None (centralized) |
| Resolution | UMA Protocol (decentralized oracle) | Centralized team + public sources |
| Min Trade | ~$1 | $1 |
Polymarket leads in liquidity and volume, especially for political and crypto markets. Kalshi leads in regulatory compliance and breadth of market categories — it's the only CFTC-regulated prediction market exchange in the United States.
API Architecture Comparison
Polymarket API
Polymarket's API is split across multiple services:
| Service | Purpose | Auth |
|---|---|---|
| CLOB API | Order book, trading | API key + signature |
| Gamma API | Market metadata, search | Public (no auth for reads) |
| Subgraph (The Graph) | Historical data, on-chain events | Public GraphQL |
For read-only market data (which most applications need), the Gamma API is the primary entry point. Trading requires the CLOB API with cryptographic signatures.
Base URLs:
Gamma API: https://gamma-api.polymarket.com
CLOB API: https://clob.polymarket.com
Kalshi API
Kalshi provides a single, unified REST API:
| Service | Purpose | Auth |
|---|---|---|
| REST API v2 | Everything (markets, trading, account) | API key + secret |
Kalshi's approach is simpler — one API, one authentication method, one set of documentation.
Base URL:
REST API: https://trading-api.kalshi.com/trade-api/v2
Architecture Summary
| Aspect | Polymarket | Kalshi |
|---|---|---|
| API Style | Multiple services | Single unified API |
| Protocol | REST + GraphQL | REST only |
| Real-Time | WebSocket (CLOB) | WebSocket |
| Complexity | Higher (multiple endpoints) | Lower (one API) |
| Documentation | Community-maintained + official | Official, well-structured |
Data Format Differences
This is where the platforms diverge most significantly. Let's compare how each represents the same market.
Market Object
Polymarket (Gamma API):
{
"id": "21742",
"condition_id": "0x1a2b3c...",
"question": "Will Bitcoin reach $150,000 by end of 2026?",
"outcomes": "[\"Yes\", \"No\"]",
"outcomePrices": "[\"0.42\", \"0.58\"]",
"volume": "2450000.50",
"active": true,
"closed": false,
"category": "Crypto",
"end_date_iso": "2026-12-31T23:59:59.000Z",
"image": "https://polymarket-upload.s3.us-east-2.amazonaws.com/..."
}
Kalshi:
{
"ticker": "BTC-150K-26DEC31",
"event_ticker": "BTC-150K-2026",
"title": "Bitcoin above $150,000 on December 31?",
"yes_bid": 41,
"yes_ask": 43,
"no_bid": 57,
"no_ask": 59,
"volume": 15230,
"open_interest": 8500,
"status": "active",
"category": "Financials",
"close_time": "2026-12-31T20:00:00Z"
}
Key Differences in Data Format
| Field | Polymarket | Kalshi |
|---|---|---|
| Identifier | Numeric ID + condition hash | Ticker string |
| Prices | Decimal strings ("0.42") | Integer cents (42) |
| Outcomes | JSON string array | Implicit (yes/no bid/ask) |
| Volume | USD string | Contract count (integer) |
| Status | active + closed booleans | status string field |
| Categories | Free-form string | Structured taxonomy |
| End Date | end_date_iso (ISO string) | close_time (ISO string) |
The pricing difference is the most impactful for developers. Polymarket gives you outcome probabilities as decimal strings in a parallel array. Kalshi gives you bid/ask spreads as integer cents. To get a comparable probability from Kalshi, you need to calculate the midpoint: (yes_bid + yes_ask) / 2 / 100.
For a deeper look at how these formats are unified into a single schema, see our data normalization guide.
Authentication
Polymarket
Read-only (Gamma API): No authentication required for market data. You can fetch markets, prices, and metadata without any API key.
Trading (CLOB API): Requires an API key, API secret, and API passphrase. Requests must include cryptographic signatures (HMAC) and EIP-712 typed data signatures for order placement.
# Polymarket read — no auth needed
import requests
response = requests.get("https://gamma-api.polymarket.com/markets?limit=10")
# Polymarket trading — complex auth
from py_clob_client.client import ClobClient
client = ClobClient(
host="https://clob.polymarket.com",
key=API_KEY,
chain_id=137, # Polygon
signature_type=2,
)
Kalshi
All requests: Require API key authentication via login endpoint. You receive a token that must be included in subsequent requests.
# Kalshi — auth required for everything
import requests
# Step 1: Login to get token
login = requests.post("https://trading-api.kalshi.com/trade-api/v2/login", json={
"email": "your@email.com",
"password": "your_password"
})
token = login.json()["token"]
# Step 2: Use token for requests
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(
"https://trading-api.kalshi.com/trade-api/v2/markets",
headers=headers
)
Authentication Summary
| Aspect | Polymarket | Kalshi |
|---|---|---|
| Read-Only | No auth needed | Auth required |
| Trading | API key + crypto signatures | API key + token |
| Complexity | High (crypto wallet needed) | Medium (email/password) |
| Token Refresh | N/A | Required periodically |
Rate Limits
| Tier | Polymarket (Gamma) | Kalshi |
|---|---|---|
| Public/Free | ~10 req/sec | Varies by endpoint |
| Authenticated | Higher limits | Higher limits |
| WebSocket | Available | Available |
| Pagination | Cursor-based | Cursor + limit/offset |
Both platforms will rate-limit aggressive polling. For real-time data, both offer WebSocket connections that are more efficient than polling.
Market Coverage
| Category | Polymarket | Kalshi |
|---|---|---|
| US Politics | Extensive | Extensive |
| International Politics | Strong | Limited |
| Cryptocurrency | Extensive | Moderate |
| Economics (Fed, GDP) | Moderate | Extensive |
| Weather | None | Extensive |
| Sports | Growing | Growing |
| Entertainment | Moderate | Moderate |
| Science/Tech | Moderate | Limited |
| Total Markets | 1,000+ active | 500+ active |
Polymarket's strength is political and crypto markets with deep liquidity. Kalshi uniquely offers weather and economic markets (Fed decisions, jobs reports) that you won't find elsewhere.
Developer Experience
Documentation Quality
Polymarket: Documentation is split across multiple sources — official docs for the CLOB API, community-maintained docs for the Gamma API, and The Graph documentation for subgraph queries. This fragmentation makes onboarding harder.
Kalshi: Comprehensive, centralized documentation with interactive examples and clear API reference. Easier to get started as a developer.
SDK Availability
| Language | Polymarket | Kalshi |
|---|---|---|
| Python | py-clob-client (official) | kalshi-python (community) |
| JavaScript | @polymarket/clob-client | Limited |
| Others | Community libraries | Limited |
Common Pain Points
Polymarket:
- Gamma API responses use JSON strings inside JSON (outcomes and prices are stringified arrays)
- Need a crypto wallet and USDC for trading
- Multiple API services to coordinate
- Rate limits not clearly documented
Kalshi:
- Authentication required even for read-only data
- Token expiration requires refresh logic
- Volume is in contracts, not USD — conversion requires price context
- Smaller market selection overall
When to Use Each Platform
Use Polymarket When:
- You need high-liquidity political/crypto markets
- You only need read-only data (no auth hassle via Gamma API)
- Your users are international (not US-restricted)
- You want on-chain data via The Graph for historical analysis
Use Kalshi When:
- You need CFTC-regulated data for compliance
- You need economic or weather markets (unique to Kalshi)
- Your users are US-based and prefer fiat
- You want a simpler, single-API architecture
Use Both (via Unified API) When:
- You want maximum market coverage across categories
- You're building arbitrage detection that compares prices cross-platform
- You don't want to maintain two separate integrations
- You need normalized data without writing custom parsers
A unified API like Propheseer handles the normalization, authentication, and rate limiting for both platforms (plus Gemini) through a single endpoint. One API key, one data format, one set of rate limits. See how it works in our quick start guide.
Side-by-Side Code Comparison
Here's the same task — fetching open political markets — implemented for each platform:
Direct Polymarket
import requests
import json
response = requests.get("https://gamma-api.polymarket.com/markets", params={
"active": "true",
"category": "Politics",
"limit": 10,
})
markets = response.json()
for market in markets:
prices = json.loads(market["outcomePrices"])
print(f"{market['question']}: {float(prices[0]):.0%} Yes")
Direct Kalshi
import requests
# Login first
login = requests.post("https://trading-api.kalshi.com/trade-api/v2/login", json={
"email": EMAIL, "password": PASSWORD
})
token = login.json()["token"]
response = requests.get(
"https://trading-api.kalshi.com/trade-api/v2/markets",
headers={"Authorization": f"Bearer {token}"},
params={"status": "active", "category": "Political", "limit": 10}
)
markets = response.json()["markets"]
for market in markets:
prob = (market["yes_bid"] + market["yes_ask"]) / 2 / 100
print(f"{market['title']}: {prob:.0%} Yes")
Propheseer (Both Platforms)
import requests
response = requests.get("https://api.propheseer.com/v1/markets",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"category": "politics", "status": "open", "limit": 10}
)
markets = response.json()["data"]
for market in markets:
print(f"[{market['source']}] {market['question']}: {market['outcomes'][0]['probability']:.0%} Yes")
The unified approach eliminates the per-platform quirks: no JSON string parsing, no bid/ask midpoint calculations, no separate auth flows.
Want to access both Polymarket and Kalshi without the integration overhead? Get your free Propheseer API key and start querying both platforms in a single request.