This is the side-by-side API reference for Polymarket and Kalshi — the two dominant prediction market platforms. Every endpoint, CLI command, and SDK method is documented in parallel so you can find the equivalent operation on each platform without switching between documentation sites.

If you’re building an agent that needs to browse markets, read prices, place bets, manage positions, or stream live data, this page has the exact call you need for each platform. For a deep-dive tutorial on Polymarket specifically, see the Polymarket API Tutorial. For py_clob_client method signatures and return types, see the py_clob_client Reference.

For an overview of how these trading APIs fit into the full agent stack (identity, wallet, trading, intelligence), see The Agent Betting Stack Explained.

Platform Overview

Before diving into endpoints, here’s what you’re working with.

PolymarketKalshi
Base URL (Market Data)https://gamma-api.polymarket.comhttps://api.elections.kalshi.com/trade-api/v2
Base URL (Trading)https://clob.polymarket.comSame as above
Base URL (WebSocket)wss://ws-subscriptions-clob.polymarket.com/ws/wss://api.elections.kalshi.com/trade-api/ws/v2
CLI Toolpolymarket (Rust, via Homebrew)None (REST only)
Python SDKpy-clob-clientkalshi_python_sync
TypeScript SDK@polymarket/clob-clientkalshi-typescript
Auth (read-only)None requiredNone required for market data
Auth (trading)API key + HMAC signature (L2 headers)API key + RSA signature
CurrencyUSDC on PolygonUSD (cents)
Rate LimitsPublished: 15,000/10s general (full table)Varies by endpoint
ChainPolygon (chainId: 137)N/A (centralized)
Market StructureSeries → Events → MarketsSeries → Events → Markets
Pricing0.00 to 1.00 (USDC per share)1 to 99 (cents per contract)
FeesTaker fees by category since March 30, 2026: Crypto 1.80%, Sports 0.75%, Politics 1.00%, Finance 1.00%, Economics 1.50%, Culture 1.25%, Weather 1.25%, Tech 1.00%, Mentions 1.56%. Geopolitics is fee-free. Maker rebates range 20–50% by category.0% fees on all trades
Demo/SandboxNo official sandboxhttps://demo-api.kalshi.co/trade-api/v2
US APISeparate platform at api.polymarket.us (Ed25519 auth, KYC required). See US vs Global guideN/A (US-based by default)

Note on the “elections” subdomain: Kalshi’s api.elections.kalshi.com provides access to ALL markets — not just election-related ones. This includes economics, weather, sports, technology, and more.

Polymarket 5-minute crypto markets: Polymarket launched short-duration crypto markets that resolve every 5 minutes. These markets carry taker fees and maker rebates like other crypto markets. Agents scanning for trading opportunities will encounter these alongside standard markets.


Authentication

Polymarket

Polymarket uses a three-tier authentication system.

Level 0 (no auth): Browse markets, read prices, check order books. No credentials needed.

Level 1 (wallet signature): Create or derive API credentials. Requires your private key to sign a message.

Level 2 (API key): Place orders, manage positions, cancel orders. Requires API key + secret + passphrase sent as HMAC-signed headers via five POLY_* headers.

Polymarket US uses a completely different auth system (Ed25519 instead of EIP-712/HMAC) with different SDKs and endpoints. The Trading Gateway is being deprecated in favor of the new Exchange Gateway. Developer onboarding now requires an application process and sandbox integration testing before production access is granted. See the Polymarket US vs. Global API Guide for details.

# Polymarket: Create a client with full trading auth
from py_clob_client.client import ClobClient

client = ClobClient(
    host="https://clob.polymarket.com",
    key="YOUR_PRIVATE_KEY",        # Wallet private key
    chain_id=137,                   # Polygon
    signature_type=1,               # 1 = proxy wallet
    funder="YOUR_FUNDER_ADDRESS"    # Address holding your funds
)
client.set_api_creds(client.create_or_derive_api_creds())

Note: Polymarket’s agent-skills documentation describes signature_type=2 (Gnosis Safe / browser-wallet proxy) as the wallet pattern most Polymarket accounts use; use signature_type=1 for Magic Link (email) proxy wallets. Older samples often show 1 as a generic “proxy” example—verify against your actual login path.

# Polymarket CLI: Import wallet for trading
polymarket wallet import 0xYOUR_PRIVATE_KEY
polymarket wallet show

Complete py_clob_client reference: For every ClobClient method with parameters, return types, and working examples, see the py_clob_client Method Reference. Deep-dive guides: get_order_book(), get_balance_allowance(), get_positions(), create_order().

Kalshi

