py_clob_client is Polymarket’s official Python SDK for trading on the CLOB (Central Limit Order Book) API. 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.

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)

Polymarket substantially rewrote the py-clob-client README in early 2026 — it now includes full copy-pasteable examples for unauthenticated and authenticated clients, market/limit orders, and token allowances. If you just need to get started, the README is now good enough. This page exists for everything after that:

New (April 2026): Polymarket has published py-clob-client-v2 and clob-client-v2 (TypeScript) as early-stage successor repos. Both were created in April 2026 with empty descriptions and minimal activity — this reference still documents v1 (py-clob-client v0.34.6), which remains the production SDK with 1.1M monthly PyPI downloads. We’ll add a v2 migration section once Polymarket ships a release and publishes migration notes. Watch both repos if you’re building new integrations.

Quick Method Lookup

MethodCategoryWhat It Does
get_balance()BalanceUSDC balance in wei
get_balance_allowance()BalanceBalance + token allowance
get_positions()PositionsAll open positions
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 in one call
post_order()TradingSubmit signed order
post_orders()TradingBatch submit (up to 15)
get_order()ManagementSingle order by ID
get_orders()ManagementAll open orders
cancel()ManagementCancel one order
cancel_all()ManagementCancel all orders
create_or_derive_api_creds()AuthDerive API credentials
set_api_creds()AuthActivate credentials

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
Wei conversionget_balance() returns "1250000000" and you think you have 1.25B USDCDivide by 1e6 — USDC uses 6 decimals, not 18
Wrong signature_typeAuth silently fails, orders rejectedUse 0 for MetaMask/EOA, 1 for Magic/email, 2 for browser/Gnosis Safe (most common)
Missing funderOrders attributed to wrong addressRequired for proxy 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 allowance (EOA)Orders fail with no clear errorCheck get_balance_allowance() first — allowance must be > 0
Hyphen vs underscoreimport py-clob-client failsPackage installs as py-clob-client but imports as py_clob_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
  • get_positions() — Position tracking, P&L calculation, Data API alternative
  • create_order() — OrderArgs, MarketOrderArgs, GTC/FOK/FAK, tick_size, neg_risk, batch orders

Known Issues & Workarounds (April 2026)

These are active bugs and pain points from the py-clob-client GitHub Issues page as of April 2026. If you’re hitting an error, check here first.

