create_order() and post_order() are the py_clob_client methods that place trades on Polymarket. Order placement is a two-step process: first sign the order locally with your wallet, then submit it to the CLOB API. This page covers limit orders with OrderArgs, market orders with MarketOrderArgs, order types (GTC/FOK/FAK), tick size validation, batch orders, and common errors.

For the complete py_clob_client method reference covering all methods, see the py_clob_client Reference. For Kalshi’s equivalent order placement, see the Prediction Market API Reference.


The Two-Step Order Flow

Every order on Polymarket follows this pattern:

  1. Sign locallycreate_order() or create_market_order() signs the order with your private key, producing a SignedOrder
  2. Post to APIpost_order() submits the signed order to the CLOB for matching
# Step 1: Sign
signed = client.create_order(order_args)

# Step 2: Post
response = client.post_order(signed, OrderType.GTC)

This design means your private key never leaves your machine — the API only receives the cryptographic signature.


Limit Orders with OrderArgs

Signatures

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

OrderArgs Fields

FieldTypeRequiredDescription
token_idstrYesThe outcome token ID (YES or NO token)
pricefloatYesPrice per share in USDC (0.01 to 0.99)
sizefloatYesNumber of shares to buy or sell
sidestrYesBUY or SELL (import from py_clob_client.order_builder.constants)
expirationintNoUnix timestamp for auto-cancellation. Omit for GTC

post_order() Parameters

ParameterTypeDescription
signed_orderSignedOrderThe signed order from create_order()
order_typeOrderTypeGTC, FOK, or FAK (see Order Types)
post_onlyboolIf True, rejects if the order would immediately match

Example — Place a Limit Buy

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

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

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']}")
print(f"Status:   {response.get('status', 'submitted')}")

Example — Place a Limit Sell

from py_clob_client.order_builder.constants import SELL

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

signed = client.create_order(order)
response = client.post_order(signed, OrderType.GTC)

Example — Order with Expiration

import time

order = OrderArgs(
    token_id="<token-id>",
    price=0.40,
    size=50.0,
    side=BUY,
    expiration=int(time.time()) + 3600  # Expires in 1 hour
)

signed = client.create_order(order)
response = client.post_order(signed, OrderType.GTC)

Market Orders with MarketOrderArgs

Market orders execute immediately against resting liquidity at the best available prices.

Signature

client.create_market_order(order_args: MarketOrderArgs) -> SignedOrder

MarketOrderArgs Fields

FieldTypeRequiredDescription
token_idstrYesThe outcome token ID
amountfloatYesFor BUY: USDC to spend. For SELL: number of shares to sell
sidestrYesBUY or SELL
order_typeOrderTypeYesMust be OrderType.FOK (fill-or-kill)
fee_rate_bpsintNoCustom fee rate in basis points

Example — Buy $25 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(f"Order ID: {response['orderID']}")

Example — Sell 50 Shares at Market Price

from py_clob_client.order_builder.constants import SELL

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

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

Key difference: OrderArgs uses price + size (price per share × number of shares). MarketOrderArgs uses amount (total USDC to spend for buys, or shares to sell for sells).


Order Types: GTC, FOK, FAK

TypeConstantBehaviorUse Case
GTCOrderType.GTCRests on the order book until filled or canceledLimit orders — you want a specific price
FOKOrderType.FOKMust fill entirely and immediately, or is rejectedMarket orders — you want instant execution
FAKOrderType.FAKFills what it can immediately, cancels the restPartial fills OK — you want whatever is available now
from py_clob_client.clob_types import OrderType

# Limit order that rests on the book
client.post_order(signed, OrderType.GTC)

# Market order that fills immediately or fails
client.post_order(signed, OrderType.FOK)

# Aggressive limit order — fill what you can, cancel rest
client.post_order(signed, OrderType.FAK)

Post-Only Orders (Market Makers)

Post-only orders are rejected if they would immediately match against resting orders. This guarantees you’re always the maker (providing liquidity), never the taker.

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

signed = client.create_order(order)
response = client.post_order(signed, OrderType.GTC, post_only=True)
# If the best ask is <= 0.49, this order is rejected
# Otherwise, it rests on the book at 0.49

Batch Orders

Place up to 15 orders in a single API call. Essential for market makers updating quotes on both sides.

Signature

client.post_orders(signed_orders: list[SignedOrder], order_type: OrderType) -> dict

Example — Ladder of Buy Orders

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

orders = []
for price in [0.40, 0.42, 0.44, 0.46, 0.48]:
    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)
print(f"Batch submitted: {len(orders)} orders")

Example — Two-Sided Quotes

from py_clob_client.order_builder.constants import BUY, SELL

signed_orders = []

# Buy side
for price in [0.48, 0.47, 0.46]:
    order = OrderArgs(token_id="<token-id>", price=price, size=100.0, side=BUY)
    signed_orders.append(client.create_order(order))

# Sell side
for price in [0.52, 0.53, 0.54]:
    order = OrderArgs(token_id="<token-id>", price=price, size=100.0, side=SELL)
    signed_orders.append(client.create_order(order))

response = client.post_orders(signed_orders, OrderType.GTC)
print(f"Posted {len(signed_orders)} orders (3 bids + 3 asks)")

