Skip to content
trading-polymarket logo

Polymarket Trading - Complete API Reference

trading-polymarket

Execute trades on Polymarket using py_clob_client - full API access for market data, orders, positions

alsk1992/CloddsBot0installs2.9Kstars

SKILL.md

Full skill instructions

Polymarket Trading - Complete API Reference

Full access to Polymarket's CLOB (Central Limit Order Book) via the official py_clob_client library.

60+ methods documented. This is the complete reference.

Required Environment Variables

PRIVATE_KEY=0x...           # Ethereum private key for signing
POLY_FUNDER_ADDRESS=0x...   # Your wallet address on Polygon
POLY_API_KEY=...            # From Polymarket API
POLY_API_SECRET=...         # Base64 encoded secret
POLY_API_PASSPHRASE=...     # API passphrase

Installation

pip install py-clob-client requests

Authentication Levels

LevelRequirementsCapabilities
L0NoneRead-only: orderbooks, prices, markets
L1Private keyCreate & sign orders (not post)
L2Private key + API credsFull trading: post orders, cancel, query

Signature Types

TypeUse Case
0Standard EOA (MetaMask, hardware wallets)
1Magic/​email wallets (delegated signing)
2Proxy wallets (Gnosis Safe, browser proxy)

ClobClient - Complete API (60+ Methods)

Initialization

from py_clob_client.client import ClobClient
from py_clob_client.clob_types import (
    OrderArgs, MarketOrderArgs, ApiCreds, OrderType,
    BookParams, TradeParams, OpenOrderParams, BalanceAllowanceParams,
    AssetType, OrderScoringParams, OrdersScoringParams, DropNotificationParams
)
from py_clob_client.order_builder.constants import BUY, SELL
from py_clob_client.constants import POLYGON  # 137

# Level 2 Auth (full trading access)
client = ClobClient(
    host="https://clob.polymarket.com",
    key=os.getenv("PRIVATE_KEY"),           # Private key for signing
    chain_id=POLYGON,                        # 137 for mainnet, 80002 for Amoy testnet
    funder=os.getenv("POLY_FUNDER_ADDRESS"), # Wallet address (for proxy wallets)
    signature_type=2                         # 0=EOA, 1=MagicLink, 2=Proxy
)

# Set API credentials for authenticated endpoints
client.set_api_creds(ApiCreds(
    api_key=os.getenv("POLY_API_KEY"),
    api_secret=os.getenv("POLY_API_SECRET"),
    api_passphrase=os.getenv("POLY_API_PASSPHRASE")
))

Health & Configuration

client.get_ok()                    # Check if server is up
client.get_server_time()           # Get server timestamp
client.get_address()               # Your signer's public address
client.get_collateral_address()    # USDC contract address
client.get_conditional_address()   # CTF contract address
client.get_exchange_address()      # Exchange contract (neg_risk=False default)

Market Data - Single Token

# Get prices and spreads
client.get_midpoint(token_id)              # Mid market price
client.get_price(token_id, side="BUY")     # Best price for side
client.get_spread(token_id)                # Current spread
client.get_last_trade_price(token_id)      # Last executed trade price

# Get full orderbook
orderbook = client.get_order_book(token_id)
# Returns: OrderBookSummary with bids, asks, tick_size, neg_risk, timestamp, hash

Market Data - Batch (Multiple Tokens)

params = [
    BookParams(token_id="TOKEN1", side="BUY"),
    BookParams(token_id="TOKEN2", side="SELL")
]

client.get_midpoints(params)           # Multiple midpoints
client.get_prices(params)              # Multiple prices
client.get_spreads(params)             # Multiple spreads
client.get_order_books(params)         # Multiple orderbooks
client.get_last_trades_prices(params)  # Multiple last prices

Market Metadata

client.get_tick_size(token_id)      # Returns: "0.1", "0.01", "0.001", or "0.0001"
client.get_neg_risk(token_id)       # Returns: True/​False (negative risk market)
client.get_fee_rate_bps(token_id)   # Returns: fee rate in basis points (0 or 1000)

Order Types

from py_clob_client.clob_types import OrderType

