py-clob-client-v2 is Polymarket’s official Python SDK for trading on the CLOB (Central Limit Order Book) API. It installs as py-clob-client-v2 and imports as py_clob_client_v2. This reference documents every public method — signature, parameters, return type, and working code example — so you can look up exactly how to call any function without reading source code.

⚠️ This page documents CLOB V2 (live April 28, 2026). Polymarket migrated its entire trading stack to CLOB V2 in a hard cutover. The old V1 package (py-clob-client) and V1-signed orders no longer work on production — you must use py-clob-client-v2. V2 also renamed several methods (create_or_derive_api_creds()create_or_derive_api_key(), get_orders()get_open_orders(), cancel()cancel_order()), removed others (get_balance(), get_positions()), switched the BUY/SELL constants to a Side enum, migrated collateral from USDC.e to pUSD, and changed the order struct and fee model. Migrating from V1? See Polymarket’s Migrating to CLOB V2 guide and the Polymarket API Tutorial.

For a step-by-step tutorial on the full Polymarket API ecosystem, see the Polymarket API Tutorial. For side-by-side comparison with Kalshi’s Python SDK, see the Prediction Market API Reference.

Try it live: Test Polymarket endpoints in the API Playground — no setup required.

Why This Page Exists (What the README Doesn’t Cover)

The py-clob-client-v2 README and examples/ directory give you copy-pasteable starting points for unauthenticated and authenticated clients, market/limit orders, and token allowances. If you just need to get started, those are now good enough. This page exists for everything after that:

  • The Common Pitfalls table documents the bugs and silent failures the README doesn’t mention — installing the retired V1 package, the Side enum, signature_type confusion, FOK on thin markets, missing pUSD allowances
  • The Migrating from V1 section maps every renamed and removed method so V1 code you find online doesn’t lead you astray
  • The deep-dive sub-pages go far beyond the README’s examples with production error handling, retry patterns, and real-world code
  • The Choosing the Right Method Pattern decision tree helps you pick the right workflow for your use case
  • The Polymarket US compatibility note answers whether py-clob-client-v2 works with the CFTC-regulated US platform (it doesn’t)
  • The RFQ documentation covers the institutional-trading sub-client the README barely mentions

CLOB V2 cutover (April 28, 2026): Polymarket rebuilt its trading stack — new Exchange contracts, a rewritten CLOB backend, new V2 SDK packages, a new order struct, a new fee model, pUSD collateral (replacing USDC.e), and a new builder-attribution mechanism. There is no backward compatibility: the V1 packages (py-clob-client, @polymarket/clob-client) and V1-signed orders stopped working on production at cutover. Use py-clob-client-v2 (Python), @polymarket/clob-client-v2 (TypeScript, now built on viem), and rs-clob-client-v2 (Rust). This reference has been fully updated for V2.

Quick Method Lookup

MethodCategoryWhat It Does
get_balance_allowance()BalancepUSD/token balance + allowance (there is no get_balance() in V2)
update_balance_allowance()BalanceRefresh the cached balance/allowance
get_price()Order BookCurrent price for token/side
get_midpoint()Order BookMid between best bid/ask
get_order_book()Order BookFull bids/asks
get_order_books()Order BookBatch — multiple tokens
create_order()TradingSign a limit order
create_market_order()TradingSign a market order
create_and_post_order()TradingSign + post a limit order in one call
create_and_post_market_order()TradingSign + post a market order in one call
post_order()TradingSubmit signed order
post_orders()TradingBatch submit (up to 15)
get_order()ManagementSingle order by ID
get_open_orders()ManagementAll open orders (was get_orders() in V1)
cancel_order()ManagementCancel one order (was cancel() in V1)
cancel_orders()ManagementCancel a list of orders by hash
cancel_all()ManagementCancel all orders
cancel_market_orders()ManagementCancel all orders in one market
get_clob_market_info()MarketTick size, min order size, fees, tokens
create_or_derive_api_key()AuthDerive API credentials (was create_or_derive_api_creds())
set_api_creds()AuthActivate credentials

Positions: CLOB V2 has no client.get_positions(). Fetch positions from the Data APIGET https://data-api.polymarket.com/positions?user=<address>. RFQ methods live on the client.rfq sub-client.

Common Pitfalls

Before diving into the method reference, here are the issues that trip up most developers — none of which are documented in the official README:

PitfallWhat HappensFix
Using the V1 packagepy-clob-client orders are rejected on production after the V2 cutoverInstall py-clob-client-v2 and from py_clob_client_v2 import ClobClient — V1-signed orders no longer settle
Bare BUY/SELL importImportError / NameError — V1’s order_builder.constants import is goneUse the Side enum: from py_clob_client_v2 import Side then Side.BUY / Side.SELL
Wei conversionget_balance_allowance() returns "1250000000" and you think you have 1.25B pUSDDivide the balance field by 1e6 — pUSD uses 6 decimals, not 18
Wrong signature_typeAuth silently fails, orders rejected0 = EOA (MetaMask), 1 = POLY_PROXY (Magic/email), 2 = POLY_GNOSIS_SAFE, 3 = POLY_1271 deposit wallet (recommended for new API users)
Missing funderOrders attributed to wrong addressRequired for proxy/Safe/deposit wallets — this is the address holding your funds
FOK on thin marketsMarket orders fail completelyIf liquidity is thin, use FAK (fill-and-kill) for partial fills instead of FOK
No rate limit handlingScript crashes on 429SDK doesn’t handle retries — implement exponential backoff yourself. See Rate Limits Guide
Stale order bookPrices moved between read and tradeUse WebSocket for real-time data. See WebSocket Guide
Missing pUSD allowance (EOA)Orders fail with no clear errorCheck get_balance_allowance(AssetType.COLLATERAL) first — allowance must be > 0 (CLOB V2 collateral is pUSD)
Hyphen vs underscoreimport py-clob-client-v2 failsPackage installs as py-clob-client-v2 but imports as py_clob_client_v2
Looking for get_positions()AttributeError — the method was removed in V2Positions come from the Data API, not the client