IssueProblemWorkaround
#326 — Fee docs mismatchFee documentation contradicts the CLOB API /fee-rate endpoint response for Sports markets, so hardcoded fee assumptions may undercharge or overchargeAlways read the live /fee-rate endpoint per market at runtime — do not cache fees from the docs. Re-verify when Sports markets resolve
#323 — Market-order roundingMarket order price uses round_normal instead of round_down, producing different fills from the official TypeScript client on identical inputsUntil a fix lands, floor the price yourself with math.floor(price * 10**tick_exp) / 10**tick_exp before building MarketOrderArgs. Track PR #325
#319 — API balance reads zeroget_balance() returns 0 via the SDK while the Polymarket UI shows a positive balance (e.g. $3.40) for the same walletDouble-check funder and signature_type (see Common Pitfalls). Cross-check with the Data API /positions endpoint. If they disagree, re-derive API creds
#316 — Cancel returns only IDscancel() / cancel_all() return just order IDs, so you can’t see sizeMatched at the moment of cancellationAfter cancelling, immediately call get_order(order_id) to read the final matched size. PR #320 proposes returning full objects
#311 — Selling positions failsErrors when trying to sell positions through the CLOB despite valid balancesVerify the outcome-token allowance via get_balance_allowance(AssetType.CONDITIONAL, token_id=...) before placing the SELL. If the conditional allowance is 0, re-approve on-chain
#301 — Minimum order sizeOrders rejected with “Size (1.08) lower than the minimum: 5”Polymarket enforces a minimum order size per market. Check the market’s min_order_size via the Gamma API before placing orders. Not all markets have the same minimum
#300 — Inconsistent balance allowanceget_balance_allowance() returns discrepant balance calculationsCompare against get_balance() as a sanity check. If the values diverge, re-derive your API credentials with create_or_derive_api_creds()
#299 — macOS install fails (Python 3.13)pip install py-clob-client fails due to ckzg wheel build errors on macOSPin Python to 3.11 or 3.12. Alternatively, install ckzg separately first: pip install ckzg then retry. Python 3.13 support is pending upstream fixes
#297 — Proxy wallet allowances stuck at 0CLOB balance shows correctly but allowances remain at 0, preventing tradingVerify your funder address matches the proxy wallet holding funds. Re-approve allowances on-chain if the proxy contract was recently upgraded
#295 — Can’t redeem closed marketsUnable to redeem positions in resolved markets via the SDKUse the Web3 contract directly to call the redeemPositions() function on the CTF Exchange contract, or redeem through the Polymarket UI
#294 — Sell order signature errorsReversed maker/taker semantics causing invalid signature errors on SELL ordersEnsure you’re on v0.34.6. If the error persists, verify your signature_type matches your wallet type and that you’re using the correct funder for proxy wallets
#293 — API trades not visible in UIOrders placed via the API don’t appear in the Polymarket web UIThis happens when the API wallet address doesn’t match the UI session wallet. Verify you’re using the same private key / proxy address in both contexts
#292 — WSS silent freezeCLOB WebSocket server accepts connection and subscription but sends no book data, so clients silently stallAdd a watchdog: if no book message arrives within 15s of subscribing, force-reconnect. See the Polymarket WebSocket Guide for reference code
#288 — EOA signature errors400 invalid signature placing simple market orders with EOA + MetaMaskConfirm signature_type=0 for EOA (not 2) and that chain_id=137. If still failing, drop back to limit orders as a workaround
#287 — False balance/allowance errors“not enough balance / allowance” despite full approvals and correct balanceRelated to #297. Re-derive API creds with create_or_derive_api_creds(); if a proxy wallet, verify funder matches the proxy holding funds
#284 — 401 on /order401 Unauthorized on POST /order even though L2 API creds and other private endpoints work for the same sessionRe-create API creds — this usually indicates stale or wrong-scope credentials. Verify the host is https://clob.polymarket.com, not a regional mirror

Tip: Watch the GitHub Issues page and PRs — there are currently 67 open PRs. Notable pending fixes include round_down for market orders (#325), configurable HTTP timeouts and error context (#318), proxy support on ClobClient (#315), type hint improvements (#313), the setup.pypyproject.toml migration (#312), and Enum fixes (#308).


Installation and Setup

Installing py_clob_client

pip install py-clob-client

The package name uses hyphens (py-clob-client) but the Python import uses underscores (py_clob_client).

Community alternative: The polymarket-apis package (v0.5.7, Python 3.12+) wraps CLOB, Gamma, Data, Web3, WebSocket, and GraphQL clients with Pydantic validation. 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,
    key: str = None,
    chain_id: int = None,
    signature_type: int = 0,
    funder: str = None
)

Parameters:

ParameterTypeRequiredDescription
hoststrYesCLOB API base URL. Use https://clob.polymarket.com for production
keystrFor tradingYour Ethereum private key (hex string with or without 0x prefix)
chain_idintFor tradingBlockchain chain ID. Use 137 for Polygon mainnet
signature_typeintNoWallet type: 0 = EOA (MetaMask), 1 = Magic/email wallet, 2 = Gnosis Safe / browser wallet proxy (most common)
funderstrFor proxy walletsThe proxy wallet address that holds your funds on Polymarket

Example — Read-only client (no authentication):

from py_clob_client.client import ClobClient

client = ClobClient("https://clob.polymarket.com")

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

Example — Authenticated client (EOA wallet):

from py_clob_client.client import ClobClient

# Use signature_type=2 for browser/Gnosis Safe wallets (most common)
client = ClobClient(
    "https://clob.polymarket.com",
    key="<your-private-key>",
    chain_id=137
)
client.set_api_creds(client.create_or_derive_api_creds())

Example — Authenticated client (Magic/email wallet):

from py_clob_client.client import ClobClient