OrderType.GTC   # Good Till Cancelled - stays open until filled/​cancelled
OrderType.FOK   # Fill Or Kill - fill entirely immediately or cancel
OrderType.GTD   # Good Till Date - expires at timestamp (min 60 seconds)
OrderType.FAK   # Fill And Kill - fill what's possible, cancel rest

When to Use Each Order Type

TypeUse CaseExample
GTCEntries - wait for fillPlace buy at 0.45, wait for dip
FOKExits - need immediate fillMarket sell entire position NOW
GTDTime-limited ordersOffer expires in 5 minutes
FAKPartial fills OKGet as much as possible now

OrderArgs - Limit Orders

OrderArgs(
    token_id: str,           # Token ID (outcome to trade)
    price: float,            # Price 0.01-0.99
    size: float,             # Number of shares
    side: str,               # "BUY" or "SELL" (or use BUY/​SELL constants)
    fee_rate_bps: int = 0,   # Optional: fee rate in bps (0 or check market)
    nonce: int = 0,          # Optional: unique nonce for cancellation
    expiration: int = 0,     # Optional: expiry timestamp (0 = GTC, use timestamp for GTD)
    taker: str = ZERO_ADDRESS  # Optional: specific taker (ZERO_ADDRESS = anyone)
)

MarketOrderArgs - Market Orders

MarketOrderArgs(
    token_id: str,           # Token ID
    amount: float,           # Total USDC amount to spend (BUY) or shares (SELL)
    side: str,               # "BUY" or "SELL"
    price: float = 0,        # Optional: worst acceptable price (slippage protection)
    fee_rate_bps: int = 0,   # Optional: fee rate
    nonce: int = 0,          # Optional: nonce
    taker: str = ZERO_ADDRESS,  # Optional: taker address
    order_type: OrderType = FOK  # Optional: FOK (default) or FAK
)

Complete Order Examples

from py_clob_client.order_builder.constants import BUY, SELL

# 1. LIMIT BUY (GTC) - sits on book until filled
order = client.create_and_post_order(
    OrderArgs(token_id=TOKEN_ID, price=0.45, size=100.0, side=BUY)
)

# 2. LIMIT SELL (GTC)
order = client.create_and_post_order(
    OrderArgs(token_id=TOKEN_ID, price=0.55, size=50.0, side=SELL)
)

# 3. MARKET BUY - spend $100 USDC at current prices (FOK)
signed = client.create_market_order(
    MarketOrderArgs(token_id=TOKEN_ID, amount=100.0, side=BUY)
)
result = client.post_order(signed, orderType=OrderType.FOK)

# 4. MARKET SELL - sell all shares immediately (FOK)
signed = client.create_market_order(
    MarketOrderArgs(token_id=TOKEN_ID, amount=my_shares, side=SELL)
)
result = client.post_order(signed, orderType=OrderType.FOK)

# 5. POST-ONLY MAKER ORDER (avoid taker fees, earn rebates)
signed = client.create_order(
    OrderArgs(token_id=TOKEN_ID, price=0.44, size=100.0, side=BUY)
)
result = client.post_order(signed, orderType=OrderType.GTC, post_only=True)
# If order would cross spread, it gets REJECTED instead of taking

# 6. GOOD TIL DATE (GTD) - expires after timestamp
import time
expiry = int(time.time()) + 300  # 5 minutes from now
signed = client.create_order(
    OrderArgs(token_id=TOKEN_ID, price=0.50, size=100.0, side=BUY, expiration=expiry)
)
result = client.post_order(signed, orderType=OrderType.GTD)

# 7. FILL AND KILL (FAK) - fill what you can, cancel rest
signed = client.create_market_order(
    MarketOrderArgs(token_id=TOKEN_ID, amount=1000.0, side=BUY)
)
result = client.post_order(signed, orderType=OrderType.FAK)

Order Operations

Create and Post Orders

# SIMPLE: Create and post in one call (recommended)
result = client.create_and_post_order(
    OrderArgs(
        token_id="123456789012345678901234567890",
        price=0.45,
        size=10.0,
        side="BUY"
    )
)
# Returns: {"orderID": "...", "status": "...", ...}

# ADVANCED: Separate create and post
order = client.create_order(OrderArgs(...))  # Returns SignedOrder
result = client.post_order(order, orderType=OrderType.GTC, post_only=False)

