This guide reflects Polymarket’s CLOB V2. The V1 clients (
py-clob-client, @polymarket/clob-client, the Rust rs-clob-client, and the Polymarket/agents framework) were archived in May 2026 and no longer work against production. If you’re still on V1 code you have to move to V2 regardless, so the mappings below target V2.What changed
| Polymarket (CLOB V2) | Limitless | |
|---|---|---|
| Chain | Polygon (137) | Base (8453) |
| Collateral | pUSD (6 decimals, wraps USDC.e) | USDC (6 decimals) |
| REST hosts | gamma-api.polymarket.com (markets, search) + clob.polymarket.com (orderbook, pricing, trading) + data-api.polymarket.com (positions, trades, activity) | api.limitless.exchange (unified) |
| WebSocket | wss://ws-subscriptions-clob.polymarket.com | wss://ws.limitless.exchange |
| Auth model | L1/L2 — derive API creds with EIP-712, sign every request with HMAC across 5 POLY_* headers | HMAC-signed scoped API tokens (lmts-api-key/lmts-timestamp/lmts-signature) for all integrations; granular scopes for partner integrations |
| SDKs | V2 CLOB clients @polymarket/clob-client-v2, py_clob_client_v2 (V1 clients archived) | Python SDK, TypeScript SDK, Go SDK, Rust SDK, or direct REST |
| Wallet types | EOA, Proxy, Gnosis Safe, 1271 (signatureType 0-3) | EOA, or server-managed wallets via delegated signing |
| Market lookup | conditionId or clobTokenIds | slug or address |
| Token IDs | clobTokenIds paired with outcomes by index | tokens.yes = Yes, tokens.no = No |
| Order signing | EIP-712 verifyingContract = CTF Exchange V2, domain version "2" | EIP-712 verifyingContract = venue.exchange, domain version "1" |
| Order struct | V2 dropped taker, nonce, feeRateBps, expiration from the signed order and added timestamp, metadata, builder | Classic CTF fields: taker, expiration, nonce, feeRateBps (no timestamp/metadata/builder) |
| Order freshness | V2 order carries a mandatory creation timestamp (ms); GTD orders have a ~1 minute expiration threshold | Optional timestamp + recvWindow on POST /orders; stale orders rejected with HTTP 425. See Receive Window. |
| Neg-risk | Separate Neg Risk CTF Exchange V2 contract | Handled via venue system — extra approval to venue.adapter for SELL |
Authentication
Polymarket requires deriving API credentials (apiKey, secret, passphrase) through an L1 EIP-712 handshake, then signing every request with HMAC-SHA256 across 5POLY_* headers.
Limitless uses a scoped API token (a token ID + secret) generated in the UI. You sign each request with HMAC-SHA256 and send three headers: lmts-api-key, lmts-timestamp, and lmts-signature.
- Polymarket (V2)
- Limitless
POLY_* headers, but you do sign each request: derive the three lmts-* headers with sign_request(TOKEN_ID, SECRET, method, path, body) for every authenticated call. The timestamp must be within 30 seconds of server time. See the full Authentication guide for details, and the Programmatic API guide for partner scopes (sub-account management and delegated order signing).
Endpoint mapping
Market data
| Action | Polymarket (CLOB V2) | Limitless |
|---|---|---|
| List active markets | GET gamma-api.polymarket.com/markets?closed=false | GET /markets/active |
| Get market by slug | GET gamma-api.polymarket.com/markets/slug/:slug | GET /markets/:slug |
| Search markets | GET gamma-api.polymarket.com/public-search?q=... | GET /markets/search?query=... |
| Orderbook | GET clob.polymarket.com/book?token_id=... | GET /markets/:slug/orderbook |
| Price history | GET clob.polymarket.com/prices-history?market=... | GET /markets/:slug/historical-price |
| Midpoint price | GET clob.polymarket.com/midpoint?token_id=... | Compute from orderbook response |
Trading
| Action | Polymarket (CLOB V2) | Limitless |
|---|---|---|
| Place order | POST clob.polymarket.com/order | POST /orders |
| Cancel order | DELETE clob.polymarket.com/order (orderID in body) | DELETE /orders/:orderId |
| Cancel multiple | DELETE clob.polymarket.com/orders (array of ids in body) | POST /orders/cancel-batch |
| Cancel all | DELETE clob.polymarket.com/cancel-all | DELETE /orders/all/:slug |
| Get open orders | GET clob.polymarket.com/data/orders | GET /markets/:slug/user-orders |
| Get order by ID | GET clob.polymarket.com/data/order/:id | POST /orders/status/batch |
Portfolio
| Action | Polymarket (CLOB V2) | Limitless |
|---|---|---|
| Get positions | GET data-api.polymarket.com/positions?user=0x... | GET /portfolio/positions |
| Get trades | GET clob.polymarket.com/data/trades?maker_address=0x... | GET /portfolio/trades |
| PnL chart | N/A | GET /portfolio/pnl-chart |
| Trade history | GET data-api.polymarket.com/activity?user=0x... | GET /portfolio/history |
Fetch a market
- Polymarket (V2)
- Limitless
Build and sign an order
Both sides use EIP-712 typed data, but the order field sets diverge in V2. Polymarket V2 droppedtaker, nonce, feeRateBps, and expiration from the signed struct and added timestamp, metadata, and builder. Limitless keeps the classic CTF-style fields (taker, expiration, nonce, feeRateBps) and has no timestamp/metadata/builder. Key differences:
| Field | Polymarket (CLOB V2) | Limitless |
|---|---|---|
chainId | 137 (Polygon) | 8453 (Base) |
verifyingContract | CTF Exchange V2 0xE111180000d2663C0091e4f400237545B87B996B (Neg Risk: 0xe2222d279d744050d28e00520010520000310F59) | venue.exchange from market data |
name (EIP-712 domain) | "Polymarket CTF Exchange" (same for Neg Risk) | "Limitless CTF Exchange" |
version (EIP-712 domain) | "2" | "1" |
tokenId source | clobTokenIds[i] paired with outcomes[i] | tokens.yes / tokens.no |
| Fields dropped vs your V1 code | taker, nonce, feeRateBps, expiration | n/a |
| Fields added | timestamp (ms), metadata, builder | n/a |
feeRateBps | Not in the signed order (removed in V2) | Must match your profile’s rank.feeRateBps on fee-bearing markets |
- Polymarket (V2)
- Limitless
ownerId is your Limitless profile ID — a required field on every POST /orders request. Fetch it once from GET /profiles/me (the id field) and cache it. Polymarket’s SDK handles this internally; on Limitless you pass it explicitly.Porting a Polymarket agent
If you’re adapting a Polymarket trading bot (a V2 CLOB client integration, or a port of the now-archivedPolymarket/agents framework), here’s a checklist:
Swap credentials
Replace
POLYGON_WALLET_PRIVATE_KEY with your existing private key on Base. Add your scoped API token (TOKEN_ID + SECRET) and sign each request with HMAC (lmts-api-key/lmts-timestamp/lmts-signature) instead of Polymarket’s POLY_* headers. You still drop Polymarket’s L1/L2 credential derivation — Limitless tokens are issued in the UI.Collapse the three hosts into one
Replace
gamma-api.polymarket.com, clob.polymarket.com, and data-api.polymarket.com all with api.limitless.exchange. Positions and history that you read from data-api move to /portfolio/*.Update EIP-712 domain
Change the domain
name from "Polymarket CTF Exchange" to "Limitless CTF Exchange", and the version from "2" to "1".Swap token ID fields
Replace
clobTokenIds lookups with the market’s tokens object. On Limitless the convention is fixed: tokens.yes = Yes, tokens.no = No (unlike Polymarket, where you pair clobTokenIds against outcomes).Use venue addresses
Fetch
venue.exchange from GET /markets/:slug and use it as verifyingContract. On Polymarket V2 you targeted the fixed CTF Exchange V2 contract — on Limitless each market can have its own venue.Rework the order fields
Remove the V2 fields
timestamp, metadata, and builder — Limitless doesn’t use them. Add back the classic CTF fields Limitless requires: taker, expiration, nonce, and feeRateBps. Also drop SDK-side params like tick_size and signature_type from your order construction.Add ownerId to order submissions
POST /orders requires an ownerId field (your Limitless profile ID, from GET /profiles/me). Polymarket’s SDK handles this internally; on Limitless you pass it explicitly in every order payload alongside order, orderType, and marketSlug.Update approvals
Approve USDC on Base (not pUSD on Polygon) to
venue.exchange. For NegRisk SELL orders, also approve Conditional Tokens to venue.adapter. See venue system.WebSocket
| Polymarket (CLOB V2) | Limitless | |
|---|---|---|
| URL | wss://ws-subscriptions-clob.polymarket.com/ws/market and /ws/user | wss://ws.limitless.exchange |
| Namespace | Channel-based (market, user) | Socket.IO namespace /markets |
| Auth | auth object (apiKey, secret, passphrase) in the user-channel subscribe message | HMAC auth headers (lmts-api-key/lmts-timestamp/lmts-signature) during handshake |
Quick reference for agents
If you’re building an LLM-powered agent or bot, here’s the minimal flow:Partner and platform migrations
If you’re migrating a platform that manages multiple user accounts on Polymarket (e.g., a trading desk, social trading app, or embedded prediction market), the Limitless Programmatic API provides a first-class partner flow:| Polymarket pattern | Limitless equivalent |
|---|---|
| Manage many wallets and private keys | Create sub-accounts with server-managed wallets — no private key management |
| Sign orders per-user with their keys | Delegated signing — server signs via Privy, submit unsigned orders |
| Derive HMAC creds per integration | Derive scoped API tokens with granular permissions |
Recommended setup for partners:
- Store HMAC credentials on your backend — never expose them to frontends
- Use the SDK server-side to sign partner-authenticated requests
- Expose only your own app-specific endpoints to the frontend
- Keep public market reads (orderbooks, prices) directly in the browser
Next steps
Python quick start
Full end-to-end walkthrough with error handling.
Venue system
How venue contracts and token approvals work.
Programmatic API
Partner integrations, sub-accounts, and delegated signing.
API reference
Complete endpoint documentation.
EIP-712 signing
Full order type definition and field reference.