Kalshi uses RSA key-pair authentication. You generate an API key and a private RSA key in your Kalshi account settings, then sign each request.

# Kalshi: Create authenticated client
import kalshi_python

config = kalshi_python.Configuration(
    host="https://api.elections.kalshi.com/trade-api/v2"
)

with open('path/to/private_key.pem', 'r') as f:
    config.private_key_pem = f.read()

config.api_key_id = "your-api-key-id"
client = kalshi_python.KalshiClient(config)
# Kalshi: Raw curl with auth headers
curl --request GET \
  --url https://api.elections.kalshi.com/trade-api/v2/portfolio/balance \
  --header 'KALSHI-ACCESS-KEY: YOUR_API_KEY' \
  --header 'KALSHI-ACCESS-SIGNATURE: COMPUTED_SIGNATURE' \
  --header 'KALSHI-ACCESS-TIMESTAMP: UNIX_MS_TIMESTAMP'

Quick Comparison: Auth

TaskPolymarketKalshi
Browse marketsNo authNo auth
Read order booksNo authNo auth (most endpoints)
Place ordersL2 (API key + HMAC)RSA signature
Manage positionsL2RSA signature
Key formatAPI key + secret + passphraseAPI key ID + RSA private key PEM
Key creationDerived from wallet signatureGenerated in account settings

Browsing Markets

This is the most common agent operation: scanning available markets to find trading opportunities. Both platforms provide unauthenticated endpoints for listing and searching markets, so you can build a market discovery pipeline before committing to either platform’s trading API.

The key difference in market browsing is structure. Polymarket separates market discovery (Gamma API) from trading (CLOB API), so you browse on one domain and trade on another. Kalshi uses a single API for both. Polymarket also has a dedicated CLI tool for quick lookups from the terminal, while Kalshi relies on curl or SDK calls.

For agents that need to scan both platforms simultaneously, the unified API section below covers aggregators like Dome and pmxt that normalize market data from both Polymarket and Kalshi into a single format.

List Markets

Polymarket — gamma-api.polymarket.com/markets:

# CLI
polymarket markets list --limit 20
polymarket -o json markets list --limit 100

# curl
curl "https://gamma-api.polymarket.com/markets?limit=20&closed=false"
# Python SDK (read-only, no auth)
from py_clob_client.client import ClobClient
client = ClobClient("https://clob.polymarket.com")
markets = client.get_markets()

Kalshi — api.elections.kalshi.com/trade-api/v2/markets:

# curl (no auth needed)
curl "https://api.elections.kalshi.com/trade-api/v2/markets?limit=20&status=open"
# Python SDK
markets = client.get_markets(limit=20, status="open")
for m in markets.markets:
    print(f"{m.ticker}: {m.title}")

Search Markets

Polymarket:

# CLI
polymarket markets search "bitcoin"
polymarket markets search "fed rate" --limit 5

# Gamma API
curl "https://gamma-api.polymarket.com/search?query=bitcoin&limit=5"

Kalshi:

# Filter by series ticker
curl "https://api.elections.kalshi.com/trade-api/v2/markets?series_ticker=KXBTC"

# No dedicated search endpoint — filter by series, event, or category

Get Market Details

Polymarket:

# CLI
polymarket markets get bitcoin-above-100k
polymarket -o json markets get bitcoin-above-100k

# Gamma API (by slug)
curl "https://gamma-api.polymarket.com/markets?slug=bitcoin-above-100k"

Kalshi:

curl "https://api.elections.kalshi.com/trade-api/v2/markets/TICKER_HERE"
market = client.get_market("KXBTC-26FEB28-T100000")
print(f"Title: {market.market.title}")
print(f"Yes price: {market.market.yes_price}¢")

Browse by Category/Tag

Polymarket:

# CLI (by tag)
polymarket events list --tag politics
polymarket events list --tag crypto
polymarket events list --tag sports

# Gamma API (by tag ID)
curl "https://gamma-api.polymarket.com/events?tag_id=2&closed=false"
# Tag IDs: politics=2, crypto=21, sports=100639, tech=1401, culture=596

Kalshi:

# Filter by category via series
curl "https://api.elections.kalshi.com/trade-api/v2/events?series_ticker=KXBTC"

# List all series to discover categories
curl "https://api.elections.kalshi.com/trade-api/v2/series/KXHIGHNY"

Quick Comparison: Market Browsing

