py_clob_client Examples 2026 | Every Function with Working Code
Complete code examples for every function in py_clob_client - the official Python client for Polymarket's CLOB API. With 2+ monthly searches for py_clob_client get_positions and growing interest in building Polymarket trading bots, this comprehensive reference provides copy-paste ready Python code for every method, from market data retrieval to order placement and position management.
This guide covers all py-clob-client v0.29.0 functions with real-world examples, error handling patterns, and best practices. Whether you're building a simple portfolio tracker or a sophisticated market making bot, this reference has everything you need.
๐ Quick Reference
- โข Installation:
pip install py-clob-client - โข Version: v0.29.0 (December 2025) with HTTP2 support
- โข Documentation: github.com/polymarket/py-clob-client
- โข Full Tutorial: See our complete Python tutorial
Installation and Setup
Install py-clob-client
# Install from PyPI (recommended)
pip install py-clob-client
# Pin web3 version to avoid conflicts
pip install web3==6.14.0
# Optional: Better async support
pip install aiopolymarket
# Optional: Retry logic
pip install tenacityโ ๏ธ Version Compatibility
Pin web3==6.14.0 to avoid dependency conflicts with eth-typing. The latest py-clob-client (v0.29.0) includes HTTP2 and Keep Alive support for better performance.
Initialize Client
Three initialization patterns depending on your needs:
1. Read-Only Access (No Authentication)
from py_clob_client.client import ClobClient
# Level 0 - public data only, no authentication required
client = ClobClient("https://clob.polymarket.com")
# Test connection
ok = client.get_ok()
server_time = client.get_server_time()
print(f"Connected: {ok}, Server Time: {server_time}")2. Standard EOA Wallet (MetaMask Export)
import os
from py_clob_client.client import ClobClient
from dotenv import load_dotenv
load_dotenv('keys.env')
client = ClobClient(
"https://clob.polymarket.com",
key=os.getenv("PK"), # Private key without 0x prefix
chain_id=137, # Polygon Mainnet
signature_type=1
)
# Generate API credentials (one-time)
api_creds = client.create_or_derive_api_creds()
client.set_api_creds(api_creds)
# Now you can place orders
print("Client initialized and authenticated")3. Magic/Browser Wallet (Funder Address Required)
client = ClobClient(
"https://clob.polymarket.com",
key=os.getenv("PK"),
chain_id=137,
signature_type=1,
funder=os.getenv("FUNDER_ADDRESS") # Required for Magic wallets
)
api_creds = client.create_or_derive_api_creds()
client.set_api_creds(api_creds)๐ก Track Profitable Wallets Using py_clob_client
While py_clob_client is powerful for building your own bots, tracking which wallets are actually profitable requires monitoring multiple addresses simultaneously. PolyTrack Pro detects API usage patterns (including py_clob_client signatures) and tracks unlimited wallets with 10-second refresh rates. See which bot strategies generate consistent returns before investing months building your own system.
Learn from what works, not just what compiles. Try PolyTrack Pro free for 3 days - no credit card required.
Market Data Functions
get_markets() - Fetch All Markets
Retrieve paginated list of all markets from Polymarket. Returns market metadata including questions, condition IDs, token IDs, and current prices.
Basic Usage
# Get first page of markets (default: 20 results)
response = client.get_markets()
markets = response.get('data', [])
print(f"Found {len(markets)} markets")
for market in markets[:5]:
print(f" - {market.get('question')}")
print(f" Condition ID: {market.get('condition_id')}")
print(f" Active: {market.get('active')}")Pagination Example
# Fetch all markets with pagination
all_markets = []
next_cursor = None
while True:
if next_cursor:
response = client.get_markets(next_cursor=next_cursor)
else:
response = client.get_markets()
markets = response.get('data', [])
all_markets.extend(markets)
next_cursor = response.get('next_cursor')
if not next_cursor:
break
print(f"Fetched {len(all_markets)} markets...")
print(f"Total markets: {len(all_markets)}")Response Schema
{
"data": [
{
"condition_id": "0x1234...",
"question": "Will Bitcoin hit $100k?",
"slug": "bitcoin-100k-2025",
"active": true,
"closed": false,
"tokens": [
{"token_id": "0xabcd...", "outcome": "Yes"},
{"token_id": "0xef01...", "outcome": "No"}
],
"volume": "125000.50",
"liquidity": "50000.00"
}
],
"next_cursor": "eyJpZCI6IjEyMyJ9" # Pagination token
}get_midpoint(token_id) - Get Midpoint Price
Returns the midpoint between the best bid and ask prices for a token. Useful for determining fair market value.
token_id = "0xabcd..." # Token ID for YES outcome
# Get midpoint price
midpoint = client.get_midpoint(token_id)
print(f"Midpoint price: $"+f"{midpoint}")
# Calculate probability
probability = float(midpoint) * 100
print(f"Implied probability: {probability:.1f}%")๐ก Midpoint Calculation
Midpoint = (best_bid + best_ask) / 2. This represents the fair market price between buyers and sellers. For market makers, placing orders around the midpoint is key to capturing the spread.
get_price(token_id, side) - Get Best Bid or Ask
Get the best available bid (BUY side) or ask (SELL side) price for a token. Essential for determining entry/exit prices.
token_id = "0xabcd..."
# Get best bid (highest buy order)
best_bid = client.get_price(token_id, side="BUY")
print(f"Best bid: $"+f"{best_bid}")
# Get best ask (lowest sell order)
best_ask = client.get_price(token_id, side="SELL")
print(f"Best ask: $"+f"{best_ask}")
# Calculate spread
spread = float(best_ask) - float(best_bid)
spread_pct = (spread / float(best_ask)) * 100
print(f"Spread: {'$'}{spread:.4f} ({spread_pct:.2f}%)")
# Use in trading strategy
if spread_pct > 0.02: # 2% spread
print("Good market making opportunity")get_order_book(token_id) - Get Full Order Book
Retrieve the complete order book with all bid and ask orders, sorted by price. Essential for market making strategies and understanding liquidity depth.
token_id = "0xabcd..."
# Get full order book
orderbook = client.get_order_book(token_id)
# Access bids (buy orders, sorted highest to lowest)
bids = orderbook.get('bids', [])
print(f"Top 5 bids:")
for bid in bids[:5]:
price = bid['price']
size = bid['size']
print(f" $"+f"{price} x {size} shares")
# Access asks (sell orders, sorted lowest to highest)
asks = orderbook.get('asks', [])
print(f"\nTop 5 asks:")
for ask in asks[:5]:
price = ask['price']
size = ask['size']
print(f" $"+f"{price} x {size} shares")
# Calculate total liquidity
total_bid_volume = sum(float(b['size']) * float(b['price']) for b in bids)
total_ask_volume = sum(float(a['size']) * float(a['price']) for a in asks)
print(f"\nTotal bid volume: $"+f"{total_bid_volume:.2f}")
print(f"Total ask volume: $"+f"{total_ask_volume:.2f}")get_order_books(token_ids) - Get Multiple Order Books
Fetch order books for multiple tokens in a single request. More efficient than multiple individual calls.
from py_clob_client.clob_types import BookParams
# Get order books for multiple tokens
token_ids = ["0xabcd...", "0xef01...", "0x1234..."]
books_params = [BookParams(token_id=tid) for tid in token_ids]
orderbooks = client.get_order_books(books_params)
# Process each order book
for i, book in enumerate(orderbooks):
token_id = token_ids[i]
best_bid = book['bids'][0]['price'] if book['bids'] else None
best_ask = book['asks'][0]['price'] if book['asks'] else None
print(f"Token {token_id}: Bid $"+f"{best_bid} / Ask $"+f"{best_ask}")get_last_trade_price(token_id) - Get Last Trade Price
Returns the price of the most recent trade for a token. Useful for tracking price movements and validating current prices.
token_id = "0xabcd..."
last_price = client.get_last_trade_price(token_id)
print(f"Last trade price: $"+f"{last_price}")
# Compare with current midpoint
current_mid = client.get_midpoint(token_id)
price_change = float(current_mid) - float(last_price)
change_pct = (price_change / float(last_price)) * 100
print(f"Current midpoint: $"+f"{current_mid}")
print(f"Change: $"+f"{price_change:.4f} ({change_pct:.2f}%)")See What Whales Are Trading Right Now
Get instant alerts when top traders make moves. Track P&L, win rates, and copy winning strategies.