Deep-Dive Method Guides

For expanded examples, error handling, and production patterns, see the dedicated guides for the most-used methods:

  • get_order_book() — OrderBookSummary, batch retrieval, spread calculation, depth analysis
  • get_balance_allowance() — BalanceAllowanceParams, AssetType, wei conversion, pre-trade validation
  • Position tracking — Reading positions from the Data API and computing P&L (CLOB V2 has no get_positions() client method)
  • create_order() — OrderArgs, MarketOrderArgs, GTC/GTD/FOK/FAK, tick_size, neg_risk, batch orders

Migrating from V1 (CLOB V2 Changes)

If you’re porting a V1 bot — or copy-pasting V1 code you found online — these are the changes that will break first. CLOB V2 went live April 28, 2026, and the V1 py-clob-client package no longer works against production.

Package and imports:

V1V2
pip install py-clob-clientpip install py-clob-client-v2
from py_clob_client.client import ClobClientfrom py_clob_client_v2 import ClobClient
from py_clob_client.clob_types import OrderArgs, ...from py_clob_client_v2 import OrderArgs, ... (all types are top-level)
from py_clob_client.order_builder.constants import BUY, SELLfrom py_clob_client_v2 import SideSide.BUY / Side.SELL

Renamed methods:

V1V2
create_or_derive_api_creds()create_or_derive_api_key()
get_orders()get_open_orders()
cancel(order_id)cancel_order(OrderPayload(orderID=...))

Removed methods (and what to use instead):

Removed in V2Replacement
get_balance()get_balance_allowance(BalanceAllowanceParams(asset_type=AssetType.COLLATERAL))
get_positions()Data API — GET https://data-api.polymarket.com/positions?user=<address>
Top-level get_rfq_quote() / accept_rfq_quote()The client.rfq sub-client

Behavioral changes:

  • Collateral is pUSD, not USDC.e. Balances and allowances are denominated in pUSD (still 6 decimals). API-only EOA traders wrap USDC.e → pUSD via the Collateral Onramp; proxy/Safe/deposit wallets handle this for you.
  • signature_type adds POLY_1271 (3) for deposit wallets, now recommended for new API users. SignatureTypeV2 is an enum (SignatureTypeV2.POLY_1271, etc.) but plain integers still work.
  • The order struct dropped nonce, feeRateBps, and taker and added timestamp, metadata, and builder. OrderArgs/MarketOrderArgs therefore no longer take fee_rate_bps/nonce/taker; they take builder_code, metadata, and user_usdc_balance.
  • Fees are protocol-set at match time, not embedded in your signed order. Don’t try to set a fee — read the live rate with get_fee_rate_bps() or get_clob_market_info().
  • create_order() and create_and_post_order() take an options argument (PartialCreateOrderOptions(tick_size=..., neg_risk=...)).
  • Pre-migration orders: V1 orders placed before the cutover are read via get_pre_migration_orders().

Note: py-clob-client-v2 is a young package (first published April 2026). Watch its GitHub Issues and the examples/ directory for the current method surface — the V2 API may still shift between minor releases.


Installation and Setup

Installing py-clob-client-v2

pip install py-clob-client-v2

The package name uses hyphens (py-clob-client-v2) but the Python import uses underscores (py_clob_client_v2). The old V1 package (py-clob-client) is retired — it no longer works against production after the CLOB V2 cutover.

Community alternative: The polymarket-apis package wraps CLOB, Gamma, Data, Web3, WebSocket, and GraphQL clients with Pydantic validation. Confirm it targets CLOB V2 before relying on it for trading — community wrappers can lag the official V2 release. See the full comparison below if you’re deciding between the two.

ClobClient Initialization

ClobClient is the main entry point for all SDK operations.

Signature:

ClobClient(
    host: str,
    chain_id: int,
    key: str = None,
    creds: ApiCreds = None,
    signature_type: int = None,
    funder: str = None,
    builder_config: BuilderConfig = None,
    use_server_time: bool = False,
    retry_on_error: bool = False,
    fee_slippage: float = 0,
)

Parameters:

ParameterTypeRequiredDescription
hoststrYesCLOB API base URL. Use https://clob.polymarket.com for production
chain_idintYesBlockchain chain ID. Use 137 for Polygon mainnet
keystrFor tradingYour Ethereum private key (hex string with or without 0x prefix)
credsApiCredsNoPre-derived API credentials. Pass these to skip the separate set_api_creds() call
signature_typeintNoWallet type: 0 = EOA (MetaMask), 1 = POLY_PROXY (Magic/email), 2 = POLY_GNOSIS_SAFE, 3 = POLY_1271 deposit wallet (recommended new)
funderstrFor proxy walletsThe proxy/Safe/deposit wallet address that holds your funds on Polymarket
builder_configBuilderConfigNoBuilder attribution config (see the Builder Program)
use_server_timeboolNoSign with the CLOB server’s time instead of local time — useful when your clock drifts
fee_slippagefloatNoTolerance for the protocol-set fee when building market orders

V2 change: chain_id is now required (it has no default), and the constructor is called with keyword arguments in every official example. Note the new creds, builder_config, use_server_time, and fee_slippage parameters.

Example — Read-only client (no authentication):

from py_clob_client_v2 import ClobClient

client = ClobClient(host="https://clob.polymarket.com", chain_id=137)

# Public endpoints work without auth
price = client.get_price(token_id="<token-id>", side="BUY")

Example — Authenticated client (EOA wallet):

from py_clob_client_v2 import ClobClient

# EOA (MetaMask) — funder is the EOA itself, so no signature_type/funder needed
client = ClobClient(
    host="https://clob.polymarket.com",
    chain_id=137,
    key="<your-private-key>",
)
client.set_api_creds(client.create_or_derive_api_key())

Example — Authenticated client (deposit wallet, POLY_1271 — recommended for new users):

from py_clob_client_v2 import ClobClient, SignatureTypeV2

client = ClobClient(
    host="https://clob.polymarket.com",
    chain_id=137,
    key="<your-private-key>",
    signature_type=SignatureTypeV2.POLY_1271,  # 3 — deposit wallet
    funder="<your-deposit-wallet-address>",
)
client.set_api_creds(client.create_or_derive_api_key())

Example — Authenticated client (Magic/email proxy, POLY_PROXY):

from py_clob_client_v2 import ClobClient, SignatureTypeV2

client = ClobClient(
    host="https://clob.polymarket.com",
    chain_id=137,
    key="<your-private-key>",
    signature_type=SignatureTypeV2.POLY_PROXY,  # 1 — Magic/email; use POLY_GNOSIS_SAFE (2) for a Safe
    funder="<your-proxy-wallet-address>",
)
client.set_api_creds(client.create_or_derive_api_key())

Authentication: create_or_derive_api_key()

Derives or creates API credentials from your wallet signature. Call this once, then reuse the credentials. This method was renamed in V2 — it was create_or_derive_api_creds() in V1.

Signature:

client.create_or_derive_api_key(nonce: int = None) -> ApiCreds

Returns: An ApiCreds object containing your API key, secret, and passphrase. Pass this to set_api_creds() to enable authenticated endpoints.

Usage:

creds = client.create_or_derive_api_key()
client.set_api_creds(creds)

# Now you can use authenticated endpoints (trading, balance, etc.)

You only need to derive credentials once per session. The credentials are deterministic — deriving them again with the same wallet produces the same result. If you already have your ApiCreds, you can pass them straight into the constructor (ClobClient(..., creds=ApiCreds(...))) and skip set_api_creds() entirely.

Related auth methods: create_api_key() (force-create new creds), derive_api_key() (derive existing creds only), get_api_keys() (list), and delete_api_key(). For monitoring agents that must never trade, use create_readonly_api_key() (see below).

Readonly API Keys

Create read-only API credentials that allow market data queries but prevent order placement — useful for monitoring dashboards and analytics agents that should never trade. V2 exposes create_readonly_api_key(), get_readonly_api_keys(), and delete_readonly_api_key(key).

Token Allowances (EOA Wallets)

If you use a standard EOA wallet (MetaMask, hardware wallet), you must set token allowances before trading. This is a one-time on-chain transaction that approves the V2 Exchange contracts to spend your pUSD (CLOB V2 migrated collateral from USDC.e to pUSD).

Check if allowances are set:

from py_clob_client_v2 import BalanceAllowanceParams, AssetType

result = client.get_balance_allowance(
    BalanceAllowanceParams(asset_type=AssetType.COLLATERAL)
)
if int(result['allowance']) == 0:
    print("No allowance set — you need to approve pUSD spending first")
    # See: https://docs.polymarket.com/v2-migration for approval instructions

If allowance is 0, all order placements will fail silently or with a cryptic error. This is the #1 issue new developers hit with py-clob-client-v2 on EOA wallets. Proxy, Safe, and deposit-wallet users (email/browser/POLY_1271) typically don’t need to worry about this — the proxy or deposit contract handles approvals.


Balance Methods

get_balance() — Removed in V2

There is no client.get_balance() method in CLOB V2. The standalone balance method was removed; use get_balance_allowance() instead (below), which returns both balance and allowance for a given asset type. If you’re porting V1 code that calls client.get_balance(), replace it:

# V1 (no longer works):
# balance_wei = client.get_balance()

# V2 equivalent:
from py_clob_client_v2 import BalanceAllowanceParams, AssetType

result = client.get_balance_allowance(
    BalanceAllowanceParams(asset_type=AssetType.COLLATERAL)
)
balance_pusd = int(result["balance"]) / 1e6
print(f"Balance: {balance_pusd:.2f} pUSD")