OperationPolymarket CLIPolymarket APIKalshi API
List marketsmarkets list --limit NGET /marketsGET /markets
Searchmarkets search "query"GET /search?query=XFilter by series/event
Get one marketmarkets get SLUGGET /markets?slug=XGET /markets/{ticker}
By categoryevents list --tag TAGGET /events?tag_id=NFilter by series_ticker
List eventsevents listGET /eventsGET /events
Get eventGET /events/{id}GET /events/{ticker}
JSON output-o json on any commandAll responses are JSONAll responses are JSON
Pagination--limit, --offsetlimit, offset paramslimit, cursor params
Auth requiredNoNoNo

Order Books & Pricing

Reading order books and current prices is the second most common agent operation — essential for arbitrage detection, spread analysis, and order sizing. The two platforms differ significantly in how they expose order book data.

Polymarket provides a traditional two-sided order book with separate bids and asks, along with convenience endpoints for midpoint and price lookups. Kalshi only returns bids — in binary markets, a YES bid at price X is equivalent to a NO ask at (100-X), so you compute asks by inverting the other side. This difference matters for agents that compare order books across platforms: you need to normalize Kalshi’s one-sided representation into a two-sided book before making cross-platform comparisons.

Price formats also differ. Polymarket uses decimals between 0 and 1 (e.g., 0.65 means $0.65 per share). Kalshi uses cents between 1 and 99 (e.g., 65 means $0.65 per contract). Since early 2026, Kalshi has been transitioning from integer cents to decimal dollars (yes_price_dollars instead of yes_price) — check the fractional_trading_enabled flag on market responses.

Get Order Book

Polymarket — clob.polymarket.com/book:

# CLI
polymarket clob book TOKEN_ID

# curl
curl "https://clob.polymarket.com/book?token_id=TOKEN_ID"
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import BookParams

client = ClobClient("https://clob.polymarket.com")
book = client.get_order_book("TOKEN_ID")

# Batch: get multiple books at once
books = client.get_order_books([
    BookParams(token_id="TOKEN_1"),
    BookParams(token_id="TOKEN_2")
])

Kalshi — api.elections.kalshi.com/trade-api/v2/markets/TICKER/orderbook:

curl "https://api.elections.kalshi.com/trade-api/v2/markets/TICKER/orderbook"
book = client.get_market_orderbook("TICKER", depth=10)
# Returns yes bids and no bids only (no asks)
# In binary markets: yes bid at X¢ = no ask at (100-X)¢

Important Kalshi note: Kalshi only returns bids, not asks. This is because in binary markets, a yes bid at price X is equivalent to a no ask at (100-X). Your agent needs to compute asks by inverting the opposite side’s bids.

Kalshi orderbook fixed-point fields: The orderbook endpoint now returns yes_ask_size_fp, yes_bid_size_fp, and related fixed-point fields alongside the existing integer fields. Agents parsing orderbook data should use the _fp fields for precision on fractional-trading-enabled markets.

Get Midpoint Price

Polymarket:

# CLI
polymarket clob midpoint TOKEN_ID
polymarket -o json clob midpoint TOKEN_ID | jq '.mid'

# Python
mid = client.get_midpoint("TOKEN_ID")

Kalshi:

# No dedicated midpoint endpoint — compute from orderbook
# Midpoint = (best_yes_bid + (100 - best_no_bid)) / 2

Get Price History

Polymarket:

# CLI
polymarket clob price-history TOKEN_ID --interval 1d
polymarket clob price-history TOKEN_ID --interval 1h

# CLOB API
curl "https://clob.polymarket.com/prices-history?market=TOKEN_ID&interval=1d"

Kalshi:

curl "https://api.elections.kalshi.com/trade-api/v2/markets/TICKER/history?limit=100"

Quick Comparison: Order Books & Pricing

OperationPolymarket CLIPolymarket APIKalshi API
Order bookclob book TOKENGET /book?token_id=XGET /markets/{ticker}/orderbook
Midpointclob midpoint TOKENget_midpoint(token)Compute from orderbook
Best priceget_price(token, side)Best bid from orderbook
Spreadget_spread(token)Compute from orderbook
Price historyclob price-history TOKENGET /prices-historyGET /markets/{ticker}/history
Batch booksget_order_books([...])One call per market
Book formatBids + AsksBids + AsksBids only (compute asks)

Placing Orders

The core trading operation. Both platforms support limit orders and market orders, but with different mechanics.

Kalshi breaking change — March 12, 2026: Kalshi removed legacy integer-cent price fields and integer contract count fields from all API endpoints. If your code uses yes_price (cents, e.g., yes_price=45) or count (integer contracts) in order requests, migrate to yes_price_dollars (e.g., yes_price_dollars=0.45) and count_fp for fractional-enabled markets. See Kalshi changelog for the full migration guide.

Limit Orders

Polymarket:

# CLI
polymarket clob create-order \
  --token TOKEN_ID \
  --side buy \
  --price 0.45 \
  --size 10
from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY

order = OrderArgs(
    token_id="TOKEN_ID",
    price=0.45,     # Price per share in USDC (0.00-1.00)
    size=10.0,      # Number of shares
    side=BUY
)
signed = client.create_order(order)
resp = client.post_order(signed, OrderType.GTC)  # Good-til-canceled
// TypeScript
import { ClobClient, Side } from "@polymarket/clob-client";

const order = await client.createAndPostOrder(
  { tokenID: "TOKEN_ID", price: 0.50, size: 10, side: Side.BUY },
  { tickSize: "0.01", negRisk: false }
);

Kalshi:

import uuid

order = client.create_order(
    ticker="MARKET_TICKER",
    action="buy",
    side="yes",
    count=10,                    # Number of contracts (use count_fp on fractional-enabled markets)
    type="limit",
    yes_price_dollars=0.45,      # Price in dollars (0.01–0.99); replaces legacy yes_price cents field
    client_order_id=str(uuid.uuid4())
)
curl --request POST \
  --url https://api.elections.kalshi.com/trade-api/v2/portfolio/orders \
  --header 'Content-Type: application/json' \
  --header 'KALSHI-ACCESS-KEY: KEY' \
  --header 'KALSHI-ACCESS-SIGNATURE: SIG' \
  --header 'KALSHI-ACCESS-TIMESTAMP: TS' \
  --data '{
    "ticker": "MARKET_TICKER",
    "action": "buy",
    "side": "yes",
    "count": 10,
    "type": "limit",
    "yes_price_dollars": 0.45,
    "client_order_id": "UUID"
  }'

Market Orders

Polymarket:

# CLI
polymarket clob market-order \
  --token TOKEN_ID \
  --side buy \
  --amount 5
from py_clob_client.clob_types import MarketOrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY

mo = MarketOrderArgs(
    token_id="TOKEN_ID",
    amount=25.0,         # USDC amount to spend
    side=BUY,
    order_type=OrderType.FOK  # Fill-or-kill
)
signed = client.create_market_order(mo)
resp = client.post_order(signed, OrderType.FOK)

Kalshi:

order = client.create_order(
    ticker="MARKET_TICKER",
    action="buy",
    side="yes",
    count=10,
    type="market",         # No price needed for market orders
    client_order_id=str(uuid.uuid4())
)

Polymarket taker fees (since March 30, 2026): The feeRateBps field is now required on signed order objects. Developers must fetch the current fee rate dynamically via the fee-rate API endpoint before constructing orders. Fee rates vary by market category (see the Platform Overview table).

Order Types

TypePolymarketKalshi
Good-til-canceled (GTC)OrderType.GTCtype: "limit" (default)
Fill-or-kill (FOK)OrderType.FOKtime_in_force: "fill_or_kill"
Market orderMarketOrderArgs + FOKtype: "market"
Post-onlypost_only=True on post_order()post_only: true
Reduce-onlyNot directly supportedreduce_only: true

Price Formats

This is a common source of bugs when building cross-platform agents:

PolymarketKalshi
Price range0.00 to 1.000.01 to 0.99
UnitUSDC per shareDollars per contract (yes_price_dollars)
“50% chance”price: 0.50yes_price_dollars: 0.50
“10% chance”price: 0.10yes_price_dollars: 0.10
Size unitNumber of shares (decimal)Number of contracts (count, or count_fp for fractional markets)
Tick sizes0.01 or 0.001 (varies)$0.01 (subpenny on some markets)
FeesTaker fee varies by category (0.75%–1.80%); fetch via fee-rate API. feeRateBps required on signed orders.0% fees on all trades

Order Management

View Open Orders

Polymarket:

# CLI
polymarket clob orders

# Python
orders = client.get_orders()

Kalshi:

orders = client.get_orders(status="resting")
curl "https://api.elections.kalshi.com/trade-api/v2/portfolio/orders?status=resting" \
  --header 'KALSHI-ACCESS-KEY: KEY' \
  --header 'KALSHI-ACCESS-SIGNATURE: SIG' \
  --header 'KALSHI-ACCESS-TIMESTAMP: TS'

Cancel Orders

Polymarket:

# CLI: Cancel one
polymarket clob cancel ORDER_ID

# CLI: Cancel all
polymarket clob cancel-all

# Python
client.cancel(order_id="ORDER_ID")
client.cancel_all()
client.cancel_market_orders(market="CONDITION_ID")

Kalshi:

# Cancel one
client.cancel_order("ORDER_ID")