client = ClobClient(
    "https://clob.polymarket.com",
    key="<your-private-key>",
    chain_id=137,
    signature_type=1,  # Magic/email; use 2 for browser/Gnosis Safe (most common)
    funder="<your-proxy-wallet-address>"
)
client.set_api_creds(client.create_or_derive_api_creds())

Authentication: create_or_derive_api_creds()

Derives or creates API credentials from your wallet signature. Call this once, then reuse the credentials.

Signature:

client.create_or_derive_api_creds() -> 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_creds()
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.

Readonly API Keys

Added in v0.34.x. You can create read-only API credentials that allow market data and position queries but prevent order placement. Useful for monitoring dashboards and analytics agents that should never trade.

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 Polymarket exchange contract to spend your USDC.

Check if allowances are set:

result = client.get_balance_allowance(
    BalanceAllowanceParams(asset_type=AssetType.COLLATERAL)
)
if int(result['allowance']) == 0:
    print("No allowance set — you need to approve USDC spending first")
    # See: https://docs.polymarket.com 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 on EOA wallets. Proxy wallet users (email/browser wallets) typically don’t need to worry about this.


Balance Methods

get_balance() Method

Returns your USDC balance on Polymarket. This is the simplest way to check how much USDC you have available for trading.

Signature:

client.get_balance() -> str

Parameters: None.

Returns: A string representing your USDC balance in wei (1 USDC = 10^6 wei). You need to convert this to a human-readable amount.

Example:

from py_clob_client.client import ClobClient

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

balance_wei = client.get_balance()
balance_usdc = int(balance_wei) / 1e6
print(f"Balance: {balance_usdc:.2f} USDC")
# Example output: Balance: 1250.00 USDC

Common pitfall: The return value is in wei (micro-USDC), not USDC. Divide by 1e6 (or 10**6) to get the USDC 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 more detailed than 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 USDC, or AssetType.CONDITIONAL for outcome tokens
token_idstrRequired when asset_type is CONDITIONAL — the specific outcome token ID

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

Example — Check USDC balance and allowance:

from py_clob_client.client import ClobClient
from py_clob_client.clob_types import BalanceAllowanceParams, AssetType

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

result = client.get_balance_allowance(
    BalanceAllowanceParams(asset_type=AssetType.COLLATERAL)
)
print(f"Balance: {int(result['balance']) / 1e6:.2f} USDC")
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']}")

When to use get_balance() vs get_balance_allowance():

  • Use get_balance() for a quick USDC balance check (e.g., before placing an order).
  • Use get_balance_allowance() when you need to verify allowances are set (important for EOA wallets) or when checking conditional token balances for specific outcomes.

Position Methods

get_positions() Method

Retrieves your current positions across all markets. Each position represents your holdings of a specific outcome token.

Signature:

client.get_positions() -> list

Parameters: None required. The method fetches all positions for the authenticated user.

Returns: A list of position dictionaries, each containing details about a specific token holding.

Response fields per position:

FieldTypeDescription
assetdictToken details including token_id and condition_id
sizestrNumber of shares held
avgPricestrAverage entry price per share
sidestrSide of the position

Example — List all positions:

from py_clob_client.client import ClobClient

client = ClobClient(
    "https://clob.polymarket.com",
    key="<your-private-key>",
    chain_id=137,
    signature_type=1,  # Magic/email; use 2 for browser/Gnosis Safe (most common)
    funder="<your-proxy-address>"
)
client.set_api_creds(client.create_or_derive_api_creds())

positions = client.get_positions()
for pos in positions:
    token_id = pos["asset"]["token_id"]
    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 have an existing position before placing an order:

def has_position(client, target_token_id):
    """Check if we already hold a position in this outcome."""
    positions = client.get_positions()
    for pos in positions:
        if pos["asset"]["token_id"] == target_token_id:
            return float(pos["size"]) > 0
    return False

# Only buy if we don't already have a position
if not has_position(client, "<token-id>"):
    order = OrderArgs(token_id="<token-id>", price=0.50, size=10.0, side=BUY)
    signed = client.create_order(order)
    client.post_order(signed, OrderType.GTC)

Note: For querying positions via the public Data API (which doesn’t require authentication), you can use:

curl "https://data-api.polymarket.com/positions?user=YOUR_WALLET_ADDRESS"