Tick Size Validation

Every Polymarket market has a tick_size — the minimum price increment. Orders that don’t align to the tick size are rejected.

Tick SizeValid PricesExample
0.010.01, 0.02, …, 0.99Most markets
0.0010.001, 0.002, …, 0.999High-volume markets
def align_price(price, tick_size=0.01):
    """Round a price to the nearest valid tick."""
    return round(round(price / tick_size) * tick_size, 4)

# Example
raw_price = 0.4537
aligned = align_price(raw_price, tick_size=0.01)
print(f"{raw_price}{aligned}")  # 0.4537 → 0.45

aligned_fine = align_price(raw_price, tick_size=0.001)
print(f"{raw_price}{aligned_fine}")  # 0.4537 → 0.454

To get the tick size for a market, query the Gamma API:

import requests

slug = "bitcoin-above-100k"
resp = requests.get(f"https://gamma-api.polymarket.com/markets?slug={slug}")
market = resp.json()[0]
tick_size = float(market.get("minimum_tick_size", "0.01"))

Neg Risk Markets

Some Polymarket markets are flagged as neg_risk (negative risk). In these markets, holding complementary positions reduces your collateral requirement. Your agent should check this flag when calculating margin.

import requests

# Check if a market is neg_risk
resp = requests.get(f"https://gamma-api.polymarket.com/markets?slug={slug}")
market = resp.json()[0]
is_neg_risk = market.get("neg_risk", False)

if is_neg_risk:
    print("Neg-risk market — complementary positions reduce margin")

When using the TypeScript SDK, neg_risk is passed in the options:

const order = await client.createAndPostOrder(
  { tokenID: "TOKEN_ID", price: 0.50, size: 10, side: Side.BUY },
  { tickSize: "0.01", negRisk: true }  // Pass neg_risk flag
);

Complete Workflow: Buy, Monitor, Sell

A full trading cycle combining order placement with position and balance checks:

from py_clob_client.client import ClobClient
from py_clob_client.clob_types import (
    OrderArgs, MarketOrderArgs, OrderType,
    BalanceAllowanceParams, AssetType
)
from py_clob_client.order_builder.constants import BUY, SELL

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

token_id = "<token-id>"

# 1. Check balance
balance = client.get_balance_allowance(
    BalanceAllowanceParams(asset_type=AssetType.COLLATERAL)
)
usdc = int(balance["balance"]) / 1e6
print(f"Available: ${usdc:.2f} USDC")

# 2. Check order book for pricing
book = client.get_order_book(token_id)
best_ask = float(book.asks[0]["price"]) if book.asks else None
print(f"Best ask: ${best_ask}")

# 3. Place a limit buy below the best ask
if best_ask and usdc > 0:
    buy_price = round(best_ask - 0.02, 2)  # 2 cents below ask
    buy_size = min(100, usdc / buy_price)

    order = OrderArgs(
        token_id=token_id,
        price=buy_price,
        size=buy_size,
        side=BUY
    )
    signed = client.create_order(order)
    resp = client.post_order(signed, OrderType.GTC)
    print(f"Buy order placed: {buy_size:.0f} shares @ ${buy_price}")

# 4. Check positions after fill
positions = client.get_positions()
for pos in positions:
    if pos["asset"]["token_id"] == token_id:
        size = float(pos["size"])
        print(f"Position: {size:.2f} shares")

# 5. Place a sell order at target price
sell_price = 0.70
sell_order = OrderArgs(
    token_id=token_id,
    price=sell_price,
    size=size,
    side=SELL
)
signed = client.create_order(sell_order)
resp = client.post_order(signed, OrderType.GTC)
print(f"Sell order placed: {size:.0f} shares @ ${sell_price}")

Common Errors

ErrorCauseFix
INSUFFICIENT_BALANCENot enough USDC for the orderCheck balance with get_balance_allowance() first
INVALID_TICK_SIZEPrice doesn’t match market’s tick sizeCheck and align to tick size (0.01 or 0.001)
ORDER_ALREADY_EXISTSDuplicate order submissionThe SDK generates nonces — ensure you’re calling create_order() fresh each time
MARKET_NOT_TRADABLEMarket is closed or resolvedCheck market status via Gamma API before ordering
INVALID_SIGNATUREAuth signature mismatchRegenerate credentials: client.set_api_creds(client.create_or_derive_api_creds())
FOK order rejectedNot enough liquidity for full fillCheck order book depth or use FAK for partial fills
UNAUTHORIZEDAPI credentials not setCall set_api_creds() before any trading methods
Post-only rejectedOrder would immediately matchYour price crosses the spread — adjust it

CLI Equivalent

Place orders via the Polymarket CLI:

# Limit order
polymarket clob create-order \
  --token TOKEN_ID \
  --side buy \
  --price 0.45 \
  --size 20

# Market order
polymarket clob market-order \
  --token TOKEN_ID \
  --side buy \
  --amount 25

# Cancel an order
polymarket clob cancel ORDER_ID

# Cancel all orders
polymarket clob cancel-all

See Also


{{ partial “marketplace-cta.html” . }}


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.