# Cancel all (batch)
client.batch_cancel_orders(
    tickers=["TICKER1", "TICKER2"]
)
# Cancel one
curl --request DELETE \
  "https://api.elections.kalshi.com/trade-api/v2/portfolio/orders/ORDER_ID" \
  --header 'KALSHI-ACCESS-KEY: KEY' \
  --header 'KALSHI-ACCESS-SIGNATURE: SIG' \
  --header 'KALSHI-ACCESS-TIMESTAMP: TS'

Amend Orders

Polymarket: Not supported via API — cancel and replace.

Kalshi:

# Amend an existing order (change price/size without cancel+replace)
# client_order_id is now optional — you can amend using just order_id
client.amend_order(
    order_id="ORDER_ID",
    count=15,
    yes_price_dollars=0.48   # Use yes_price_dollars (not legacy yes_price cents)
)
curl --request POST \
  "https://api.elections.kalshi.com/trade-api/v2/portfolio/orders/ORDER_ID/amend" \
  --header 'Content-Type: application/json' \
  --data '{"count": 15, "yes_price_dollars": 0.48}'

Quick Comparison: Order Management

OperationPolymarket CLIPolymarket APIKalshi API
List ordersclob ordersget_orders()GET /portfolio/orders
Cancel oneclob cancel IDcancel(order_id)DELETE /portfolio/orders/{id}
Cancel allclob cancel-allcancel_all()POST /portfolio/orders/batch (cancel)
AmendNot supportedNot supportedPOST /portfolio/orders/{id}/amend
Batch createNot supportedpost_orders([...]) (up to 15 per request, raised from 5)POST /portfolio/orders/batch

Positions & Portfolio

Check Positions: get_positions

Polymarket — data-api.polymarket.com/positions:

# CLI
polymarket data positions YOUR_ADDRESS

# Data API
curl "https://data-api.polymarket.com/positions?user=YOUR_ADDRESS"

Kalshi:

positions = client.get_positions(settlement_status="unsettled")
for p in positions.market_positions:
    print(f"{p.ticker}: {p.position} contracts")
curl "https://api.elections.kalshi.com/trade-api/v2/portfolio/positions" \
  --header 'KALSHI-ACCESS-KEY: KEY' \
  --header 'KALSHI-ACCESS-SIGNATURE: SIG' \
  --header 'KALSHI-ACCESS-TIMESTAMP: TS'

Check Balance: get_balance_allowance

Polymarket — py_clob_client get_balance and get_balance_allowance:

# CLI
polymarket clob balance --asset-type collateral

# Python
balance = client.get_balance_allowance()

Full method reference: See the dedicated get_balance_allowance() guide for BalanceAllowanceParams, AssetType, wei conversion, and pre-trade validation patterns.

Kalshi:

balance = client.get_balance()
# Returns balance in cents + portfolio_value (balance + positions value)
print(f"Available: ${balance.balance / 100:.2f}")
print(f"Portfolio: ${balance.portfolio_value / 100:.2f}")

Portfolio Value

Polymarket:

# CLI
polymarket data value YOUR_ADDRESS

Kalshi:

balance = client.get_balance()
# portfolio_value includes balance + position market values

Withdraw / Bridge Funds

Polymarket now offers a POST /withdraw endpoint to bridge USDC.e from Polymarket to any supported chain and token. This is useful for agents that need to move funds off-platform programmatically after closing positions.

Kalshi: Withdrawals are managed through the Kalshi dashboard; no public API endpoint for withdrawals.

Trade History

Polymarket:

# CLI
polymarket clob trades

# Python
trades = client.get_trades()

Kalshi:

fills = client.get_fills(ticker="MARKET_TICKER")
# A "fill" = a completed trade match
# Each fill includes:
#   fee_cost          — fee charged on this fill (since January 28, 2026)
#   yes_price_dollars — dollar-denominated yes price (replaces deprecated yes_price_fixed)
#   no_price_dollars  — dollar-denominated no price (replaces deprecated no_price_fixed)

Quick Comparison: Portfolio

OperationPolymarket CLIPolymarket APIKalshi API
Positionsdata positions ADDRGET /positionsGET /portfolio/positions
Balanceclob balanceget_balance_allowance()GET /portfolio/balance
Portfolio valuedata value ADDRCompute from positionsIncluded in balance response
Trade historyclob tradesget_trades()GET /portfolio/fills
SettlementsOn-chain (CTF redeem)GET /portfolio/settlements (now includes yes_total_cost_dollars / no_total_cost_dollars; legacy cent fields deprecated)
SubaccountsNot applicablePUT /portfolio/subaccounts/netting (manage netting across subaccounts)
Withdraw/BridgePOST /withdraw (bridge USDC.e to other chains/tokens)Dashboard only (no API endpoint)