Or via the Polymarket CLI:

polymarket data positions YOUR_WALLET_ADDRESS

Order Types

MarketOrderArgs

MarketOrderArgs 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.clob_types import MarketOrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY, SELL

Fields:

FieldTypeRequiredDescription
token_idstrYesThe outcome token ID to trade
amountfloatYesDollar amount in USDC to spend (for BUY) or number of shares to sell (for SELL)
sidestrYesBUY or SELL
order_typeOrderTypeYesMust be OrderType.FOK (fill-or-kill) for market orders
fee_rate_bpsintNoCustom fee rate in basis points. Defaults to the standard rate

Example — Buy $25 worth of YES tokens at market price:

from py_clob_client.clob_types import MarketOrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY

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

signed = client.create_market_order(market_order)
response = client.post_order(signed, OrderType.FOK)
print(response)

Example — Sell 10 shares at market price:

from py_clob_client.order_builder.constants import SELL

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

signed = client.create_market_order(sell_order)
response = client.post_order(signed, OrderType.FOK)

Market orders use FOK (fill-or-kill) — the order must fill completely or it’s rejected entirely. If there isn’t enough resting liquidity to fill your full amount, the order fails. For partial fills, use a limit order with FAK (fill-and-kill) instead.

OrderArgs

OrderArgs 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.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY, SELL

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
sidestrYesBUY or SELL
expirationintNoUnix timestamp for order expiration. If omitted, order is GTC

Example — Place a limit buy order:

from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY

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

signed = client.create_order(order)
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), FOK, or FAK order types, while market orders must use FOK.


Order Placement Methods

Placing orders is the core trading workflow. py_clob_client separates order creation (signing) from order submission (posting) to give you maximum control. For simple trades, use create_and_post_order() 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 is a two-step process: first sign the order locally, then post it to the CLOB API.

Signatures:

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

create_order() Parameters:

ParameterTypeDescription
order_argsOrderArgsThe order specification (token, price, size, side)

post_order() Parameters:

ParameterTypeDescription
signed_orderSignedOrderThe signed order from create_order()
order_typeOrderTypeOrderType.GTC, OrderType.FOK, or OrderType.FAK
post_onlyboolIf True, rejects the order if it would immediately match. Use for market-making strategies

Example:

from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY

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

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

Post-only example (for market makers):

signed = client.create_order(order)
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, order_type: OrderType = OrderType.GTC) -> dict

Example:

from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs
from py_clob_client.order_builder.constants import BUY

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

resp = client.create_and_post_order(OrderArgs(
    price=0.50,
    size=100.0,
    side=BUY,
    token_id="<token-id>"
))
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()

Creates and signs a market order for immediate execution.

Signature:

client.create_market_order(order_args: MarketOrderArgs) -> SignedOrder

Example:

from py_clob_client.clob_types import MarketOrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY

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

