This is the complete method reference for @polymarket/clob-client-v2, Polymarket’s official TypeScript SDK for the CLOB (Central Limit Order Book) V2 API. Every method is documented with its signature, parameters, return type, and a working code example.
⚠️ This page documents CLOB V2 (live April 28, 2026). Polymarket rebuilt its trading stack. The old V1 package (
@polymarket/clob-client) and V1-signed orders no longer work on production — use@polymarket/clob-client-v2. V2 is viem-first (not ethers.js), takes a single options-object constructor withchain(aChainenum, not a positionalchainId), renamedgetOrders()→getOpenOrders(), removedgetPositions()(positions come from the Data API), and migrated collateral from USDC.e to pUSD. See Migrating to CLOB V2.
New projects: Polymarket has published a unified TypeScript SDK — repo
Polymarket/ts-sdk, published to npm as@polymarket/client(beta0.1.0-beta.2) — that folds all REST APIs and WebSockets into one package. It is still pre-1.0 and currently has open bugs (POLY_1271 deposit-wallet auth, builder-fee 404 crashes, a trade-timestamp unit mismatch — see Polymarket Beta SDK Bugs). This page documents the CLOB-focused@polymarket/clob-client-v2, which remains the stable path for CLOB trading today.
For the Python equivalent, see the py-clob-client-v2 Reference. For a conceptual overview, see the Polymarket API Guide. For cross-platform comparison, see the Prediction Market API Reference.
Try it live: Test Polymarket endpoints in the API Playground — no setup required.
Installation and Setup
Installing @polymarket/clob-client-v2
npm install @polymarket/clob-client-v2 viem
CLOB V2 uses viem for wallet signing. You build a viem WalletClient and pass it as the signer.
ClobClient Initialization
ClobClient is the main entry point. V2 takes a single options object (V1 used positional arguments).
Signature:
import { ClobClient, Chain } from "@polymarket/clob-client-v2";
const client = new ClobClient({
host: string, // "https://clob.polymarket.com"
chain: Chain, // Chain.POLYGON (137) or Chain.AMOY (testnet)
signer?: WalletClient, // viem WalletClient (for trading)
creds?: ApiKeyCreds, // L2 credentials (or derive with createOrDeriveApiKey)
signatureType?: SignatureTypeV2,
funderAddress?: string, // proxy / Safe / deposit wallet address
});
Parameters:
| Option | Type | Required | Description |
|---|---|---|---|
host | string | Yes | CLOB API base URL. Use "https://clob.polymarket.com" for production |
chain | Chain | Yes | Chain.POLYGON (137) or Chain.AMOY (testnet). Note: chain, not chainId |
signer | WalletClient | For trading | A viem WalletClient (V2 is viem-first, not ethers.js) |
creds | ApiKeyCreds | For L2 endpoints | Pre-derived API credentials. Omit and call createOrDeriveApiKey() |
signatureType | SignatureTypeV2 | No | EOA (0), POLY_PROXY (1), POLY_GNOSIS_SAFE (2), POLY_1271 (3) |
funderAddress | string | For proxy wallets | The proxy/Safe/deposit wallet that holds your funds. Note: funderAddress |
Example — Read-only client (no authentication):
import { ClobClient, Chain } from "@polymarket/clob-client-v2";
const client = new ClobClient({ host: "https://clob.polymarket.com", chain: Chain.POLYGON });
// Public endpoints work without auth — note positional token ID + side in V2
const price = await client.getPrice("<token-id>", "BUY");
console.log("Price:", price);
Example — Authenticated client (viem signer):
import { ClobClient, Chain } from "@polymarket/clob-client-v2";
import { createWalletClient, http } from "viem";
import { polygon } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("<your-private-key>");
const walletClient = createWalletClient({ account, chain: polygon, transport: http() });
// Step 1 (L1): derive API credentials
const tempClient = new ClobClient({ host: "https://clob.polymarket.com", chain: Chain.POLYGON, signer: walletClient });
const creds = await tempClient.createOrDeriveApiKey();
// Step 2 (L2): authenticated client for trading
const client = new ClobClient({
host: "https://clob.polymarket.com",
chain: Chain.POLYGON,
signer: walletClient,
creds,
});
Signature Types and Deposit Wallets
CLOB V2 supports four signature types via the SignatureTypeV2 enum. New API users should use a deposit wallet (POLY_1271, type 3). Pass funderAddress for proxy, Safe, and deposit wallets.
import { ClobClient, Chain, SignatureTypeV2 } from "@polymarket/clob-client-v2";
// Deposit wallet (POLY_1271) — recommended for new API users
const depositClient = new ClobClient({
host: "https://clob.polymarket.com",
chain: Chain.POLYGON,
signer: walletClient,
creds,
signatureType: SignatureTypeV2.POLY_1271,
funderAddress: "<your-deposit-wallet-address>",
});
// Gnosis Safe (POLY_GNOSIS_SAFE) — existing browser-wallet flow
const safeClient = new ClobClient({
host: "https://clob.polymarket.com",
chain: Chain.POLYGON,
signer: walletClient,
creds,
signatureType: SignatureTypeV2.POLY_GNOSIS_SAFE,
funderAddress: "<your-proxy-wallet-address>",
});
SignatureTypeV2 | Value | Wallet |
|---|---|---|
EOA | 0 | Direct EOA (MetaMask); funderAddress is the EOA |
POLY_PROXY | 1 | Magic/email proxy wallet |
POLY_GNOSIS_SAFE | 2 | Gnosis Safe (browser wallet) |
POLY_1271 | 3 | Deposit wallet (ERC-1271) — recommended for new API users |
Authentication
createOrDeriveApiKey()
Derives or creates API credentials from your wallet signature (L1 auth). If credentials already exist for your wallet, it returns them; otherwise it creates new ones. Renamed from V1’s createApiKey/derive split — this is the one-shot method.
Signature:
client.createOrDeriveApiKey(nonce?: number): Promise<ApiKeyCreds>
Returns: An ApiKeyCreds object: { key, secret, passphrase }.
Example:
const creds = await tempClient.createOrDeriveApiKey();
console.log("API Key:", creds.key);
// Re-initialize with creds for L2 (authenticated) trading
const client = new ClobClient({
host: "https://clob.polymarket.com",
chain: Chain.POLYGON,
signer: walletClient,
creds,
});
Credentials are deterministic — deriving them again with the same wallet and signatureType produces the same result.
Other Authentication Methods
| Method | Description |
|---|---|
deriveApiKey(nonce?) | Derives existing credentials (throws if none exist) |
createApiKey(nonce?) | Creates new credentials |
getApiKeys() | Lists API key sets for your wallet |
deleteApiKey() | Deletes the current API credentials |
createReadonlyApiKey() | Creates read-only credentials (market data, no trading) |
getReadonlyApiKeys() / deleteReadonlyApiKey(key) | Manage read-only keys |
Balance Methods
CLOB V2 collateral is pUSD (an ERC-20 backed 1:1 by USDC; it replaced USDC.e). There is no getBalance() — use getBalanceAllowance(). Balances are returned in wei (1 pUSD = 10^6 wei); divide by 1e6.
getBalanceAllowance(params)
Returns your balance and token allowance for a given asset type.
Signature:
client.getBalanceAllowance(params: { asset_type: AssetType; token_id?: string }): Promise<BalanceAllowanceResponse>
Example — Check pUSD balance:
import { AssetType } from "@polymarket/clob-client-v2";
const result = await client.getBalanceAllowance({ asset_type: AssetType.COLLATERAL });
const balancePusd = parseInt(result.balance) / 1e6;
console.log(`Balance: ${balancePusd.toFixed(2)} pUSD`);
console.log(`Allowance: ${result.allowance}`);
Example — Check conditional (outcome token) balance:
const result = await client.getBalanceAllowance({
asset_type: AssetType.CONDITIONAL,
token_id: "<outcome-token-id>",
});
console.log(`Token balance: ${result.balance}`);
updateBalanceAllowance(params)
Forces the CLOB to re-read your on-chain balance/allowance (call after a deposit or approval).
await client.updateBalanceAllowance({ asset_type: AssetType.COLLATERAL });
Market Data Methods
These work without authentication — use a read-only client. In V2 these take positional arguments (V1 used { tokenID } objects). For real-time data, prefer the WebSocket API over polling. For batch queries, use getPrices/getMidpoints/getOrderBooks.
getPrice(tokenID, side)
client.getPrice(tokenID: string, side: string): Promise<string>
const price = await client.getPrice("<token-id>", "BUY");
console.log(`Best buy price: $${price}`);
getMidpoint(tokenID)
const midpoint = await client.getMidpoint("<token-id>");
console.log(`Midpoint: $${midpoint}`);
getOrderBook(tokenID)
Returns an OrderBookSummary with bids and asks (each entry has price and size), plus inline tick_size, neg_risk, min_order_size, and last_trade_price.
const book = await client.getOrderBook("<token-id>");
console.log("Top bids:");
book.bids.slice(0, 5).forEach((bid) => console.log(` $${bid.price} — ${bid.size}`));
console.log("Top asks:");
book.asks.slice(0, 5).forEach((ask) => console.log(` $${ask.price} — ${ask.size}`));
getOrderBooks(params)
Batch — fetch multiple books in one request. Takes an array of BookParams.
const books = await client.getOrderBooks([
{ token_id: "<token-id-1>" },
{ token_id: "<token-id-2>" },
]);
getTickSize / getNegRisk / getSpread / getLastTradePrice
const tickSize = await client.getTickSize("<token-id>"); // e.g. "0.01"
const negRisk = await client.getNegRisk("<token-id>"); // boolean
const spread = await client.getSpread("<token-id>");
const lastTrade = await client.getLastTradePrice("<token-id>");
getClobMarketInfo(conditionID)
Returns tick size, min order size, fee details, and tokens for a market in one call.
const info = await client.getClobMarketInfo("<condition-id>");
getPricesHistory(params)
const now = Math.floor(Date.now() / 1000);
const history = await client.getPricesHistory({
market: "<token-id>",
startTs: now - 86400,
endTs: now,
fidelity: 100,
});
Batch variants
client.getMidpoints(params: BookParams[]): Promise<...>
client.getPrices(params: BookParams[]): Promise<...>
client.getSpreads(params: BookParams[]): Promise<...>
Order Types
Limit orders (OrderArgs) give you price control; market orders (MarketOrderArgs) give you immediate execution. V2 change: orders no longer carry feeRateBps or nonce — fees are protocol-set at match time, and tick size / neg-risk move to a separate options argument.
OrderArgs (limit)
interface OrderArgs {
tokenID: string; // The outcome token to trade
price: number; // Decimal 0.01–0.99
size: number; // Number of shares
side: Side; // Side.BUY or Side.SELL
expiration?: number; // Unix timestamp (use with OrderType.GTD)
}
MarketOrderArgs (market)
interface MarketOrderArgs {
tokenID: string;
amount: number; // USDC to spend (BUY) or shares (SELL)
side: Side;
orderType: OrderType; // OrderType.FOK or OrderType.FAK
}
Order options & enums
Pass tick size and neg-risk via the options object on order-creation methods:
import { Side, OrderType } from "@polymarket/clob-client-v2";
// options: { tickSize: "0.1" | "0.01" | "0.001" | "0.0001"; negRisk?: boolean }
OrderType | Behavior |
|---|---|
GTC | Good-Til-Cancelled — rests on the book until filled/cancelled |
GTD | Good-Til-Date — rests until an expiration timestamp |
FOK | Fill-Or-Kill — fills entirely immediately or is rejected |
FAK | Fill-And-Kill — fills what it can, cancels the rest |
Order Placement
All placement methods require an authenticated (L2) client. Orders take an options object ({ tickSize, negRisk }) and the order type.
createAndPostOrder(orderArgs, options, orderType)
The one-step convenience method for limit orders.
import { Side, OrderType } from "@polymarket/clob-client-v2";
const resp = await client.createAndPostOrder(
{ tokenID: "<token-id>", price: 0.4, size: 100, side: Side.BUY },
{ tickSize: "0.01" }, // add negRisk: true for neg-risk markets
OrderType.GTC,
);
console.log("Order:", resp);
createAndPostMarketOrder(marketOrderArgs, options, orderType)
The one-step method for market orders.
const resp = await client.createAndPostMarketOrder(
{ tokenID: "<token-id>", amount: 100, side: Side.BUY, orderType: OrderType.FOK },
{ tickSize: "0.01" },
OrderType.FOK,
);
createOrder + postOrder (two-step)
Use when you need to inspect, log, or batch the signed order before submitting.
const signed = await client.createOrder(
{ tokenID: "<token-id>", price: 0.55, size: 100, side: Side.BUY },
{ tickSize: "0.01" },
);
const resp = await client.postOrder(signed, OrderType.GTC);
console.log("Order ID:", resp.orderID);
Batch: postOrders
const prices = [0.50, 0.52, 0.54];
const opts = { tickSize: "0.01" };
const signedOrders = await Promise.all(
prices.map((price) =>
client.createOrder({ tokenID: "<token-id>", price, size: 50, side: Side.BUY }, opts),
),
);
const resp = await client.postOrders(signedOrders);
Order Management
getOrder(orderID)
const order = await client.getOrder("<order-id>");
console.log(`Status: ${order.status}`);
getOpenOrders(params)
Returns your open orders. This was getOrders() in V1 — renamed in V2.
const orders = await client.getOpenOrders();
console.log(`You have ${orders.length} open orders`);
cancelOrder(payload)
Cancels a single order. V2 takes an OrderPayload ({ orderID }), not a bare string.
const result = await client.cancelOrder({ orderID: "<order-id>" });
cancelOrders / cancelAll / cancelMarketOrders
await client.cancelOrders(["<hash-1>", "<hash-2>"]); // by order hash
await client.cancelAll(); // everything
await client.cancelMarketOrders({ market: "<condition-id>" });
Positions (Data API)
CLOB V2 has no getPositions() on the client (it was removed, mirroring the Python SDK). Fetch positions from the public Data API:
const wallet = "<your-funder-address>";
const res = await fetch(`https://data-api.polymarket.com/positions?user=${wallet}`);
const positions = await res.json();
positions.forEach((p: any) => console.log(`${p.title} (${p.outcome}): ${p.size} @ ${p.avgPrice}`));
For your own fills, getTrades() is available on the client. See the py_clob_client get_positions page for the full Data API field reference.
Server Utilities
const status = await client.getOk(); // "OK"
const time = await client.getServerTime(); // server clock (for drift checks)
const version = await client.getVersion();
If your local clock drifts from the server, order signatures may be rejected — use getServerTime() to detect it.
Common Pitfalls
- Still on V1 —
@polymarket/clob-clientno longer works on production. Install@polymarket/clob-client-v2and import from it. - Using ethers instead of viem — V2 is viem-first. Build the signer with
createWalletClient()+privateKeyToAccount(). chainIdvschain— the constructor takeschain(aChainenum value), not a positionalchainId.fundervsfunderAddress— the constructor option isfunderAddress.- Object args on market-data methods — V2 market-data methods take positional args (
getOrderBook("<id>"),getPrice("<id>", "BUY")), not{ tokenID }. - Looking for
getPositions()/getOrders()—getPositions()was removed (use the Data API);getOrders()is nowgetOpenOrders(). - Setting fees —
OrderArgsno longer takesfeeRateBps; fees are protocol-set at match time. - Tick size in the wrong place — pass
tickSize(andnegRisk) via the orderoptionsobject, not onOrderArgs. - Not awaiting — every
ClobClientmethod returns aPromise.
FAQ
How do I install the Polymarket TypeScript SDK?
Run npm install @polymarket/clob-client-v2 viem. CLOB V2 uses viem for signing (not ethers.js). Import ClobClient and construct it with a single options object: new ClobClient({ host: "https://clob.polymarket.com", chain: Chain.POLYGON, signer }), where signer is a viem WalletClient. The old @polymarket/clob-client (V1) no longer works on production.
What is the difference between createOrder and createAndPostOrder?
createOrder(orderArgs, options) signs the order locally and returns it; the order isn’t live until you call postOrder(signed, orderType). createAndPostOrder(orderArgs, options, orderType) does both in one call. Use the two-step form to inspect, log, or batch with postOrders(). For market orders, the one-step method is createAndPostMarketOrder().
How do I set up authentication in the TypeScript SDK?
Build a viem WalletClient from your private key, construct ClobClient({ host, chain, signer }) (add signatureType and funderAddress for proxy/Safe/deposit wallets), then call createOrDeriveApiKey() to get L1-derived credentials. Re-construct with creds (or pass them in the constructor) for L2-authenticated trading. signatureType uses SignatureTypeV2: 0 EOA, 1 POLY_PROXY, 2 POLY_GNOSIS_SAFE, 3 POLY_1271 (deposit wallets, recommended for new API users).
Can I use the Polymarket TypeScript SDK with Viem instead of ethers.js?
In CLOB V2, viem is the default. The official examples build the signer with createWalletClient()/privateKeyToAccount() and pass it as signer. V1 used ethers.js; the V2 client is viem-first.
What price format does the Polymarket TypeScript SDK use?
Prices are decimals between 0 and 1 representing probability — 0.65 means 65% implied probability and $0.65 per share. Limit-order size is in shares; market orders take an amount in USDC. Check a market’s tick size with getTickSize() and pass it via the order options ({ tickSize: "0.01" }).
See Also
- py-clob-client-v2 Reference — Python SDK equivalent
- Polymarket API Guide — Full API reference (CLOB V2)
- Polymarket Auth Troubleshooting — Fix authentication errors
- Polymarket WebSocket Guide — Real-time streaming
- Polymarket Rate Limits Guide — Rate limits and retry strategies
- Prediction Market API Reference — Cross-platform comparison
- Polymarket Rust SDK Reference — Rust SDK alternative
This guide is maintained by AgentBets.ai. Found an error or API change we missed? Let us know on Twitter.
Not financial advice. Built for builders.