# Market order (calculates price automatically)
result = client.create_market_order(
    MarketOrderArgs(
        token_id="...",
        amount=100.0,    # Spend $100 USDC
        side="BUY"
    )
)

# Calculate expected fill price before market order
price = client.calculate_market_price(
    token_id="...",
    side="BUY",
    amount=100.0,
    order_type=OrderType.FOK
)

Cancel Orders

client.cancel(order_id="ORDER_ID")           # Cancel specific order
client.cancel_orders(["ID1", "ID2", "ID3"])  # Cancel multiple
client.cancel_all()                          # Cancel ALL open orders
client.cancel_market_orders(                 # Cancel by market/​asset
    market="CONDITION_ID",
    asset_id="TOKEN_ID"
)

Query Orders

# Get all open orders
orders = client.get_orders(
    params=OpenOrderParams(
        id="ORDER_ID",      # Optional: specific order
        market="COND_ID",   # Optional: filter by market
        asset_id="TOKEN"    # Optional: filter by token
    ),
    next_cursor="MA=="      # For pagination
)

# Get specific order
order = client.get_order(order_id="ORDER_ID")

Trade History

trades = client.get_trades(
    params=TradeParams(
        id="TRADE_ID",           # Optional: specific trade
        maker_address="0x...",   # Optional: filter by maker
        market="CONDITION_ID",   # Optional: filter by market
        asset_id="TOKEN_ID",     # Optional: filter by token
        before="2024-01-01",     # Optional: before date
        after="2023-01-01"       # Optional: after date
    ),
    next_cursor="MA=="
)

Balance & Allowance

# Check balance and allowances
balance = client.get_balance_allowance(
    params=BalanceAllowanceParams(
        asset_type=AssetType.COLLATERAL,  # USDC balance
        # or AssetType.CONDITIONAL         # Token balance
        token_id="TOKEN_ID"                # For conditional tokens
    )
)

# Update/​refresh allowance cache
client.update_balance_allowance(params=...)

Market Discovery

Get Markets from CLOB

# All active markets
markets = client.get_markets(next_cursor="MA==")
simplified = client.get_simplified_markets()

# Specific market
market = client.get_market(condition_id="CONDITION_ID")

# Market trade events
events = client.get_market_trades_events(condition_id="CONDITION_ID")

# Sampling/​featured markets
client.get_sampling_markets()
client.get_sampling_simplified_markets()

Get Markets from Gamma API (More Details)

import requests

def search_markets(query: str, limit: int = 10):
    """Search Polymarket markets by keyword"""
    url = "https://gamma-api.polymarket.com/​markets"
    params = {
        "_q": query,
        "active": "true",
        "closed": "false",
        "_limit": limit
    }
    r = requests.get(url, params=params)
    return r.json()

# Get market details
markets = search_markets("bitcoin")
for m in markets:
    print(f"Question: {m['question']}")
    print(f"Condition ID: {m['condition_id']}")
    print(f"Volume: ${m.get('volume', 0):,.2f}")
    for token in m.get('tokens', []):
        print(f"  {token['outcome']}: {token['token_id']}")
        print(f"    Price: {float(token['price']):.2f}")

On-Chain Operations

Check Token Balance (Position Size)

import requests

CTF_CONTRACT = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"
RPC_URL = "https://polygon-rpc.com/"

def get_token_balance(wallet: str, token_id: str) -> float:
    """Get balance of a specific outcome token in shares"""
    token_int = int(token_id)
    # ERC-1155 balanceOf(address,uint256)
    data = f"0x00fdd58e000000000000000000000000{wallet[2:].lower()}{token_int:064x}"

    r = requests.post(RPC_URL, json={
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [{"to": CTF_CONTRACT, "data": data}, "latest"],
        "id": 1
    })

    result = r.json().get("result", "0x0")
    balance = int(result, 16) / 1e6  # Convert from raw to shares
    return balance

# Usage
balance = get_token_balance(
    wallet="0x7c2211103e7Fbb257Ac6fa59f972cfd8bc9D4795",
    token_id="12345678901234567890"
)
print(f"Position: {balance} shares")

Check USDC Balance

USDC_CONTRACT = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"