signed = client.create_market_order(market_order)
response = client.post_order(signed, 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(signed_orders: list[SignedOrder], order_type: OrderType) -> dict

Example:

from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY

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

response = client.post_orders(orders, OrderType.GTC)

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_orders() periodically to check fill status, and cancel stale unfilled orders with cancel() 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_orders()

Retrieves all your open orders, optionally filtered by market.

Signature:

client.get_orders(params: GetOrdersParams = None) -> list

Example:

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

cancel()

Cancels a single order by ID.

Signature:

client.cancel(order_id: str) -> dict

Example:

response = client.cancel(order_id="<order-id>")
print(response)

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

Added in v0.31.0. Significantly refined in v0.34.5 (split into requester/quoter views). RFQ methods enable negotiated pricing for large orders. Instead of placing an order directly on the book, you request a quote from market makers who respond with firm prices.

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 asks for a quote → market makers respond with prices → requester accepts the best quote → the trade executes off-book. Most retail traders and simple bots should use standard limit/market orders.

get_rfq_quote()

Requests a price quote for a specified token and size.

Signature:

client.get_rfq_quote(params: RfqQuoteParams) -> dict

RfqQuoteParams fields:

FieldTypeRequiredDescription
token_idstrYesThe outcome token to get a quote for
sidestrYesBUY or SELL
sizefloatYesNumber of shares to buy or sell

Returns: A dictionary containing quote_id, price, size, expiry (Unix timestamp), and maker (the market maker’s address).

Example — Request a quote for a large position:

from py_clob_client.clob_types import RfqQuoteParams

quote = client.get_rfq_quote(RfqQuoteParams(
    token_id="<token-id>",
    side="BUY",
    size=5000.0
))
print(f"Quote: {quote['size']} shares @ ${quote['price']} (expires {quote['expiry']})")

accept_rfq_quote()

Accepts a previously received quote by its ID, triggering the off-book trade.

Signature:

client.accept_rfq_quote(quote_id: str) -> dict

Example:

response = client.accept_rfq_quote(quote["quote_id"])
print(f"RFQ trade executed: {response}")

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

Note: RFQ endpoint views were split into requester and quoter perspectives in v0.34.5 (Jan 2026). If you’re running an older version, upgrade to get the correct response schema for your role.


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: A dictionary with bids and asks arrays, each containing [price, size] entries sorted by price. The response now also includes enriched market metadata fields (question, slug, end date, outcome labels) that previously required separate Gamma API calls.

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.clob_types import BookParams

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

Bridge Operations

The Polymarket Bridge API now includes a POST /withdraw endpoint for bridging USDC.e to other chains. This endpoint is accessed via the Bridge API (https://bridge.polymarket.com/withdraw), not through py_clob_client directly. 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()get_balance_allowance()Verify USDC balance (divide by 1e6) and that allowance > 0
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()One-step convenience method
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_market_order()post_order(FOK)Use FOK for full fill; consider FAK if liquidity is thin
Check position before tradingget_positions() → check → create_order()Avoid doubling down on existing positions
Cancel everythingcancel_all()Emergency reset; also useful at bot shutdown
Monitor fillsget_order() or get_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

VersionDateKey ChangesMigration Notes
v0.34.6Feb 19, 2026Tick size cache fix — resolves stale tick sizes causing order rejectionsRecommended upgrade for all users. No breaking changes
v0.34.5Jan 13, 2026RFQ endpoint split into requester/quoter views; RFQ params cleanupBreaking for RFQ users: response schema changed — requester and quoter now get different response fields
v0.34.4Jan 6, 2026Orderbook hash resolution fixNo breaking changes
v0.34.3Jan 6, 2026HeartBeats V1 client update; post-only order handling improvementsNo breaking changes. Post-only rejections now return clearer errors
v0.34.1Dec 24, 2025Pagination fix for get_orders() and get_trades()No breaking changes. Fixes missing results on paginated queries
v0.34.0Dec 21, 2025RFQ: invert price for requester order fixBreaking for RFQ users: price field semantics changed for requester-side orders
v0.31.02025RFQ methods, readonly API keys, JSON serialization fixMajor feature release. No breaking changes for existing code

For the full changelog, see py-clob-client releases on GitHub.


Polymarket US Compatibility

py_clob_client 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-clientSeparate 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 April 2026.

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


py-clob-client vs polymarket-apis

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

py-clob-clientpolymarket-apis
MaintainerPolymarket (official)Community (qualiaenjoyer)
Versionv0.34.6v0.5.7
PyPI downloads1.1M/monthLower volume
GitHub stars1,058171
Python version3.9+3.12+
API coverageCLOB onlyCLOB, Gamma, Data, Web3, WebSockets, GraphQL
Type safetyBasic typesPydantic validation
Installpip install py-clob-clientpip install polymarket-apis

Use py-clob-client when:

  • You’re building a trading bot focused on order placement and management
  • You need the widest Python version compatibility (3.9+)
  • You want the official SDK that Polymarket maintains and tests against their API
  • Your project only interacts with the CLOB (order book, orders, positions)

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’re on Python 3.12+ and don’t need backward compatibility
  • You want a single unified client instead of juggling py_clob_client + requests for Gamma + custom WebSocket code

Can you use both? Yes — some projects use polymarket-apis for market discovery and data, then switch to py-clob-client for order execution where they want the official 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.