Common pitfall: The balance field is in wei (micro-pUSD), not pUSD. Divide by 1e6 (or 10**6) to get the pUSD amount. Forgetting this conversion is a frequent source of bugs.

get_balance_allowance() Method

Returns both your balance and the token allowance for a specific asset type. This is the canonical way to check funds in V2 — it replaces the removed get_balance() — and is essential for checking whether you have sufficient allowance set for trading.

Signature:

client.get_balance_allowance(params: BalanceAllowanceParams = None) -> dict

Parameters:

ParameterTypeRequiredDescription
paramsBalanceAllowanceParamsNoSpecifies the asset type and optional token ID

BalanceAllowanceParams fields:

FieldTypeDescription
asset_typeAssetTypeAssetType.COLLATERAL for pUSD, or AssetType.CONDITIONAL for outcome tokens
token_idstrRequired when asset_type is CONDITIONAL — the specific outcome token ID
signature_typeintOptional — override the client’s signature type for this lookup (defaults to -1 = unset)

Returns: A dictionary with balance and allowance fields, both as strings in wei.

Example — Check pUSD balance and allowance:

from py_clob_client_v2 import ClobClient, BalanceAllowanceParams, AssetType

client = ClobClient(
    host="https://clob.polymarket.com",
    chain_id=137,
    key="<your-private-key>",
)
client.set_api_creds(client.create_or_derive_api_key())

result = client.get_balance_allowance(
    BalanceAllowanceParams(asset_type=AssetType.COLLATERAL)
)
print(f"Balance: {int(result['balance']) / 1e6:.2f} pUSD")
print(f"Allowance: {result['allowance']}")

Example — Check conditional token balance:

result = client.get_balance_allowance(
    BalanceAllowanceParams(
        asset_type=AssetType.CONDITIONAL,
        token_id="<outcome-token-id>"
    )
)
print(f"Token balance: {result['balance']}")
print(f"Token allowance: {result['allowance']}")

update_balance_allowance() Method

After an on-chain deposit or approval, the CLOB caches your balance/allowance and may not reflect the change immediately. Call update_balance_allowance() with the same BalanceAllowanceParams to force a refresh:

client.update_balance_allowance(
    BalanceAllowanceParams(asset_type=AssetType.COLLATERAL)
)

Position Tracking (Data API)

CLOB V2 has no client.get_positions() method. Positions live in the Data API, a separate public service — you query it by wallet address with no authentication. The CLOB client handles balances and allowances (get_balance_allowance()); positions (shares held, average entry, unrealized P&L) are a Data API job.

Endpoint:

GET https://data-api.polymarket.com/positions?user=<wallet-address>

Each position object includes (among other fields) asset (the outcome token ID), conditionId, size (shares held), avgPrice (average entry price), curPrice (current price), cashPnl/percentPnl (unrealized P&L), title, and outcome.

Example — List all positions for a wallet:

import requests

WALLET = "<your-wallet-address>"  # the funder/proxy address holding your positions

positions = requests.get(
    "https://data-api.polymarket.com/positions",
    params={"user": WALLET},
).json()

for pos in positions:
    token_id = pos["asset"]
    size = float(pos["size"])
    avg_price = float(pos["avgPrice"])
    print(f"Token: {token_id[:16]}... | Shares: {size} | Avg Price: ${avg_price:.2f}")

Example — Check if you already hold a position before placing an order:

import requests
from py_clob_client_v2 import OrderArgs, OrderType, PartialCreateOrderOptions, Side

def has_position(wallet, target_token_id):
    """Check if we already hold a position in this outcome."""
    positions = requests.get(
        "https://data-api.polymarket.com/positions",
        params={"user": wallet},
    ).json()
    for pos in positions:
        if pos["asset"] == target_token_id and float(pos["size"]) > 0:
            return True
    return False

# Only buy if we don't already have a position
if not has_position(WALLET, "<token-id>"):
    client.create_and_post_order(
        order_args=OrderArgs(token_id="<token-id>", price=0.50, size=10.0, side=Side.BUY),
        options=PartialCreateOrderOptions(tick_size="0.01"),
        order_type=OrderType.GTC,
    )

The user parameter is the funder address that holds your positions (your proxy/Safe/deposit wallet, or the EOA itself), not necessarily the signing key. See the Data API Reference for activity, trade history, and P&L endpoints.


Order Types

MarketOrderArgs

MarketOrderArgs (an alias for MarketOrderArgsV2) is the data class for specifying market orders — orders that execute immediately against resting liquidity at the best available price.

Import:

from py_clob_client_v2 import MarketOrderArgs, OrderType, Side

Fields:

FieldTypeRequiredDescription
token_idstrYesThe outcome token ID to trade
amountfloatYesUSDC amount to spend (for BUY) or number of shares to sell (for SELL)
sideSideYesSide.BUY or Side.SELL
order_typeOrderTypeNoOrderType.FOK (default) or OrderType.FAK
pricefloatNoAuto-calculated from the book if omitted
user_usdc_balancefloatNoYour collateral balance; if provided and too small, the order size is reduced to fit fees
builder_codestrNobytes32 builder code for fee attribution (see the Builder Program)
metadatastrNoOptional bytes32 metadata attached to the order