WebSocket Streaming

For agents that need real-time data, both platforms offer WebSocket feeds.

Polymarket WebSocket

Base URL: wss://ws-subscriptions-clob.polymarket.com/ws/

Channels:
  market  — Order book updates, price changes (public)
  user    — Order status updates (authenticated)
# Subscribe to market channel
import websocket
import json

ws = websocket.create_connection(
    "wss://ws-subscriptions-clob.polymarket.com/ws/market"
)

# Subscribe to specific assets
ws.send(json.dumps({
    "type": "subscribe",
    "assets_ids": ["TOKEN_ID_1", "TOKEN_ID_2"]
}))

while True:
    msg = json.loads(ws.recv())
    # msg contains orderbook updates, trade events

Kalshi WebSocket

Base URL: wss://api.elections.kalshi.com/trade-api/ws/v2

Channels:
  orderbook             — Live order book snapshots
  ticker                — Price/volume updates
  trades                — Completed trades
  fills                 — Your fills (authenticated)
  market_lifecycle      — Market state changes
  order_group_updates   — Order group lifecycle events: created, triggered, reset, deleted, limit_updated (Jan 2026)
# Kalshi WebSocket subscription
import websocket
import json

ws = websocket.create_connection(
    "wss://api.elections.kalshi.com/trade-api/ws/v2"
)

# Authenticate
ws.send(json.dumps({
    "id": 1,
    "cmd": "subscribe",
    "params": {
        "channels": ["orderbook", "ticker"],
        "market_tickers": ["TICKER1", "TICKER2"]
    }
}))

Quick Comparison: WebSocket

FeaturePolymarketKalshi
Public channelsmarketorderbook, ticker, trades, market_lifecycle
Authenticated channelsuserfills, positions, order_group_updates
Subscription formatassets_ids arraymarket_tickers array
Book updatesIncrementalSnapshots
Auth methodSeparate auth handshakeAuth headers on connect

Polymarket CLI Complete Command Reference

The Polymarket CLI is unique to the ecosystem — no other platform has a dedicated CLI for agent access. Here’s the full command map for quick reference.

Browsing (No Wallet Required)

polymarket markets list [--limit N] [--offset N]
polymarket markets search "QUERY" [--limit N]
polymarket markets get SLUG
polymarket events list [--tag TAG] [--limit N]
polymarket clob book TOKEN_ID
polymarket clob midpoint TOKEN_ID
polymarket clob price-history TOKEN_ID [--interval 1d|1h|1m]
polymarket status                    # API health check

Wallet Management

polymarket wallet create             # Generate new wallet
polymarket wallet import 0xKEY       # Import existing private key
polymarket wallet show               # Display wallet address and config
polymarket approve set               # Approve USDC for trading (needs MATIC)

Trading (Wallet Required)

polymarket clob market-order --token TOKEN --side buy|sell --amount USDC
polymarket clob create-order --token TOKEN --side buy|sell --price 0.XX --size N
polymarket clob balance [--asset-type collateral|conditional]
polymarket clob orders               # List open orders
polymarket clob trades               # List trade history
polymarket clob cancel ORDER_ID
polymarket clob cancel-all

Data & Positions

polymarket data positions ADDRESS    # All positions for an address
polymarket data value ADDRESS        # Portfolio value

Utility

polymarket setup                     # Guided first-time setup
polymarket upgrade                   # Update CLI to latest version
polymarket shell                     # Interactive REPL mode
polymarket --version
polymarket --help
polymarket -o json COMMAND           # JSON output (on any command)

Unified API Aggregators

The direct Polymarket and Kalshi APIs are powerful but different — different auth, different price formats, different SDKs. A growing category of unified APIs abstracts these differences into a single interface. If your agent needs to trade across multiple prediction markets, these tools save significant integration work.

Deep dive available: For a complete comparison of all three tools with code examples, data quality benchmarks, and a decision framework, see the Dome vs pmxt vs OddsPapi Comparison Guide.

Dome (Acquired by Polymarket)

Dome was a YC W25 startup that built a single-API-key interface to Polymarket, Kalshi, and other prediction markets. Polymarket acquired Dome in early 2026, signaling the industry’s move toward standardized API access.

Status: Integrated into Polymarket. The standalone Dome API is being merged into Polymarket’s official developer tooling. New integrations should use the Polymarket API directly, but Dome’s unified data models influenced how Polymarket is expanding its API surface.