def get_usdc_balance(wallet: str) -> float:
    """Get USDC balance on Polygon"""
    # ERC-20 balanceOf(address)
    data = f"0x70a08231000000000000000000000000{wallet[2:].lower()}"

    r = requests.post(RPC_URL, json={
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [{"to": USDC_CONTRACT, "data": data}, "latest"],
        "id": 1
    })

    result = r.json().get("result", "0x0")
    return int(result, 16) / 1e6  # USDC has 6 decimals

API Key Management

# Create new API key
creds = client.create_api_key(nonce=0)

# Derive existing API key (if you lost creds but have private key)
creds = client.derive_api_key(nonce=0)

# Create or derive (tries both)
creds = client.create_or_derive_api_creds(nonce=0)

# Get all your API keys
keys = client.get_api_keys()

# Delete current API key
client.delete_api_key()

# Readonly API keys (for monitoring only)
readonly = client.create_readonly_api_key()
client.get_readonly_api_keys()
client.delete_readonly_api_key(key="...")
client.validate_readonly_api_key(address="0x...", key="...")

Advanced Features

Order Heartbeat (Keep Orders Alive)

# Start heartbeat - if not sent within 10s, all orders cancelled
heartbeat_id = client.post_heartbeat(heartbeat_id=None)

# Continue sending heartbeats
while trading:
    client.post_heartbeat(heartbeat_id=heartbeat_id)
    time.sleep(5)

Order Scoring

# Check if order is scoring (earning rewards)
is_scoring = client.is_order_scoring(
    params=OrderScoringParams(order_id="...")
)

# Check multiple orders
scores = client.are_orders_scoring(
    params=OrdersScoringParams(order_ids=["ID1", "ID2"])
)

Notifications

notifications = client.get_notifications()
client.drop_notifications(params=DropNotificationParams(...))

Fee Structure

IMPORTANT: Most Polymarket markets have ZERO fees (0% maker, 0% taker).

15-min Crypto Markets (Exception)

Only 15-minute BTC/​ETH/​SOL/​XRP price prediction markets have fees:

fee = shares × 0.25 × (price × (1 - price))²
Entry PriceFee % (per side)
0.50~1.56%
0.60 or 0.40~1.44%
0.70 or 0.30~1.10%
0.80 or 0.20~0.64%
0.90 or 0.10~0.20%

TAKER = crosses spread = PAYS fee MAKER = adds liquidity = NO fee + earns rebates

To be a maker: Post orders that don't immediately fill (inside the spread).


Decimal Precision Rules

Order SidePrice DecimalsSize Decimals
BUY24
SELL22

Min order size: $1 per side


Complete Trading Example

#!/​usr/​bin/​env python3
"""
Production-ready Polymarket trading script
"""

import os
import time
import requests
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, ApiCreds, OrderType

# Initialize
client = ClobClient(
    "https://clob.polymarket.com",
    key=os.getenv("PRIVATE_KEY"),
    chain_id=137,
    funder=os.getenv("POLY_FUNDER_ADDRESS"),
    signature_type=2
)
client.set_api_creds(ApiCreds(
    api_key=os.getenv("POLY_API_KEY"),
    api_secret=os.getenv("POLY_API_SECRET"),
    api_passphrase=os.getenv("POLY_API_PASSPHRASE")
))

TOKEN_ID = "YOUR_TOKEN_ID"
WALLET = os.getenv("POLY_FUNDER_ADDRESS")
CTF = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"

def get_balance(token_id):
    """Get position size"""
    token_int = int(token_id)
    data = f"0x00fdd58e000000000000000000000000{WALLET[2:].lower()}{token_int:064x}"
    r = requests.post("https://polygon-rpc.com/", json={
        "jsonrpc": "2.0", "method": "eth_call",
        "params": [{"to": CTF, "data": data}, "latest"], "id": 1
    })
    return int(r.json().get("result", "0x0"), 16) / 1e6

def get_orderbook(token_id):
    """Get current bid/​ask"""
    book = client.get_order_book(token_id)
    return {
        "best_bid": float(book.bids[0].price) if book.bids else 0,
        "best_ask": float(book.asks[0].price) if book.asks else 1
    }