V2 change: MarketOrderArgs no longer takes fee_rate_bps, nonce, or taker. Fees are protocol-set at match time, not embedded in your order. The new user_usdc_balance field lets the SDK fee-adjust market buys.

Example — Buy $25 worth of YES tokens at market price (one-step):

from py_clob_client_v2 import MarketOrderArgs, OrderType, PartialCreateOrderOptions, Side

response = client.create_and_post_market_order(
    order_args=MarketOrderArgs(
        token_id="<token-id>",
        amount=25.0,
        side=Side.BUY,
        order_type=OrderType.FOK,
    ),
    options=PartialCreateOrderOptions(tick_size="0.01"),
    order_type=OrderType.FOK,
)
print(response)

Example — Sell 10 shares at market price (two-step):

from py_clob_client_v2 import MarketOrderArgs, OrderType, PartialCreateOrderOptions, Side

sell_order = MarketOrderArgs(
    token_id="<token-id>",
    amount=10.0,
    side=Side.SELL,
    order_type=OrderType.FOK,
)

signed = client.create_market_order(sell_order, PartialCreateOrderOptions(tick_size="0.01"))
response = client.post_order(signed, OrderType.FOK)

Market orders use FOK (fill-or-kill) by default — the order must fill completely or it’s rejected entirely. If there isn’t enough resting liquidity to fill your full amount, switch to OrderType.FAK (fill-and-kill) to take what’s available and cancel the rest.

OrderArgs

OrderArgs (an alias for OrderArgsV2) is the data class for limit orders — orders that specify an exact price and rest on the order book until filled.

Import:

from py_clob_client_v2 import OrderArgs, OrderType, PartialCreateOrderOptions, Side

Fields:

FieldTypeRequiredDescription
token_idstrYesThe outcome token ID to trade
pricefloatYesPrice per share in USDC (0.01 to 0.99)
sizefloatYesNumber of shares to buy or sell
sideSideYesSide.BUY or Side.SELL
expirationintNoUnix timestamp after which the order expires. 0 (default) = no expiration (GTC); set a future timestamp and post with OrderType.GTD
builder_codestrNobytes32 builder code for fee attribution
metadatastrNoOptional bytes32 metadata attached to the order
user_usdc_balancefloatNoIf provided and insufficient to cover size × price plus fees, the size is reduced

V2 change: OrderArgs no longer takes nonce, fee_rate_bps, or taker. It adds builder_code, metadata, and user_usdc_balance. Tick size and neg-risk now live on the separate options argument to create_order(), not on OrderArgs.

Example — Place a limit buy order:

from py_clob_client_v2 import OrderArgs, OrderType, PartialCreateOrderOptions, Side

order = OrderArgs(
    token_id="<token-id>",
    price=0.50,
    size=10.0,
    side=Side.BUY,
)

signed = client.create_order(order, PartialCreateOrderOptions(tick_size="0.01"))
response = client.post_order(signed, OrderType.GTC)
print(response)

Key difference from MarketOrderArgs: OrderArgs uses price + size (price per share and number of shares), while MarketOrderArgs uses amount (total USDC to spend). Limit orders can use GTC (good-til-cancelled), GTD (good-til-date, via expiration), FOK, or FAK; market orders use FOK or FAK.


Order Placement Methods

Placing orders is the core trading workflow. py-clob-client-v2 separates order creation (signing) from order submission (posting) to give you maximum control. For simple trades, use create_and_post_order() (limit) or create_and_post_market_order() (market) as a shortcut. For production bots that need logging, validation, or batching, use the two-step create_order()post_order() pattern.

Choosing between limit and market orders depends on your urgency. Limit orders (OrderArgs) rest on the book until filled and give you price control — use them when you can wait for your price. Market orders (MarketOrderArgs) execute immediately against resting liquidity but give you no control over the fill price — use them when speed matters more than a few cents of slippage. Most autonomous agents use limit orders with GTC (good-til-cancelled) to avoid overpaying.

create_order() and post_order()

Order placement in py-clob-client-v2 is a two-step process: first sign the order locally, then post it to the CLOB API.

Signatures:

client.create_order(order_args: OrderArgs, options: PartialCreateOrderOptions = None) -> SignedOrder
client.post_order(signed_order, order_type: OrderType = OrderType.GTC, post_only: bool = False, defer_exec: bool = False) -> dict

create_order() Parameters:

ParameterTypeDescription
order_argsOrderArgsThe order specification (token, price, size, side)
optionsPartialCreateOrderOptionstick_size and neg_risk for the market (fetched if omitted)

post_order() Parameters:

ParameterTypeDescription
signed_ordersigned orderThe signed order from create_order()
order_typeOrderTypeOrderType.GTC, OrderType.GTD, OrderType.FOK, or OrderType.FAK
post_onlyboolIf True, rejects the order if it would immediately match. Use for market-making strategies
defer_execboolIf True, defers matching-engine execution (advanced — for coordinated multi-order submission)

Example:

from py_clob_client_v2 import OrderArgs, OrderType, PartialCreateOrderOptions, Side

order = OrderArgs(
    token_id="<token-id>",
    price=0.45,
    size=20.0,
    side=Side.BUY,
)

