What changed
| Polymarket | Limitless | |
|---|---|---|
| Chain | Polygon (137) | Base (8453) |
| Collateral | USDC.e | USDC (6 decimals) |
| REST hosts | gamma-api.polymarket.com (data) + clob.polymarket.com (trading) | 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 | Single API key in X-API-Key header |
| SDKs | py-clob-client, @polymarket/clob-client, polymarket-client-sdk (Rust) | Python SDK, TypeScript SDK, or direct REST |
| Wallet types | EOA, Proxy, Gnosis Safe | EOA |
| Market lookup | condition_id or clobTokenIds | slug or address |
| Token IDs | clobTokenIds[0] = Yes, [1] = No | positionIds[0] = Yes, [1] = No |
| Order signing | EIP-712 verifyingContract = CTF Exchange | EIP-712 verifyingContract = venue.exchange |
| Neg-risk | Pass negRisk flag when creating orders | 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 single API key generated in the UI.
- Polymarket
- Limitless
POLY_* headers.
Endpoint mapping
Market data
| Action | Polymarket | Limitless |
|---|---|---|
| List active markets | GET gamma-api.polymarket.com/markets?active=true | GET /markets/active |
| Get market by slug | GET gamma-api.polymarket.com/markets?slug=... | GET /markets/:slug |
| Search markets | GET gamma-api.polymarket.com/markets?tag=... | GET /markets/search?query=... |
| Orderbook | GET clob.polymarket.com/book?token_id=... | GET /markets/:slug/orderbook |
| Price history | GET gamma-api.polymarket.com/markets/:id/prices-history | GET /markets/:slug/historical-price |
| Midpoint price | GET clob.polymarket.com/midpoint?token_id=... | Compute from orderbook response |
Trading
| Action | Polymarket | Limitless |
|---|---|---|
| Place order | POST clob.polymarket.com/order | POST /orders |
| Cancel order | DELETE clob.polymarket.com/order/:id | DELETE /orders/:orderId |
| Cancel multiple | DELETE clob.polymarket.com/cancel-orders (up to 3000) | POST /orders/cancel-batch |
| Cancel all | DELETE clob.polymarket.com/cancel-all | DELETE /orders/all/:slug |
| Get open orders | GET clob.polymarket.com/orders | GET /markets/:slug/user-orders |
| Get order by ID | GET clob.polymarket.com/order/:id | POST /orders/status/batch |
Portfolio
| Action | Polymarket | Limitless |
|---|---|---|
| Get positions | GET clob.polymarket.com/positions | GET /portfolio/positions |
| Get trades | GET clob.polymarket.com/trades | GET /portfolio/trades |
| PnL chart | N/A | GET /portfolio/pnl-chart |
| Trade history | GET gamma-api.polymarket.com/activity | GET /portfolio/history |
Fetch a market
- Polymarket
- Limitless
Build and sign an order
The order structure is almost identical — both use EIP-712 typed data with the same field names. Key differences:| Field | Polymarket | Limitless |
|---|---|---|
chainId | 137 (Polygon) | 8453 (Base) |
verifyingContract | CTF Exchange address | venue.exchange from market data |
name (EIP-712 domain) | "Polymarket CTF Exchange" | "Limitless CTF Exchange" |
tokenId source | clobTokenIds[0|1] | positionIds[0|1] |
- Polymarket
- Limitless
ownerId is your Limitless profile ID — a required field on every POST /orders request. You can find it in the Limitless UI or from your first authenticated API response. Polymarket’s SDK handles this internally; on Limitless you pass it explicitly.Porting a Polymarket agent
If you’re adapting an agent built with the Polymarket/agents framework, here’s a checklist:Swap credentials
Replace
POLYGON_WALLET_PRIVATE_KEY with your existing private key on Base. Add API_KEY with your lmts_ key. Remove any HMAC credential derivation code.Update base URLs
Replace both
gamma-api.polymarket.com and clob.polymarket.com with api.limitless.exchange.Swap token ID fields
Replace
clobTokenIds lookups with positionIds. The index convention is the same: [0] = Yes, [1] = No.Use venue addresses
Fetch
venue.exchange from GET /markets/:slug and use it as verifyingContract. On Polymarket you may have hardcoded the CTF Exchange address — on Limitless each market can have its own venue.Remove Polymarket-specific params
Drop
tick_size, neg_risk, funder, and signature_type from order construction. These are either not needed or handled by the venue system.Add ownerId to order submissions
POST /orders requires an ownerId field (your Limitless profile ID). 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 Polygon) to
venue.exchange. For NegRisk SELL orders, also approve Conditional Tokens to venue.adapter. See venue system.WebSocket
| Polymarket | Limitless | |
|---|---|---|
| URL | wss://ws-subscriptions-clob.polymarket.com/ws/... | wss://ws.limitless.exchange |
| Namespace | Channel-based (market, user) | Socket.IO namespace /markets |
| Auth | API key in connection params | X-API-Key header during handshake |
Rate limits
| Polymarket | Limitless | |
|---|---|---|
| Concurrent requests | Varies by builder tier | 2 |
| Minimum delay | Varies | 300 ms between requests |