# Check position
position = get_balance(TOKEN_ID)
print(f"Current position: {position} shares")

# Get market
book = get_orderbook(TOKEN_ID)
print(f"Bid: {book['best_bid']:.2f}, Ask: {book['best_ask']:.2f}")

# Place a buy order (maker - inside spread)
buy_price = book['best_bid'] + 0.01  # 1 cent above bid
if buy_price < book['best_ask']:  # Ensure we're maker
    result = client.create_and_post_order(OrderArgs(
        token_id=TOKEN_ID,
        price=buy_price,
        size=10.0,
        side="BUY"
    ))
    print(f"Buy order placed: {result}")

# Place a sell order (market sell via FOK)
if position > 0:
    result = client.create_and_post_order(OrderArgs(
        token_id=TOKEN_ID,
        price=0.01,  # Lowest price = immediate fill
        size=position,
        side="SELL"
    ))
    print(f"Sold position: {result}")

Error Handling

from py_clob_client.exceptions import PolyApiException

try:
    result = client.create_and_post_order(OrderArgs(...))
except PolyApiException as e:
    print(f"API Error: {e}")
except Exception as e:
    print(f"Error: {e}")

Common errors:

  • "insufficient balance" - Not enough USDC/​tokens
  • "invalid price" - Price outside 0.01-0.99 or wrong decimals
  • "order too small" - Below minimum order size
  • "market closed" - Market not accepting orders

CLI Commands (/​poly)

Access Polymarket trading directly from Claude Code:

Market Data

/​poly search <query>                     # Search markets
/​poly market <condition-id>              # Market details
/​poly book <token-id>                    # View orderbook

Trading

/​poly buy <token-id> <size> <price>      # Buy shares (limit)
/​poly sell <token-id> <size> <price>     # Sell shares (limit)
/​poly orders                             # Open orders
/​poly cancel <order-id>                  # Cancel order
/​poly cancel all                         # Cancel all orders
/​poly trades [limit]                     # Recent trade history
/​poly balance                            # USDC + positions

Advanced Orders

/​poly twap <buy|sell> <token> <total> <price> [slices] [interval-sec]
/​poly bracket <token> <size> <tp> <sl>   # TP + SL bracket
/​poly trigger buy <token> <size> <price> # Buy when price drops

Note: TWAP and bracket orders are persisted to the database and will automatically resume after restarts.

Auto-Redeem (Resolved Positions)

/​poly redeem                           # One-time redeem all resolved positions
/​poly redeem start                     # Start auto-polling (default: every 60s)
/​poly redeem stop                      # Stop auto-polling
/​poly redeem status                    # Check auto-redeemer status
/​poly redeem pending                   # List positions pending redemption
/​poly redeem <conditionId> <tokenId>   # Redeem specific position

Env vars:

  • POLY_REDEEM_INTERVAL_MS - Polling interval in ms (default: 60000 = 1 minute)

Real-Time Fills (WebSocket)

/​poly fills                              # Connect fills WebSocket
/​poly fills status                       # Show connection + recent fills
/​poly fills stop                         # Disconnect fills WebSocket
/​poly fills clear                        # Clear tracked fills

Order Heartbeat

/​poly heartbeat                          # Start heartbeat (keeps orders alive)
/​poly heartbeat status                   # Check heartbeat status
/​poly heartbeat stop                     # Stop heartbeat (orders cancelled in 10s)

Account & Settlements

/​poly settlements                        # View pending settlements from resolved markets
/​poly allowance                          # Check USDC approval status
/​poly orderbooks <token1> [token2] ...   # Batch fetch orderbooks

Complete ClobClient Method Reference

Health & Config (L0 - No Auth)

MethodParametersReturnsDescription
get_ok()-dictHealth check
get_server_time()-dictServer timestamp
get_address()-strYour signer address
get_collateral_address()-strUSDC contract
get_conditional_address()-strCTF contract
get_exchange_address(neg_risk)boolstrExchange contract

Market Data (L0 - No Auth)