signed = client.create_order(order, PartialCreateOrderOptions(tick_size="0.01"))
response = client.post_order(signed, OrderType.GTC)
print(f"Order ID: {response['orderID']}")

Post-only example (for market makers):

signed = client.create_order(order, PartialCreateOrderOptions(tick_size="0.01"))
response = client.post_order(signed, OrderType.GTC, post_only=True)
# Rejects if the order would cross the spread

create_and_post_order()

Convenience method that combines create_order() and post_order() into a single call. For simple cases where you don’t need to inspect the signed order before posting.

Signature:

client.create_and_post_order(order_args: OrderArgs, options: PartialCreateOrderOptions = None, order_type: OrderType = OrderType.GTC, post_only: bool = False, defer_exec: bool = False) -> dict

Example:

from py_clob_client_v2 import ClobClient, OrderArgs, OrderType, PartialCreateOrderOptions, Side

client = ClobClient(host="https://clob.polymarket.com", chain_id=137, key="<key>")
client.set_api_creds(client.create_or_derive_api_key())

resp = client.create_and_post_order(
    order_args=OrderArgs(price=0.50, size=100.0, side=Side.BUY, token_id="<token-id>"),
    options=PartialCreateOrderOptions(tick_size="0.01"),
    order_type=OrderType.GTC,
)
print(resp)

Use the two-step create_order() + post_order() workflow when you need to log, validate, or modify the signed order before submitting. Use create_and_post_order() for straightforward trades.

create_market_order() and create_and_post_market_order()

create_market_order() signs a market order for immediate execution; create_and_post_market_order() signs and submits it in one call (the market-order counterpart to create_and_post_order()).

Signatures:

client.create_market_order(order_args: MarketOrderArgs, options: PartialCreateOrderOptions = None) -> SignedOrder
client.create_and_post_market_order(order_args: MarketOrderArgs, options: PartialCreateOrderOptions = None, order_type: OrderType = OrderType.FOK, defer_exec: bool = False) -> dict

Example:

from py_clob_client_v2 import MarketOrderArgs, OrderType, PartialCreateOrderOptions, Side

market_order = MarketOrderArgs(
    token_id="<token-id>",
    amount=50.0,
    side=Side.BUY,
    order_type=OrderType.FOK,
)

# One-step:
response = client.create_and_post_market_order(
    order_args=market_order,
    options=PartialCreateOrderOptions(tick_size="0.01"),
    order_type=OrderType.FOK,
)

Batch Orders

Place up to 15 orders in a single API call. Essential for market makers updating multiple price levels.

Signature:

client.post_orders(args: list, post_only: bool = False, defer_exec: bool = False) -> dict

Example:

from py_clob_client_v2 import OrderArgs, OrderType, PartialCreateOrderOptions, Side

opts = PartialCreateOrderOptions(tick_size="0.01")
orders = []
for price in [0.48, 0.49, 0.50]:
    order = OrderArgs(
        token_id="<token-id>",
        price=price,
        size=50.0,
        side=Side.BUY,
    )
    orders.append(client.create_order(order, opts))

response = client.post_orders(orders, post_only=False)

Note: In V2 the order type travels with each signed order, so post_orders() takes post_only/defer_exec flags rather than a single order_type for the whole batch.


Order Management Methods

After placing orders, you need to track their status, monitor fills, and cancel orders that are no longer wanted. These methods give you full visibility into your open and historical orders. In production bots, the typical pattern is: place orders, poll get_open_orders() periodically to check fill status, and cancel stale unfilled orders with cancel_order() or cancel_all().

get_order()

Retrieves a single order by its ID.

Signature:

client.get_order(order_id: str) -> dict

Example:

order = client.get_order("<order-id>")
print(f"Status: {order['status']}")
print(f"Filled: {order['size_matched']} / {order['original_size']}")

get_open_orders()

Retrieves all your open orders, optionally filtered. This was get_orders() in V1 — it was renamed in V2.

Signature:

client.get_open_orders(params: OpenOrderParams = None) -> list

Example:

open_orders = client.get_open_orders()
for order in open_orders:
    print(f"Order {order['id']}: {order['side']} {order['original_size']} @ {order['price']}")

Migrating? Orders placed before the CLOB V2 cutover aren’t returned here — read them with client.get_pre_migration_orders().

cancel_order()

Cancels a single order. This was cancel(order_id) in V1 — V2 renamed it and it now takes an OrderPayload instead of a bare ID string.

Signature:

client.cancel_order(payload: OrderPayload) -> dict

Example:

from py_clob_client_v2 import OrderPayload

response = client.cancel_order(OrderPayload(orderID="<order-id>"))
print(response)

cancel_orders() and cancel_market_orders()

Cancel a specific list of orders by hash, or every open order in a single market:

from py_clob_client_v2 import OrderMarketCancelParams

# Cancel a list of orders by hash
client.cancel_orders(["<order-hash-1>", "<order-hash-2>"])

# Cancel all open orders in one market
client.cancel_market_orders(OrderMarketCancelParams(market="<condition-id>"))

cancel_all()

Cancels all your open orders across all markets.

Signature:

client.cancel_all() -> dict

Example:

response = client.cancel_all()
print(f"Cancelled all open orders")

RFQ (Request for Quote) Methods