What Dome contributed:

  • Normalized market schema across platforms (consistent event/market/outcome hierarchy)
  • Single authentication layer for multi-platform access
  • Unified order placement with platform-specific execution routing
  • Real-time price aggregation across platforms

See the Dome tool entry for links and current status.

pmxt — “CCXT for Prediction Markets”

pmxt is an open-source SDK that normalizes prediction market data into a consistent format, inspired by how CCXT unifies crypto exchange APIs. Unlike Dome (which was a hosted service), pmxt runs client-side — no third-party server in the middle.

Installation:

pip install pmxt

Basic usage:

import pmxt

# Initialize exchanges
poly = pmxt.polymarket()
kalshi = pmxt.kalshi()

# Fetch markets (normalized format)
poly_markets = poly.fetch_markets()
kalshi_markets = kalshi.fetch_markets()

# Normalized market object
# {
#   "id": "...",
#   "symbol": "PRESIDENTIAL-ELECTION-2028",
#   "question": "Who will win the 2028 Presidential Election?",
#   "outcomes": [{"name": "Democrat", "price": 0.54}, ...],
#   "volume": 1250000,
#   "platform": "polymarket"
# }

Key features:

  • Normalized market, order book, and trade data across platforms
  • Consistent price format (0-1 implied probability)
  • Local execution — your API keys stay on your machine
  • Extensible — community can add new platform adapters

Limitations:

  • Newer project, smaller community than CCXT
  • Trading support varies by platform (read operations are more mature than write)
  • No hosted API — you manage your own infrastructure

OddsPapi

OddsPapi bridges prediction markets and traditional sportsbooks, aggregating odds data from both worlds into a single feed. This is particularly useful for cross-market arbitrage strategies.

Key features:

  • Aggregates Polymarket, Kalshi, and 10+ sportsbooks
  • Odds normalization across American, decimal, and implied probability formats
  • Historical odds data for backtesting
  • REST API with generous free tier

Best for: Agents that need to compare prediction market prices against sportsbook odds. If your strategy involves cross-market arbitrage or market-making informed by sportsbook lines, OddsPapi provides the data bridge.

For live multi-sportsbook odds data, see also The Odds API.

Unified API Comparison

DomepmxtOddsPapi
TypeHosted API (now part of Polymarket)Open-source SDKHosted API
PlatformsPolymarket, Kalshi, othersPolymarket, KalshiPrediction markets + sportsbooks
Auth modelSingle API keyPer-platform API keys (local)Single API key
Trading supportFull (order placement, management)Partial (read-heavy, trading in development)Read-only (odds data)
Real-time dataWebSocket feedsPolling (WebSocket planned)REST polling
PricingWas paid SaaS (now integrated)Free, open-sourceFree tier + paid plans
Self-hostedNo (was cloud-only)Yes (runs locally)No (cloud API)
Best forN/A (use Polymarket API directly)Multi-platform agents, CCXT usersCross-market arb, sportsbook comparison

When to Use Unified vs. Direct APIs

Use direct APIs (Polymarket/Kalshi) when:

  • You trade on a single platform
  • You need the lowest possible latency
  • You need features not yet supported by unified SDKs (e.g., advanced order types, FIX protocol)
  • You need full WebSocket streaming with orderbook reconstruction

Use a unified SDK (pmxt) when:

  • Your agent trades on multiple prediction markets
  • You want consistent data models across platforms
  • You’re building a comparison or aggregation tool
  • You value open-source and local execution

Use an odds aggregator (OddsPapi, The Odds API) when:

  • Your strategy compares prediction markets to sportsbooks
  • You need cross-market arbitrage detection
  • You want historical odds data for backtesting

Notable exclusion: OG.com. OG.com is a CFTC-regulated prediction market by Crypto.com (CDNA) with sports-focused contracts and parlays. It is excluded from this API reference because it does not offer a public API or SDK for programmatic trading.


SDKs & Client Libraries: Python, TypeScript, Go

Polymarket SDKs: py-clob-client and More

LanguagePackageInstallDocs
Pythonpy-clob-clientpip install py-clob-clientGitHub
TypeScript@polymarket/clob-clientnpm i @polymarket/clob-clientGitHub
Gopoly-market-sdkgo get github.com/mtt-labs/poly-market-sdkpkg.go.dev
Rust (CLI)polymarketbrew install polymarketGitHub
Pythonpolymarket-apispip install polymarket-apis (v0.5.7+, Python ≥3.12)PyPI

Deep dive: For every py_clob_client method with parameters, return types, and working code examples, see the py_clob_client Method Reference.