MethodParametersReturnsDescription
get_midpoint(token_id)strdictMid price
get_midpoints(params)list[BookParams]dictMultiple mid prices
get_price(token_id, side)str, strdictBest price for side
get_prices(params)list[BookParams]dictMultiple prices
get_spread(token_id)strdictBid-ask spread
get_spreads(params)list[BookParams]dictMultiple spreads
get_order_book(token_id)strOrderBookSummaryFull orderbook
get_order_books(params)list[BookParams]listMultiple orderbooks
get_last_trade_price(token_id)strdictLast trade
get_last_trades_prices(params)list[BookParams]dictMultiple last trades
get_tick_size(token_id)strTickSize"0.1"/"0.01"/"0.001"/"0.0001"
get_neg_risk(token_id)strboolIs neg_risk market
get_fee_rate_bps(token_id)strintFee in basis points

Market Discovery (L0 - No Auth)

MethodParametersReturnsDescription
get_markets(next_cursor)strdictPaginated markets
get_simplified_markets(next_cursor)strdictSimplified markets
get_sampling_markets(next_cursor)strdictFeatured markets
get_market(condition_id)strdictSingle market
get_market_trades_events(condition_id)strdictTrade events

Order Creation (L1 - Needs Private Key)

MethodParametersReturnsDescription
create_order(order_args, options)OrderArgs, CreateOrderOptionsdictSign limit order
create_market_order(order_args, options)MarketOrderArgs, CreateOrderOptionsdictSign market order
calculate_market_price(token_id, side, amount, order_type)str, str, float, OrderTypefloatExpected fill price

Order Posting (L2 - Needs API Creds)

MethodParametersReturnsDescription
post_order(order, orderType, post_only)SignedOrder, OrderType, booldictPost single order
post_orders(args)list[PostOrdersArgs]dictPost batch orders
create_and_post_order(order_args, options)OrderArgs, PartialCreateOrderOptionsdictCreate + post (recommended)

Order Cancellation (L2 - Needs API Creds)

MethodParametersReturnsDescription
cancel(order_id)strdictCancel one order
cancel_orders(order_ids)list[str]dictCancel multiple
cancel_all()-dictCancel ALL orders
cancel_market_orders(market, asset_id)str, strdictCancel by market

Order Queries (L2 - Needs API Creds)

MethodParametersReturnsDescription
get_orders(params, next_cursor)OpenOrderParams, strlistGet open orders
get_order(order_id)strdictGet specific order
get_trades(params, next_cursor)TradeParams, strlistTrade history

API Key Management (L2 - Needs API Creds)

MethodParametersReturnsDescription
create_api_key(nonce)intApiCredsCreate new key
derive_api_key(nonce)intApiCredsDerive existing key
create_or_derive_api_creds(nonce)intApiCredsCreate or derive
set_api_creds(creds)ApiCreds-Set credentials
get_api_keys()-dictList your keys
delete_api_key()-dictDelete current key
create_readonly_api_key()-ReadonlyApiKeyResponseReadonly key
get_readonly_api_keys()-list[str]List readonly keys
delete_readonly_api_key(key)strboolDelete readonly key

Balance & Allowance (L2 - Needs API Creds)

MethodParametersReturnsDescription
get_balance_allowance(params)BalanceAllowanceParamsdictCheck balance
update_balance_allowance(params)BalanceAllowanceParamsdictRefresh allowance

Advanced Features (L2 - Needs API Creds)

MethodParametersReturnsDescription
post_heartbeat(heartbeat_id)strdictKeep orders alive (10s timeout)
is_order_scoring(params)OrderScoringParamsdictCheck if earning rewards
are_orders_scoring(params)OrdersScoringParamsdictCheck multiple orders
get_notifications()-dictGet notifications
drop_notifications(params)DropNotificationParamsdictDelete notifications
get_closed_only_mode()-dictCheck closed-only status

Contract Addresses (Polygon Mainnet)

USDC = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"           # Collateral token
CTF  = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"           # Conditional tokens (ERC-1155)
EXCHANGE = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E"       # Regular exchange
NEG_RISK = "0xC5d563A36AE78145C45a50134d48A1215220f80a"       # Neg risk exchange (crypto)

Quick Reference: Common Patterns

Check Position → Sell All

balance = get_token_balance(wallet, token_id)
if balance > 0:
    client.create_and_post_order(OrderArgs(
        token_id=token_id, price=0.01, size=balance, side="SELL"
    ))