RFQ enables negotiated pricing for large orders. Instead of placing an order directly on the book, a requester asks for a quote and market makers respond with firm prices.

V2 change: RFQ is no longer a set of top-level client methods (V1’s client.get_rfq_quote() / client.accept_rfq_quote()). In V2 it lives on a dedicated client.rfq sub-client with an explicit requester/quoter split.

Who uses this: Institutional traders, high-volume agents, and market makers executing large positions where market impact is a concern. The typical flow is: requester creates a request → market makers respond with quotes → requester accepts the best quote → the trade executes off-book. Most retail traders and simple bots should use standard limit/market orders.

client.rfq methods:

MethodRoleWhat It Does
create_rfq_request(...)RequesterOpen an RFQ for a token/size
cancel_rfq_request(params)RequesterCancel an open request
get_rfq_requests(params)BothList RFQ requests
get_rfq_best_quote(params)RequesterRead the best quote received
get_rfq_requester_quotes(params)RequesterQuotes from the requester’s view
accept_rfq_quote(params)RequesterAccept a quote (AcceptQuoteParams) and execute off-book
create_rfq_quote(...)QuoterRespond to a request with a firm price
cancel_rfq_quote(params)QuoterCancel a quote you posted
get_rfq_quoter_quotes(params)QuoterQuotes from the quoter’s view
approve_rfq_order(params)QuoterApprove an order for an accepted quote
rfq_config()BothRead current RFQ configuration

Example — requester flow (sketch):

# RFQ lives on the sub-client in V2:
request = client.rfq.create_rfq_request(...)        # open the request
best = client.rfq.get_rfq_best_quote(...)           # read the best quote back
client.rfq.accept_rfq_quote(...)                    # accept it -> off-book execution

The RFQ param/response dataclasses (AcceptQuoteParams, CancelRfqRequestParams, GetRfqQuotesParams, etc.) live in py_clob_client_v2.rfq. Because the RFQ surface is the newest part of the V2 SDK, check the rfq module for current signatures before building against it.

RFQ vs Standard Orders

FactorStandard OrdersRFQ
Market impactVisible on the order bookOff-book, no impact
Price discoveryYou set the price (limit) or take the book (market)Market makers compete to quote you
Size limitsBatch up to 15 ordersSingle large block trades
SpeedImmediate (GTC rests, FOK fills or fails)Requires quote round-trip
Best for< $10K positions, automated strategies> $10K positions, institutional flow

Price and Order Book Methods

These methods provide market data — current prices, midpoints, and full order books. They work without authentication, so you can use them from a read-only client. For real-time data, consider the Polymarket WebSocket API instead of polling these endpoints. Polling is simpler to implement but consumes rate limit budget and introduces latency between price changes and your bot’s awareness of them.

When building a trading bot, the typical pattern is to use get_order_book() for initial state, then switch to WebSocket for live updates. Use get_midpoint() for quick price checks, and get_price() when you need the best available price on a specific side (bid vs ask).

get_price()

Returns the current price for a specific token and side.

Signature:

client.get_price(token_id: str, side: str) -> str

Parameters:

ParameterTypeDescription
token_idstrThe outcome token ID
sidestr"BUY" or "SELL" — the side you want the price for

Example:

buy_price = client.get_price(token_id="<token-id>", side="BUY")
sell_price = client.get_price(token_id="<token-id>", side="SELL")
print(f"Buy at: ${buy_price} | Sell at: ${sell_price}")

get_midpoint()

Returns the midpoint between the best bid and best ask.

Signature:

client.get_midpoint(token_id: str) -> str

Example:

mid = client.get_midpoint(token_id="<token-id>")
print(f"Midpoint: ${mid}")

get_order_book()

Returns the full order book for a token.

Signature:

client.get_order_book(token_id: str) -> dict

Returns: An OrderBookSummary with bids and asks arrays, each containing price/size entries sorted by price. The /book response also carries a few trading parameters inline — min_order_size, neg_risk, and tick_size — so you don’t need a separate lookup for them. For market context (question text, slug, end date, outcome labels) use the Gamma API or get_clob_market_info().

Example:

book = client.get_order_book(token_id="<token-id>")

print("Top 5 bids:")
for bid in book["bids"][:5]:
    print(f"  ${bid['price']}{bid['size']} shares")

print("Top 5 asks:")
for ask in book["asks"][:5]:
    print(f"  ${ask['price']}{ask['size']} shares")

get_order_books()

Batch endpoint — fetch order books for multiple tokens in one request.

Signature:

client.get_order_books(params: list[BookParams]) -> list

Example:

from py_clob_client_v2 import BookParams

books = client.get_order_books([
    BookParams(token_id="<token-id-1>"),
    BookParams(token_id="<token-id-2>"),
])

More market-data methods: V2 also exposes batch and history variants — get_prices(), get_midpoints(), get_spread()/get_spreads(), get_last_trade_price()/get_last_trades_prices(), and get_prices_history() — plus get_clob_market_info() for tick size, min order size, fees, and tokens in one call.

Bridge Operations