polymarket-apis (v0.5.7, April 2026) is a unified third-party Python SDK that wraps the CLOB, Gamma, Data, Web3, WebSockets, and GraphQL clients into a single package with Pydantic validation. Requires Python ≥3.12. Use it as a higher-level alternative to py-clob-client when you need access to multiple Polymarket APIs from one import.

Kalshi SDKs

LanguagePackageInstallDocs
Pythonkalshi_python_syncpip install kalshi_python_syncdocs.kalshi.com
TypeScriptkalshi-typescriptnpm install kalshi-typescriptdocs.kalshi.com

Error Handling

Polymarket Common Errors

ErrorMeaningFix
INSUFFICIENT_BALANCENot enough USDCFund wallet or reduce order size
INVALID_TICK_SIZEPrice doesn’t match market’s tick sizeCheck tick size (0.01 or 0.001)
ORDER_ALREADY_EXISTSDuplicate order submissionGenerate new nonce
MARKET_NOT_TRADABLEMarket is closed or resolvedCheck market status before ordering
INVALID_SIGNATUREAuth signature mismatchRegenerate API credentials

Kalshi Common Errors

HTTP CodeMeaningFix
400Bad request (invalid params). Order validation failures now return granular error codes (e.g., specific field-level errors) instead of the generic invalid_order response.Check the error code and message for the specific validation failure
401Authentication failedVerify API key and signature
403Insufficient permissionsCheck account status and permissions
404Market/order not foundVerify ticker or order ID
429Rate limitedBack off and retry with exponential delay
500Server errorRetry after brief delay

Cross-Platform Arbitrage Reference

For agents comparing prices across platforms, here’s how to normalize data:

def normalize_price(polymarket_price=None, kalshi_price=None):
    """Convert to a common 0-1 probability format."""
    if polymarket_price is not None:
        return polymarket_price  # Already 0.00-1.00
    if kalshi_price is not None:
        return kalshi_price / 100  # Convert cents to 0.00-1.00

def denormalize_price(probability, platform):
    """Convert common probability to platform-native format."""
    if platform == "polymarket":
        return round(probability, 2)  # 0.00-1.00
    elif platform == "kalshi":
        return int(probability * 100)  # 1-99 cents

When comparing equivalent markets across platforms, an arbitrage opportunity exists when the combined cost of buying “Yes” on one platform and “No” on the other totals less than 1.00 (after fees).

The price normalization pattern above extends to sportsbooks. American odds (-110, +150), decimal odds (1.91, 2.50), and prediction market probabilities (0.52, 0.40) all represent the same underlying concept. For converting between these formats and normalizing odds across offshore sportsbooks like BetOnline, Bovada, and BookMaker, see the Odds Normalization Guide.


Rate Limits

Polymarket

Polymarket now publishes concrete rate limits enforced via Cloudflare throttling. The general limit is 15,000 requests per 10 seconds, with CLOB trading endpoints at 3,500/10s burst and 36,000/10min sustained for POST /order. Gamma API is 4,000/10s general, and Data API is 1,000/10s general.

Kalshi

Kalshi enforces rate limits per endpoint. When rate limited, the API returns HTTP 429 with a Retry-After header. The demo environment at demo-api.kalshi.co has more generous limits for testing.

To check your account’s specific rate limit tier, use the endpoint added in January 2026:

curl "https://api.elections.kalshi.com/trade-api/v2/account/limits" \
  --header 'KALSHI-ACCESS-KEY: KEY' \
  --header 'KALSHI-ACCESS-SIGNATURE: SIG' \
  --header 'KALSHI-ACCESS-TIMESTAMP: TS'
# Returns your API tier and read/write limits

Deep dive: See the Polymarket Rate Limits Guide for 429 error handling, retry code, and rate limit header documentation.


Frequently Asked Questions

Which prediction market API should I use?

Polymarket offers the highest volume and a decentralized order book on Polygon. Kalshi is CFTC-regulated and uses USD directly. For U.S.-based agents, Kalshi has clearer regulatory standing. For global agents, Polymarket has more markets and liquidity. See the Platform Overview table above for a detailed comparison.

What is the best Python SDK for prediction markets?

For Polymarket, use py-clob-client (method reference). For Kalshi, use kalshi_python_sync. Both are official SDKs maintained by the platforms with full trading support including order placement, position tracking, and WebSocket streaming.

Can I use the same code for both Polymarket and Kalshi?

No — they use different authentication (EIP-712 vs RSA-PSS), different price formats (0.00-1.00 vs cents), and different SDKs. However, you can build an abstraction layer. See the Cross-Platform Arbitrage Reference section above for price normalization code and comparison patterns.


Further Reading