Maker Entry (No Fees)

book = client.get_order_book(token_id)
best_bid = float(book.bids[0].price) if book.bids else 0
maker_price = best_bid + 0.01  # 1 cent above bid
signed = client.create_order(OrderArgs(token_id=token_id, price=maker_price, size=100, side="BUY"))
client.post_order(signed, orderType=OrderType.GTC, post_only=True)

Market Buy $50 Worth

signed = client.create_market_order(MarketOrderArgs(token_id=token_id, amount=50.0, side="BUY"))
client.post_order(signed, orderType=OrderType.FOK)

Cancel Everything

client.cancel_all()

WebSocket Channels (Real-Time Updates)

Polymarket provides WebSocket channels for real-time updates. No RPC needed - everything goes through CLOB.

WebSocket URLs

MARKET_WS = "wss://ws-subscriptions-clob.polymarket.com/​ws/​market"
USER_WS = "wss://ws-subscriptions-clob.polymarket.com/​ws/​user"

Market Channel (Public - No Auth)

Subscribe to orderbook updates, price changes, trades for any market.

import websocket
import json

def on_message(ws, message):
    data = json.loads(message)
    event_type = data.get("event_type")

    if event_type == "book":
        # Full orderbook snapshot (on subscribe + after trades)
        print(f"Book update: {data['bids']}, {data['asks']}")

    elif event_type == "price_change":
        # Order placed/​cancelled affecting price level
        print(f"Price change: {data}")

    elif event_type == "last_trade_price":
        # Trade executed
        print(f"Trade: {data['price']} x {data['size']}")

    elif event_type == "tick_size_change":
        # Tick size changed (price went extreme)
        print(f"Tick size: {data['old_tick_size']} -> {data['new_tick_size']}")

def on_open(ws):
    # Subscribe to specific token
    ws.send(json.dumps({
        "type": "subscribe",
        "channel": "market",
        "assets_ids": [TOKEN_ID]  # List of token IDs
    }))

ws = websocket.WebSocketApp(
    "wss://ws-subscriptions-clob.polymarket.com/​ws/​market",
    on_message=on_message,
    on_open=on_open
)
ws.run_forever()

User Channel (Authenticated - For Fills)

Subscribe to YOUR order updates, fills, trades. This is how you get fill notifications.

import websocket
import json
import hmac
import hashlib
import time
import base64

API_KEY = os.getenv("POLY_API_KEY")
API_SECRET = os.getenv("POLY_API_SECRET")
API_PASSPHRASE = os.getenv("POLY_API_PASSPHRASE")

def get_auth_headers():
    """Generate HMAC auth for WebSocket"""
    timestamp = str(int(time.time()))
    message = f"GET\n{timestamp}\n/​ws/​user"
    signature = hmac.new(
        base64.b64decode(API_SECRET),
        message.encode(),
        hashlib.sha256
    ).digest()
    return {
        "POLY-ADDRESS": WALLET_ADDRESS,
        "POLY-SIGNATURE": base64.b64encode(signature).decode(),
        "POLY-TIMESTAMP": timestamp,
        "POLY-API-KEY": API_KEY,
        "POLY-PASSPHRASE": API_PASSPHRASE
    }

def on_message(ws, message):
    data = json.loads(message)
    event_type = data.get("event_type")

    if event_type == "trade":
        # YOUR FILL - order matched!
        status = data.get("status")  # MATCHED, MINED, CONFIRMED, FAILED
        print(f"FILL: {data['side']} {data['size']} @ {data['price']}")
        print(f"  Status: {status}")
        print(f"  Trade ID: {data['id']}")
        print(f"  Market: {data['market']}")

        if status == "CONFIRMED":
            print("  ✓ Trade confirmed on-chain!")
        elif status == "FAILED":
            print("  ✗ Trade failed - check logs")

    elif event_type == "order":
        order_type = data.get("type")  # PLACEMENT, UPDATE, CANCELLATION
        print(f"ORDER {order_type}: {data['side']} {data['original_size']} @ {data['price']}")
        print(f"  Filled: {data.get('size_matched', 0)}")

        if order_type == "CANCELLATION":
            print("  Order cancelled")

