CLOB Compatibility
PolySimulator mirrors Polymarket’s real execution model :
All orders are limit orders — market orders are just limit orders with FOK/IOC time-in-force at marketable prices
BUY fills at best ask, SELL fills at best bid — not the midpoint
The price field is the worst-price limit — slippage protection built into the order, not a separate parameter
FOK (Fill-or-Kill) and IOC (Immediate-or-Cancel) — immediate execution order types
The POST /v1/clob/order endpoint mirrors Polymarket’s real CLOB API schema , enabling one-URL-swap migration from paper trading to live trading.
The Migration Promise
┌──────────────────────────────────────────────────────────────────┐
│ Change ONLY the base URL and credentials to go live │
│ │
│ Virtual: https://api.polysimulator.com/v1/clob/order │
│ Live: https://clob.polymarket.com/order │
└──────────────────────────────────────────────────────────────────┘
Virtual Mode (PolySimulator)
Live Mode (Polymarket)
import requests
BASE = "https://api.polysimulator.com/v1"
headers = { "X-API-Key" : "ps_live_kJ9mNx2p..." }
order = requests.post( f " { BASE } /clob/order" , headers = headers, json = {
"token_id" : "71321045679252..." ,
"side" : "BUY" ,
"price" : "0.65" ,
"size" : "10" ,
"order_type" : "GTC" ,
}).json()
Authentication difference : PolySimulator uses the X-API-Key header.
Polymarket’s live CLOB requires L2 HMAC credentials (API key + secret + passphrase)
derived from your wallet’s private key via py_clob_client. See the
Live Migration Guide for full credential setup.
Request Schema
{
"token_id" : "71321045679252212594626385532706912750332728571942532289631379312455583992563" ,
"side" : "BUY" ,
"price" : "0.65" ,
"size" : "10" ,
"order_type" : "GTC" ,
"fee_rate_bps" : 0 ,
"nonce" : "optional-nonce" ,
"client_order_id" : "my-order-001"
}
All numeric fields (price, size) must be strings. Both PolySimulator
and Polymarket’s real CLOB API expect string-encoded decimals, e.g. "0.65"
not 0.65. Using floats will be rejected.
Field Type Required Description token_idstring Yes CLOB outcome token ID sidestring Yes BUY or SELLpricestring Yes Limit price as decimal string (“0.01”–“0.99”) sizestring Yes Number of shares as decimal string (> 0) order_typestring No GTC (default), FOK, IOC, GTDfee_rate_bpsint No Accepted but ignored in virtual mode noncestring No Accepted but ignored in virtual mode takerstring No Accepted but ignored in virtual mode client_order_idstring No Idempotency key
Response Schema
Mirrors the Polymarket CLOB response shape. Status values use lowercase
strings matching Polymarket’s insert-order convention:
{
"success" : true ,
"orderID" : "42" ,
"status" : "matched" ,
"transactID" : "42" ,
"errorMsg" : null ,
"price" : "0.65" ,
"size" : "10.0" ,
"side" : "BUY" ,
"takingAmount" : "6.50" ,
"makingAmount" : "10.0"
}
Status Value Meaning matchedOrder fully filled liveOrder pending (limit order resting) unmatchedOrder cancelled or rejected
Field Mapping
Polymarket CLOB PolySimulator /v1/clob/order Notes tokenId / token_idtoken_idResolved to condition_id via Redis side (0=BUY, 1=SELL)side (“BUY”/“SELL”)String enum price (string)price (string)Decimal string: "0.65" size (string)size (string)Decimal string: "10" feeRateBpsfee_rate_bpsAccepted; no fees in virtual mode orderTypeorder_typeGTC/FOK/IOC/GTD signature— Not required (virtual mode) salt— Not required (virtual mode)
Fields like signature, salt, maker, and signer that are required
for Polymarket’s blockchain settlement are accepted but ignored in
virtual mode. This means you can develop your bot with (or without) these
fields — either way works.
String vs Float numerics : Both PolySimulator and Polymarket require price and size
as strings (e.g., "0.65" not 0.65). Always pass strings to ensure compatibility.
Public CLOB Read Endpoints
These endpoints mirror Polymarket’s public CLOB data API and require no authentication .
They accept token_id (the CLOB outcome token) as query parameter.
Method Endpoint Description GET/v1/price?token_id=...Single token price with bid/ask POST/v1/pricesBatch prices for multiple token IDs GET/v1/midpoint?token_id=...Best-bid/best-ask midpoint GET/v1/spread?token_id=...Spread (best bid, best ask, spread) GET/v1/book?token_id=...Full order book snapshot GET/v1/prices-history?token_id=...Historical OHLC candles
Single Price
Batch Prices
Midpoint
import requests
price = requests.get(
"https://api.polysimulator.com/v1/price" ,
params = { "token_id" : "71321045679252..." }
).json()
# {"token_id": "71321...", "price": "0.65", "bid": "0.64", "ask": "0.66"}
These endpoints use the same Redis price cache as the authenticated API.
Data is refreshed every 30 seconds by the price poller.
Cancel Endpoints
Bulk cancel endpoints match Polymarket’s cancel response shape:
{canceled: [...], not_canceled: {...}}.
Method Endpoint Description DELETE/v1/cancel-allCancel all pending limit orders DELETE/v1/cancel-market-orders?market=...Cancel pending orders for a specific market
The cancel-market-orders endpoint accepts either market (condition_id) or
asset_id (token_id) as query parameters.
// Response shape (both endpoints)
{
"canceled" : [ "42" , "43" ],
"not_canceled" : { "44" : "Cannot cancel order with status: FILLED" }
}
When to Use CLOB-Compat vs Native API
Use Case Recommended Endpoint New bot development POST /v1/orders — richer features, string numericsPorting existing Polymarket bot POST /v1/clob/order — minimal code changesPlanning to go live on Polymarket POST /v1/clob/order — URL-swap readyAdvanced features (batch, limit, slippage) POST /v1/orders — full feature set
Next Steps