All articles
Polymarket·November 17, 2025·6 min read

Polymarket CLOB API: Order Types, Fill Logic & Execution

A hands-on walkthrough of Polymarket's Central Limit Order Book API covering limit, market, and GTC/GTD order types, how fills are matched on-chain via the CTF Exchange, and latency considerations for algorithmic traders.

The Polymarket CLOB API is the programmatic interface to a fully on-chain central limit order book — one that settles on Polygon via Gnosis Conditional Token Framework contracts rather than against a venue's internal ledger. Understanding exactly how orders move through that pipeline matters: the gap between placing a limit order and seeing it fill involves an off-chain matching engine, an EIP-712 signed order structure, and a final on-chain settlement step that most traders never instrument properly.

How the CLOB Is Actually Structured

Polymarket runs a hybrid architecture. The order book itself is maintained off-chain by a centralized operator (the CLOB service), but every matched trade settles on-chain via the CTF Exchange contract deployed on Polygon. Orders are signed with EIP-712 typed data — you sign a LimitOrderData struct that commits to token address, size, price (as a probability expressed in USDC cents, 0–100), and expiry — and the exchange contract validates that signature on-chain at settlement.

The key implication: you do not submit a transaction per order. You submit a signed order payload to the REST/WebSocket API, and the operator runs the matching engine. Only matched trades hit the chain. Cancellations are also operator-mediated (off-chain acknowledgment), not on-chain transactions. This matters for latency budgeting — your cancel round-trip is an HTTP call, not a blockchain write.

Order Types and Their Actual Behaviour

The API exposes three meaningful order type combinations:

  • Limit / GTC (Good Till Cancelled): sits in the book until matched or explicitly cancelled. This is the workhorse for market-making — you post a resting bid and offer and they stay put. No on-chain cost for unmatched orders.
  • Limit / GTD (Good Till Date): same as GTC but with a Unix timestamp expiry baked into the signed struct. The operator enforces expiry off-chain; the contract also rejects expired signatures at settlement. Use this instead of manually cancelling stale quotes — it eliminates the cancel race condition in volatile markets.
  • Market / FOK (Fill or Kill): aggressively crosses the spread and is rejected entirely if it cannot be fully filled immediately. There is no partial-fill market order — if you size beyond available liquidity at the touch, the order is rejected rather than partially executed. This surprises engineers coming from traditional perps venues.

There is no IOC (Immediate Or Cancel) at the API level as of the current implementation. Teams emulate it with a very short GTD expiry, but that is not the same thing — a true IOC would allow partial fills; GTD-as-IOC just kills the order if it cannot fill in time.

Fill Matching and Price Priority

The matching engine runs standard price-time priority. For YES/NO binary markets, each side is its own ERC-1155 conditional token; the CLOB treats them independently. When your limit bid at 0.63 (63 cents) is matched against a resting ask, the engine checks:

  1. Does the ask price satisfy ask_price <= bid_price?
  2. Is neither order expired?
  3. Do both signatures verify against the on-chain contract's expected struct hash?

If all three pass, the matched pair is bundled and submitted as a matchOrders call on the CTF Exchange. Fills execute at the resting order's price — the aggressor gets price improvement. This is important for market-maker sizing logic: your resting ask at 0.65 fills at 0.65 even if the market order would have accepted 0.70.

Gas for settlement is paid by the operator and socialized. You do not pay per-fill gas directly, but the operator's cost structure is why fee tiers exist — expect a 2% maker / 0% taker rebate structure in liquid markets, though this varies by market category.

The WebSocket Feed and Orderbook State

For market-making bots and arbitrage engines, polling the REST endpoint for book state is too slow. The WebSocket API (wss://ws-subscriptions-clob.polymarket.com/ws/market) pushes incremental book updates: book snapshots on subscribe, then price_change and last_trade_price events as the book evolves.

A few sharp edges worth knowing:

  • The book feed publishes price levels, not individual orders. You see quantity at each tick, not order count or individual order IDs. Reconstructing depth requires accumulating deltas against your initial snapshot carefully — a missed message leaves your local book wrong.
  • The WebSocket heartbeats on a 10-second interval. If your consumer stalls and misses more than one heartbeat window, your book state is stale. Build explicit staleness checks into any quoting loop.
  • For order status, subscribe to the user channel with your API key — this pushes fill notifications, cancel acknowledgments and order status updates. Don't poll order status via REST in a hot loop; the rate limits are real and will get your key throttled.

Signing Orders: The EIP-712 Detail That Burns People

Every order requires an EIP-712 signature against the LimitOrderData struct. The domain separator includes the chain ID (Polygon mainnet: 137) and the CTF Exchange contract address. A common bug is constructing the struct hash correctly but against the wrong contract address — orders sign without error but are rejected at match time with a cryptic invalid-signature response.

The nonce field in the order struct is not an account nonce. It is a per-order random salt that prevents replay. Generate it as a random uint256 per order; do not increment a counter. Reusing a nonce does not cause a stuck account — the operator just rejects duplicate nonce+address combinations.

For Python implementations (the most common choice for Polymarket bots), use the py_clob_client library as a reference for the struct encoding, not as a dependency you trust blindly in production — its error handling for partial API failures is thin.

Latency Reality for Algorithmic Execution

The REST endpoint latency from a well-located VPS (AWS us-east-1 or eu-west-1) is typically 30–80ms round-trip for order placement. The matching engine processes accepted orders within single-digit milliseconds. On-chain settlement of matched trades runs 2–5 seconds on Polygon under normal load — this is the figure that matters for resolution-critical positions, not order placement latency.

For market-making strategies, the practical execution loop is: receive book update via WebSocket → compute fair value and desired quotes → cancel stale resting orders → place new limit orders via REST. At realistic quote refresh rates (every 1–5 seconds for most markets), REST latency is not the binding constraint. The binding constraint is almost always your fair-value model update speed and the quality of your cancel-replace logic. A news-driven event bot has a different profile — there the placement race after an event trigger is where REST latency actually hurts.


If you want a production Polymarket execution engine built on this stack — CLOB integration, order management, inventory control and resolution-safe exits — talk to us at TierZero. We ship these in Python and TypeScript against live markets, not demos.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Polymarket#CLOB API#Order Types#Algorithmic Trading#Prediction Markets#CTF Exchange#Market Making