def on_open(ws):
    # Subscribe with auth
    ws.send(json.dumps({
        "type": "subscribe",
        "channel": "user",
        "auth": get_auth_headers(),
        # Optional: filter to specific market
        # "markets": [CONDITION_ID]
    }))

ws = websocket.WebSocketApp(
    "wss://ws-subscriptions-clob.polymarket.com/​ws/​user",
    on_message=on_message,
    on_open=on_open
)
ws.run_forever()

Message Types Summary

Market Channel:

EventTriggerKey Fields
bookSubscribe, trades affect bookbids, asks, timestamp
price_changeOrder placed/​cancelledprice, size, side
last_trade_priceTrade executedprice, size, side
tick_size_changePrice extreme (>0.96 or <0.04)old_tick_size, new_tick_size

User Channel:

EventTriggerKey Fields
tradeYour order filledstatus, side, size, price, market
orderOrder placed/​updated/​cancelledtype (PLACEMENT/​UPDATE/​CANCELLATION), size_matched

Trade Status Flow

MATCHED → MINED → CONFIRMED (success)
                → RETRYING → CONFIRMED/​FAILED

Keepalive

Send PING every 10 seconds to keep connection alive:

import threading

def send_ping():
    while True:
        ws.send(json.dumps({"type": "ping"}))
        time.sleep(10)

threading.Thread(target=send_ping, daemon=True).start()

Real-Time Data Client (Alternative)

Polymarket also provides @polymarket/​real-time-data-client for TypeScript:

import { RealTimeDataClient } from "@polymarket/​real-time-data-client";

const client = new RealTimeDataClient({
    onMessage: (msg) => console.log(msg),
    onConnect: (c) => {
        // Subscribe to user fills with auth
        c.subscribe({
            subscriptions: [{
                topic: "clob_user",
                type: "*",
                clob_auth: {
                    key: API_KEY,
                    secret: API_SECRET,
                    passphrase: API_PASSPHRASE
                }
            }]
        });
    }
});

client.connect();

No RPC Needed - CLOB Handles Everything

OperationMethod
Get positionsGET /​data/​positions?user={address} via Gamma API
Get balanceclient.get_balance_allowance()
Place ordersclient.create_and_post_order()
Get fillsUser WebSocket channel
Get pricesclient.get_order_book() or Market WebSocket
Cancel ordersclient.cancel()

The only time you might use RPC is to check on-chain token balances independently, but even that's available via Gamma API positions endpoint.

More skills from alsk1992

portfolio logo
alsk1992/CloddsBot

portfolio

Track your positions and P&L across prediction markets and futures exchanges

2.9K 0
View
predictfun logo
alsk1992/CloddsBot

predictfun

Predict.fun prediction market trading (BNB Chain)

2.9K 0
View
ledger logo
alsk1992/CloddsBot

ledger

Trade decision audit trail and statistics

2.9K 0
View
permissions logo
alsk1992/CloddsBot

permissions

Command approvals, tool policies, and exec security

2.9K 0
View
news logo
alsk1992/CloddsBot

news

Monitor news and correlate with prediction market movements

2.9K 0
View
whale-tracking logo
alsk1992/CloddsBot

whale-tracking

Monitor whale trades on Polymarket and crypto chains (Solana, ETH, Polygon, ARB, Base, OP)

2.9K 0
View
raydium logo
alsk1992/CloddsBot

raydium

Raydium - swaps, CLMM positions, AMM liquidity on Solana

2.9K 0
View
history logo
alsk1992/CloddsBot

history

Trade history tracking, sync, and performance analytics

2.9K 0
View
kamino logo
alsk1992/CloddsBot

kamino

Kamino Finance — Solana lending, borrowing, and liquidity vaults

2.9K 0
View
qrcoin logo
alsk1992/CloddsBot

qrcoin

Participate in QR Coin auctions on Base - bid to display URLs on QR codes

2.9K 0
View
endaoment logo
alsk1992/CloddsBot

endaoment

Donate to 501(c)(3) charities onchain via Endaoment - tax-deductible crypto donations

2.9K 0
View
trading-futures logo
alsk1992/CloddsBot

trading-futures

Trade perpetual futures on Binance, Bybit, Hyperliquid, MEXC with up to 200x leverage

2.9K 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View