The Polymarket Bridge API includes a POST /withdraw endpoint for bridging funds to other chains. This endpoint is accessed via the Bridge API (https://bridge.polymarket.com/withdraw), not through py-clob-client-v2 directly. (CLOB V2 collateral is pUSD; the Bridge handles the on/off-ramp.) See the Polymarket API Guide — Bridge API for endpoint documentation and example code.


Choosing the Right Method Pattern

For quick reference, here is how common trading workflows map to SDK methods:

WorkflowMethodsNotes
Check if I can tradeget_balance_allowance()Verify pUSD balance (divide by 1e6) and that allowance > 0 — there’s no get_balance() in V2
Find a market to tradeUse Gamma API (requests.get) → get_order_book()Gamma for discovery, CLOB for execution data
Place a simple betcreate_and_post_order() (limit) / create_and_post_market_order() (market)One-step convenience methods
Place a bet with validationcreate_order() → inspect → post_order()Two-step when you need to log or validate before submitting
Place many orders at onceLoop create_order()post_orders()Batch up to 15 orders in a single API call
Buy immediately at market pricecreate_and_post_market_order(FOK)Use FOK for full fill; switch to FAK if liquidity is thin
Check position before tradingData API GET /positions → check → create_order()Positions come from the Data API, not the client
Cancel everythingcancel_all()Emergency reset; also useful at bot shutdown
Monitor fillsget_order() or get_open_orders()Poll periodically or use WebSocket for real-time fill events

For expanded examples and production patterns on each method, see the deep-dive guides linked in the method lookup table at the top of this page.


Version History

CLOB V2 is a clean break from the V1 release line, so this table tracks the V1 → V2 transition rather than individual V2 point releases. The py-clob-client-v2 package is young and moves quickly — check PyPI and the GitHub releases for the current version.

MilestoneDateKey Changes
CLOB V2 cutoverApr 28, 2026Hard migration to py-clob-client-v2: new Exchange contracts, rewritten CLOB backend, a new order struct (drops nonce/feeRateBps/taker, adds timestamp/metadata/builder), protocol-set fees, pUSD collateral, the Side enum, options-based order creation, the RFQ sub-client, method renames (create_or_derive_api_key, get_open_orders, cancel_order), and removal of get_balance()/get_positions(). V1 packages and V1-signed orders stopped working on production.
py-clob-client v0.34.6 (final V1)Feb 19, 2026Last notable V1 release before V2 superseded it (tick size cache fix). V1 is now retired
py-clob-client v0.31.02025V1 introduced RFQ methods and readonly API keys

For the V2 changelog, see py-clob-client-v2 releases on GitHub. For Polymarket’s platform-level changes, see the Polymarket Changelog and Migrating to CLOB V2.


Polymarket US Compatibility

py-clob-client-v2 does not work with Polymarket US. This is the most common source of confusion for US-based developers.

Polymarket US is a CFTC-regulated Designated Contract Market (DCM) that launched after receiving CFTC approval in November 2025. It operates on a completely separate infrastructure from the global Polymarket platform:

Global PolymarketPolymarket US
API endpointclob.polymarket.comapi.polymarket.us
Auth schemeEIP-712 (wallet signing)Ed25519 (key-pair signing)
Python SDKpy-clob-client-v2Separate CFTC-compliant SDKs
KYC requiredNoYes (mandatory)
RegulationUnregulated (non-US)CFTC-regulated DCM

If you need to integrate with the US platform, you’ll need to use the SDKs provided at polymarketexchange.com/developers.html. Pointing ClobClient at api.polymarket.us will fail — the authentication schemes are fundamentally incompatible.

The Polymarket US developer portal now notes that the Trading Gateway is being deprecated in favor of the Exchange Gateway — new integrations should target the Exchange Gateway. No official Python SDK has been announced for Polymarket US as of May 2026.

For more on the differences between global and US Polymarket APIs, see the Polymarket API Guide.


py-clob-client-v2 vs polymarket-apis

Two Python packages exist for Polymarket development. Here’s when to use each.

py-clob-client-v2polymarket-apis
MaintainerPolymarket (official)Community (qualiaenjoyer)
CLOB versionCLOB V2Confirm V2 support before trading
API coverageCLOB onlyCLOB, Gamma, Data, Web3, WebSockets, GraphQL
Type safetyDataclassesPydantic validation
Installpip install py-clob-client-v2pip install polymarket-apis

Use py-clob-client-v2 when:

  • You’re building a trading bot focused on order placement and management
  • You want the official SDK that Polymarket maintains and tests against their API
  • Your project only interacts with the CLOB (order book, orders, balances)
  • You need V2 signing — it’s guaranteed to track the current Exchange contracts and order struct

Use polymarket-apis when:

  • You need market discovery (Gamma), portfolio analytics (Data API), and real-time streaming (WebSockets) in one package
  • You want Pydantic-validated response models with type safety
  • You want a single unified client instead of juggling py_clob_client_v2 + requests for Gamma + custom WebSocket code
  • Caveat: community wrappers can lag the official V2 release — confirm it signs CLOB V2 orders correctly before trusting it with real funds

Can you use both? Yes — some projects use polymarket-apis for market discovery and data, then switch to py-clob-client-v2 for order execution where they want the official V2 signing logic. The two packages don’t conflict.


See Also


This reference is maintained by AgentBets.ai. Found an error or SDK change we missed? Let us know on Twitter.

Not financial advice. Built for builders.