Free forever. No credit card required.
Position Functions
๐ก Pro Tip: Track Multiple Wallets at Once
get_positions() only shows your own wallet. To track whale positions and learn from profitable traders, PolyTrack Pro lets you track unlimited wallets with real-time alerts. Free tier limits you to 3 wallets with 30s refresh.
get_positions() - Get All Open Positions
๐ High Search Volume Query
py_clob_client get_positions has 2+ monthly searches (0% CTR, position 12). This is the exact function people are looking for:
Retrieve all your open positions across all markets. Returns position details including token ID, shares, average cost, and unrealized P&L. Requires authentication. Want to track whale positions instead? See the Pro tip above.
Basic Usage
# Get all positions
positions = client.get_positions()
print(f"Open positions: {len(positions)}")
for pos in positions:
token_id = pos.get('token_id')
shares = pos.get('shares', 0)
avg_price = pos.get('avg_price', 0)
unrealized_pnl = pos.get('unrealized_pnl', 0)
print(f"\nToken: {token_id}")
print(f" Shares: {shares}")
print(f" Avg Price: $"+f"{avg_price}")
print(f" Unrealized P&L: $"+f"{unrealized_pnl:.2f}")Calculate Total Portfolio Value
positions = client.get_positions()
total_value = 0
total_cost = 0
total_pnl = 0
for pos in positions:
shares = float(pos.get('shares', 0))
avg_price = float(pos.get('avg_price', 0))
current_price = float(pos.get('current_price', 0))
pnl = float(pos.get('unrealized_pnl', 0))
cost_basis = shares * avg_price
current_value = shares * current_price
total_cost += cost_basis
total_value += current_value
total_pnl += pnl
print(f"Total Cost Basis: $"+f"{total_cost:.2f}")
print(f"Total Current Value: $"+f"{total_value:.2f}")
print(f"Total Unrealized P&L: $"+f"{total_pnl:.2f}")
print(f"Return: {(total_pnl / total_cost) * 100:.2f}%")Response Schema
[
{
"token_id": "0xabcd...",
"shares": "100.50",
"avg_price": "0.45",
"current_price": "0.52",
"unrealized_pnl": "7.04",
"cost_basis": "45.23",
"current_value": "52.26"
}
]get_fills() - Get Trade History
Retrieve your complete trade history (filled orders). Useful for analyzing performance, calculating realized P&L, and building trading analytics.
# Get recent fills
fills = client.get_fills()
print(f"Total fills: {len(fills)}")
for fill in fills[:10]: # Show last 10
print(f"\nFill ID: {fill.get('id')}")
print(f" Side: {fill.get('side')}")
print(f" Size: {fill.get('size')} shares")
print(f" Price: $"+f"{fill.get('price')}")
print(f" Status: {fill.get('status')}")
print(f" Timestamp: {fill.get('timestamp')}")
# Calculate realized P&L
total_pnl = 0
for fill in fills:
if fill.get('status') == 'FILLED':
side = fill.get('side')
size = float(fill.get('size', 0))
price = float(fill.get('price', 0))
if side == 'SELL':
total_pnl += size * price # Profit on sale
elif side == 'BUY':
total_pnl -= size * price # Cost of purchase
print(f"\nRealized P&L: $"+f"{total_pnl:.2f}")Order Management Functions
create_order(OrderArgs) - Create Limit Order
Create a signed limit order with specified price and size. Limit orders stay on the orderbook until filled or cancelled (GTC) or expire at a specific time (GTD). Limit orders are maker orders with 0% fees.
Buy Order Example
from py_clob_client.clob_types import OrderArgs, OrderType
from py_clob_client.order_builder.constants import BUY, SELL
token_id = "0xabcd..." # YES token ID
# Create limit buy order: Buy 100 shares at $0.45
order_args = OrderArgs(
token_id=token_id,
price=0.45, # Price per share (0.01 - 0.99)
size=100.0, # Number of shares
side=BUY # BUY or SELL
)
# Sign the order
signed_order = client.create_order(order_args)
# Submit as Good Till Cancelled (stays on orderbook)
response = client.post_order(signed_order, OrderType.GTC)
print(f"Order placed: {response.get('id')}")
print(f"Status: {response.get('status')}")Sell Order Example
# Create limit sell order: Sell 50 shares at $0.55
sell_order = OrderArgs(
token_id=token_id,
price=0.55,
size=50.0,
side=SELL
)
signed_order = client.create_order(sell_order)
response = client.post_order(signed_order, OrderType.GTC)
print(f"Sell order placed: {response.get('id')}")๐ฐ Fee Strategy
Limit orders (GTC/GTD) are maker orders with 0% fees. Market orders (FOK) are taker orders with ~0.3% fees. Always use limit orders when possible to minimize costs. On $10,000 volume, that's $30 saved per trade.
create_market_order(MarketOrderArgs) - Create Market Order
Create a market order that executes immediately at the best available price. Market orders specify a dollar amount rather than share quantity. These are taker orders with ~0.3% fees.
๐ Common Search: MarketOrderArgs
People search: "marketorderargs" "py_clob_client" (1+ impression). MarketOrderArgs is used for market orders (dollar amounts), while OrderArgs is for limit orders (price + shares).
from py_clob_client.clob_types import MarketOrderArgs
token_id = "0xabcd..."
# Buy $25 worth of shares at market price
market_order = MarketOrderArgs(
token_id=token_id,
amount=25.0, # Dollar amount (not shares)
side=BUY, # BUY or SELL
order_type=OrderType.FOK # Fill-or-Kill
)
# Sign and submit
signed_order = client.create_market_order(market_order)
response = client.post_order(signed_order, OrderType.FOK)
print(f"Market order executed: {response.get('id')}")
print(f"Filled: {response.get('filled_size')} shares")
print(f"Avg price: $"+f"{response.get('avg_fill_price')}")Order Types Explained
| Order Type | Full Name | Behavior | Fees |
|---|---|---|---|
GTC | Good Till Cancelled | Stays on orderbook until filled or cancelled | 0% (maker) |
GTD | Good Till Date | Expires at specified timestamp | 0% (maker) |
FOK | Fill or Kill | Must fill entirely immediately or cancel | ~0.3% (taker) |
IOC | Immediate or Cancel | Fill what you can immediately, cancel rest | ~0.3% (taker) |
get_orders(OpenOrderParams) - Get Open Orders
Retrieve all your open (unfilled) orders. Useful for monitoring pending orders, checking status, and managing order lifecycle.
from py_clob_client.clob_types import OpenOrderParams
# Get all open orders
params = OpenOrderParams()
open_orders = client.get_orders(params)
print(f"Open orders: {len(open_orders)}")
for order in open_orders:
print(f"\nOrder ID: {order.get('id')}")
print(f" Side: {order.get('side')}")
print(f" Size: {order.get('original_size')} shares")
print(f" Price: $"+f"{order.get('price')}")
print(f" Filled: {order.get('filled_size', 0)} / {order.get('original_size')}")
print(f" Status: {order.get('status')}")
# Filter by token
token_id = "0xabcd..."
token_orders = [o for o in open_orders if o.get('token_id') == token_id]
print(f"\nOpen orders for token {token_id}: {len(token_orders)}")cancel(order_id) - Cancel Specific Order
Cancel a single order by order ID. Useful for canceling specific orders without affecting others.
order_id = "YOUR_ORDER_ID"
try:
client.cancel(order_id)
print(f"Order {order_id} cancelled successfully")
except Exception as e:
print(f"Cancel failed: {e}")
# Get order ID from open orders first
open_orders = client.get_orders(OpenOrderParams())
if open_orders:
first_order_id = open_orders[0].get('id')
client.cancel(first_order_id)cancel_all() - Cancel All Open Orders
Cancel all your open orders at once. Essential for market makers who need to update orders frequently or exit all positions quickly.
# Cancel all open orders
try:
client.cancel_all()
print("All orders cancelled successfully")
except Exception as e:
print(f"Cancel all failed: {e}")
# Verify cancellation
open_orders = client.get_orders(OpenOrderParams())
print(f"Remaining open orders: {len(open_orders)}")MarketOrderArgs vs OrderArgs
Understanding the difference between OrderArgs (limit orders) and MarketOrderArgs (market orders) is crucial:
| Feature | OrderArgs (Limit) | MarketOrderArgs (Market) |
|---|---|---|
| Price control | โ You set price | โ Best available price |
| Size specified | Number of shares | Dollar amount |
| Execution | May not fill immediately | Fills immediately |
| Fees | 0% (maker) | ~0.3% (taker) |
| Use case | Price control, lower fees | Immediate execution |
Complete Trading Example
Here's a complete example that demonstrates multiple functions working together. Remember: While building bots is educational, profitable strategies are rare. PolyTrack Pro users can track unlimited wallets running similar bots to see which strategies actually work before investing time and capital.
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, OrderType, OpenOrderParams
from py_clob_client.order_builder.constants import BUY, SELL
import os
# Initialize client
client = ClobClient(
"https://clob.polymarket.com",
key=os.getenv("PK"),
chain_id=137
)
client.set_api_creds(client.create_or_derive_api_creds())
# 1. Get market data
token_id = "0xabcd..." # Your token ID
current_price = client.get_midpoint(token_id)
best_bid = client.get_price(token_id, side="BUY")
best_ask = client.get_price(token_id, side="SELL")
print(f"Current price: $"+f"{current_price}")
print(f"Best bid: $"+f"{best_bid} / Best ask: $"+f"{best_ask}")
# 2. Check existing positions
positions = client.get_positions()
my_position = next((p for p in positions if p['token_id'] == token_id), None)
if my_position:
print(f"\nExisting position: {my_position['shares']} shares @ $"+f"{my_position['avg_price']}")
# 3. Place limit buy order below current price
buy_price = round(float(current_price) - 0.02, 2) # 2 cents below
buy_order = OrderArgs(
token_id=token_id,
price=buy_price,
size=100.0,
side=BUY
)
signed_buy = client.create_order(buy_order)
buy_response = client.post_order(signed_buy, OrderType.GTC)
print(f"\nBuy order placed: {buy_response.get('id')}")
# 4. Monitor order status
open_orders = client.get_orders(OpenOrderParams())
my_orders = [o for o in open_orders if o.get('token_id') == token_id]
print(f"\nOpen orders for token: {len(my_orders)}")
# 5. Cancel if price moves away
import time
time.sleep(5) # Wait 5 seconds
new_price = client.get_midpoint(token_id)
if abs(float(new_price) - buy_price) > 0.05: # Price moved 5 cents
client.cancel(buy_response.get('id'))
print("Order cancelled - price moved too far")
# 6. Check fills
fills = client.get_fills()
recent_fills = [f for f in fills if f.get('token_id') == token_id]
print(f"\nRecent fills: {len(recent_fills)}")Error Handling and Best Practices
py-clob-client Exponential Backoff
๐ High Search Volume: Exponential Backoff
py-clob-client exponential backoff has 4+ monthly searches (0% CTR, position 6). Essential for handling rate limits:
See our complete exponential backoff guide for detailed implementation.
Common Errors and Solutions
Insufficient Balance
Error: "Insufficient balance" or "insufficient funds"
Solution: Check your USDC balance before placing orders. Use client.get_balances() if available, or check via wallet.
Rate Limit (429)
Error: HTTP 429 - Too Many Requests
Solution: Implement exponential backoff. See our exponential backoff guide.
Invalid Token ID
Error: "Invalid token_id" or 404
Solution: Verify token ID from Gamma API market data. Token IDs are hex strings starting with 0x.
Safe Order Placement Pattern
import time
from tenacity import retry, wait_exponential, stop_after_attempt
def safe_place_order(client, order_args, order_type=OrderType.GTC, max_retries=3):
"""Place order with error handling and retry logic."""
for attempt in range(max_retries):
try:
# Sign order
signed_order = client.create_order(order_args)
# Submit order
response = client.post_order(signed_order, order_type)
return response
except Exception as e:
error_str = str(e)
# Rate limit - exponential backoff
if "429" in error_str or "rate limit" in error_str.lower():
wait_time = 2 ** attempt
print(f"Rate limited. Waiting {wait_time}s...")
time.sleep(wait_time)
continue
# Insufficient funds - don't retry
if "insufficient" in error_str.lower():
print("Insufficient funds")
return None
# Other errors - retry once
print(f"Order failed: {e}")
if attempt < max_retries - 1:
time.sleep(1)
else:
return None
return None
# Usage
order = OrderArgs(
token_id="0xabcd...",
price=0.45,
size=100.0,
side=BUY
)
result = safe_place_order(client, order)
if result:
print(f"Order placed: {result.get('id')}")
else:
print("Order failed after retries")Additional Helper Functions
get_ok() - Check API Health
# Check if API is operational
is_ok = client.get_ok()
print(f"API status: {is_ok}") # True if onlineget_server_time() - Get Server Timestamp
# Get server time for clock synchronization
server_time = client.get_server_time()
print(f"Server time: {server_time}")
# Useful for timing-sensitive operations
from datetime import datetime
server_dt = datetime.fromtimestamp(int(server_time) / 1000)
print(f"Server datetime: {server_dt}")Performance Tips
- Use get_order_books() for multiple tokens instead of multiple get_order_book() calls
- Cache market data locally for 30-60 seconds since prices don't change instantly
- Batch operations where possible (e.g., cancel_all vs multiple cancel calls)
- Implement connection pooling when making many requests
- Use limit orders (GTC) to avoid taker fees - saves ~0.3% per trade
Next Steps
Now that you understand all py-clob-client functions, here are recommended next steps:
- Read our complete Python tutorial for step-by-step bot building
- Learn about exponential backoff for rate limit handling
- Explore arbitrage strategies using these functions
- Build a trading bot with real examples
- Study GitHub repos to see these functions in production
๐ Identify Profitable py_clob_client Strategies Used by Elite Traders
Building bots is one thingโdiscovering which strategies consistently generate alpha is another. PolyTrack Pro analyzes millions of trades across thousands of wallets to reveal:
- Which wallets use py_clob_client - detect API patterns and bot behavior
- Real P&L data - see which code examples actually generate profits
- Order pattern analysis - identify market makers, arbitrage bots, and spike detectors
- Unlimited tracking - follow hundreds of bot wallets (free tier: only 3)
- Real-time alerts - get notified when profitable bots make trades
- CSV export & API - download data to analyze strategies yourself
Stop building bots that don't generate returns. Join professional trading teams who use PolyTrack Pro to identify and replicate proven strategies before investing development time and capital. Start your free 3-day trial - no credit card required.
Frequently Asked Questions
Use client.get_positions() to retrieve all your open positions. Returns position details including token ID, shares, average cost, and unrealized P&L. Requires authentication. See our complete code examples in the guide.
Related Articles
Stop Guessing. Start Following Smart Money.
Get instant alerts when whales make $10K+ trades. Track P&L, win rates, and copy winning strategies.