> ## Documentation Index > Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt > Use this file to discover all available pages before exploring further. # Create Order > Build, sign, and submit orders All orders on Polymarket are expressed as **limit orders**. Market orders are supported by submitting a limit order with a marketable price — your order executes immediately at the best available price on the book. The SDK handles EIP-712 signing and submission for you. If you prefer the REST API directly, see [Authentication](/api-reference/authentication) for constructing the required headers and the [API Reference](/api-reference/introduction) for full endpoint documentation including the raw order object fields and request/response schemas. *** ## Order Types | Type | Behavior | Use Case | | ------- | -------------------------------------------------------------------- | ------------------------------- | | **GTC** | Good-Til-Cancelled — rests on the book until filled or cancelled | Default for limit orders | | **GTD** | Good-Til-Date — active until a specified expiration time | Auto-expire before known events | | **FOK** | Fill-Or-Kill — must fill immediately and entirely, or cancel | All-or-nothing market orders | | **FAK** | Fill-And-Kill — fills what's available immediately, cancels the rest | Partial-fill market orders | * **GTC** and **GTD** are limit order types — they rest on the book at your specified price. * **FOK** and **FAK** are market order types — they execute against resting liquidity immediately. * **BUY**: specify the dollar amount you want to spend * **SELL**: specify the number of shares you want to sell *** ## Limit Orders The simplest way to place a limit order — create, sign, and submit in one call: ```typescript TypeScript theme={null} import { ClobClient, Side, OrderType } from "@polymarket/clob-client"; const response = await client.createAndPostOrder( { tokenID: "TOKEN_ID", price: 0.5, size: 10, side: Side.BUY, }, { tickSize: "0.01", negRisk: false, }, OrderType.GTC, ); console.log("Order ID:", response.orderID); console.log("Status:", response.status); ``` ```python Python theme={null} from py_clob_client.clob_types import OrderArgs, OrderType from py_clob_client.order_builder.constants import BUY response = client.create_and_post_order( OrderArgs( token_id="TOKEN_ID", price=0.50, size=10, side=BUY, ), options={ "tick_size": "0.01", "neg_risk": False, }, order_type=OrderType.GTC ) print("Order ID:", response["orderID"]) print("Status:", response["status"]) ``` ### Two-Step: Sign Then Submit For more control, you can separate signing from submission. This is useful for batch orders or custom submission logic: ```typescript TypeScript theme={null} // Step 1: Create and sign locally const signedOrder = await client.createOrder( { tokenID: "TOKEN_ID", price: 0.5, size: 10, side: Side.BUY, }, { tickSize: "0.01", negRisk: false }, ); // Step 2: Submit to the CLOB const response = await client.postOrder(signedOrder, OrderType.GTC); ``` ```python Python theme={null} # Step 1: Create and sign locally signed_order = client.create_order( OrderArgs( token_id="TOKEN_ID", price=0.50, size=10, side=BUY, ), options={ "tick_size": "0.01", "neg_risk": False, } ) # Step 2: Submit to the CLOB response = client.post_order(signed_order, OrderType.GTC) ``` *** ## GTD Orders (Expiring) GTD orders auto-expire at a specified time. Useful for quoting around known events. ```typescript TypeScript theme={null} // Expire in 1 hour (+ 60s security threshold buffer) const expiration = Math.floor(Date.now() / 1000) + 60 + 3600; const response = await client.createAndPostOrder( { tokenID: "TOKEN_ID", price: 0.5, size: 10, side: Side.BUY, expiration, }, { tickSize: "0.01", negRisk: false }, OrderType.GTD, ); ``` ```python Python theme={null} import time # Expire in 1 hour (+ 60s security threshold buffer) expiration = int(time.time()) + 60 + 3600 response = client.create_and_post_order( OrderArgs( token_id="TOKEN_ID", price=0.50, size=10, side=BUY, expiration=expiration, ), options={ "tick_size": "0.01", "neg_risk": False, }, order_type=OrderType.GTD ) ``` There is a security threshold of one minute on GTD expiration. To set an effective lifetime of N seconds, use `now + 60 + N`. For example, for a 30-second effective lifetime, set the expiration to `now + 60 + 30`. *** ## Market Orders Market orders execute immediately against resting liquidity using FOK or FAK types: ```typescript TypeScript theme={null} import { Side, OrderType } from "@polymarket/clob-client"; // FOK BUY: spend exactly $100 or cancel entirely const buyOrder = await client.createMarketOrder( { tokenID: "TOKEN_ID", side: Side.BUY, amount: 100, // dollar amount price: 0.5, // worst-price limit (slippage protection) }, { tickSize: "0.01", negRisk: false }, ); await client.postOrder(buyOrder, OrderType.FOK); // FOK SELL: sell exactly 200 shares or cancel entirely const sellOrder = await client.createMarketOrder( { tokenID: "TOKEN_ID", side: Side.SELL, amount: 200, // number of shares price: 0.45, // worst-price limit (slippage protection) }, { tickSize: "0.01", negRisk: false }, ); await client.postOrder(sellOrder, OrderType.FOK); ``` ```python Python theme={null} from py_clob_client.order_builder.constants import BUY, SELL from py_clob_client.clob_types import OrderType # FOK BUY: spend exactly $100 or cancel entirely buy_order = client.create_market_order( token_id="TOKEN_ID", side=BUY, amount=100, # dollar amount price=0.50, # worst-price limit (slippage protection) options={"tick_size": "0.01", "neg_risk": False}, ) client.post_order(buy_order, OrderType.FOK) # FOK SELL: sell exactly 200 shares or cancel entirely sell_order = client.create_market_order( token_id="TOKEN_ID", side=SELL, amount=200, # number of shares price=0.45, # worst-price limit (slippage protection) options={"tick_size": "0.01", "neg_risk": False}, ) client.post_order(sell_order, OrderType.FOK) ``` * **FOK** — fill entirely or cancel the whole order * **FAK** — fill what's available, cancel the rest The `price` field on market orders acts as a **worst-price limit** (slippage protection), not a target execution price. ### One-Step Market Order For convenience, `createAndPostMarketOrder` handles creation, signing, and submission in one call: ```typescript TypeScript theme={null} const response = await client.createAndPostMarketOrder( { tokenID: "TOKEN_ID", side: Side.BUY, amount: 100, price: 0.5, }, { tickSize: "0.01", negRisk: false }, OrderType.FOK, ); ``` ```python Python theme={null} response = client.create_and_post_market_order( token_id="TOKEN_ID", side=BUY, amount=100, price=0.50, options={"tick_size": "0.01", "neg_risk": False}, order_type=OrderType.FOK, ) ``` *** ## Post-Only Orders Post-only orders guarantee you're always the maker. If the order would match immediately (cross the spread), it's rejected instead of executed. ```typescript TypeScript theme={null} const response = await client.postOrder(signedOrder, OrderType.GTC, true); ``` ```python Python theme={null} response = client.post_order(signed_order, OrderType.GTC, post_only=True) ``` * Only works with **GTC** and **GTD** order types * Rejected if combined with FOK or FAK *** ## Batch Orders Place up to **15 orders** in a single request: ```typescript TypeScript theme={null} import { OrderType, Side, PostOrdersArgs } from "@polymarket/clob-client"; const orders: PostOrdersArgs[] = [ { order: await client.createOrder( { tokenID: "TOKEN_ID", price: 0.48, side: Side.BUY, size: 500, }, { tickSize: "0.01", negRisk: false }, ), orderType: OrderType.GTC, }, { order: await client.createOrder( { tokenID: "TOKEN_ID", price: 0.52, side: Side.SELL, size: 500, }, { tickSize: "0.01", negRisk: false }, ), orderType: OrderType.GTC, }, ]; const response = await client.postOrders(orders); ``` ```python Python theme={null} from py_clob_client.clob_types import OrderArgs, OrderType, PostOrdersArgs from py_clob_client.order_builder.constants import BUY, SELL response = client.post_orders([ PostOrdersArgs( order=client.create_order(OrderArgs( price=0.48, size=500, side=BUY, token_id="TOKEN_ID", ), options={"tick_size": "0.01", "neg_risk": False}), orderType=OrderType.GTC, ), PostOrdersArgs( order=client.create_order(OrderArgs( price=0.52, size=500, side=SELL, token_id="TOKEN_ID", ), options={"tick_size": "0.01", "neg_risk": False}), orderType=OrderType.GTC, ), ]) ``` *** ## Order Options Every order requires two market-specific options: `tickSize` and `negRisk`. For details on signature types (`0` = EOA, `1` = POLY\_PROXY, `2` = GNOSIS\_SAFE), see [Authentication](/api-reference/authentication#signature-types-and-funder). ### Tick Sizes Your order price must conform to the market's tick size, or the order is rejected. | Tick Size | Precision | Example Prices | | --------- | ---------- | ---------------------- | | `0.1` | 1 decimal | 0.1, 0.2, 0.5 | | `0.01` | 2 decimals | 0.01, 0.50, 0.99 | | `0.001` | 3 decimals | 0.001, 0.500, 0.999 | | `0.0001` | 4 decimals | 0.0001, 0.5000, 0.9999 | ```typescript TypeScript theme={null} const tickSize = await client.getTickSize("TOKEN_ID"); ``` ```python Python theme={null} tick_size = client.get_tick_size("TOKEN_ID") ``` ### Negative Risk Multi-outcome events (3+ outcomes) use the Neg Risk CTF Exchange. Pass `negRisk: true` for these markets. ```typescript TypeScript theme={null} const isNegRisk = await client.getNegRisk("TOKEN_ID"); ``` ```python Python theme={null} is_neg_risk = client.get_neg_risk("TOKEN_ID") ``` Both values are also available on the market object: `minimum_tick_size` and `neg_risk`. *** ## Prerequisites Before placing an order, your funder address must have approved the Exchange contract to spend the relevant tokens: * **BUY orders**: USDC.e allowance >= spending amount * **SELL orders**: conditional token allowance >= selling amount Order size is limited by your available balance minus amounts reserved by existing open orders: $$ \text{maxOrderSize} = \text{balance} - \sum(\text{openOrderSize} - \text{filledAmount}) $$ Orders are continuously monitored for validity — balances, allowances, and onchain cancellations are tracked in real time. Any maker caught intentionally abusing these checks will be blacklisted. ### Advanced Parameters These optional fields can be passed in the `UserOrder` object for fine-grained control: | Parameter | Type | Description | | ------------ | ------ | ----------------------------------------------- | | `feeRateBps` | number | Fee rate in basis points (default: market rate) | | `nonce` | number | Custom nonce for order uniqueness | | `taker` | string | Restrict the order to a specific taker address | ### Sports Markets Sports markets have additional behaviors: * Outstanding limit orders are **automatically cancelled** once the game begins, clearing the entire order book at the official start time * Marketable orders have a **3-second placement delay** before matching * Game start times can shift — monitor your orders closely, as they may not be cleared if the start time changes unexpectedly *** ## Response A successful order placement returns: ```json theme={null} { "success": true, "errorMsg": "", "orderID": "0xabc123...", "takingAmount": "", "makingAmount": "", "status": "live", "transactionsHashes": [], "tradeIDs": [] } ``` ### Statuses | Status | Description | | ----------- | ----------------------------------------------------------- | | `live` | Order resting on the book | | `matched` | Order matched immediately with a resting order | | `delayed` | Marketable order subject to a matching delay | | `unmatched` | Marketable but failed to delay — placement still successful | ### Error Messages | Error | Description | | ---------------------------------- | ----------------------------------------------- | | `INVALID_ORDER_MIN_TICK_SIZE` | Price doesn't conform to the market's tick size | | `INVALID_ORDER_MIN_SIZE` | Order size below the minimum threshold | | `INVALID_ORDER_DUPLICATED` | Identical order already placed | | `INVALID_ORDER_NOT_ENOUGH_BALANCE` | Insufficient balance or allowance | | `INVALID_ORDER_EXPIRATION` | Expiration timestamp is in the past | | `INVALID_POST_ONLY_ORDER_TYPE` | Post-only used with FOK/FAK | | `INVALID_POST_ONLY_ORDER` | Post-only order would cross the book | | `FOK_ORDER_NOT_FILLED_ERROR` | FOK order couldn't be fully filled | | `INVALID_ORDER_ERROR` | System error inserting the order | | `EXECUTION_ERROR` | System error executing the trade | | `ORDER_DELAYED` | Order match delayed due to market conditions | | `DELAYING_ORDER_ERROR` | System error while delaying the order | | `MARKET_NOT_READY` | Market not yet accepting orders | *** ## Heartbeat The heartbeat endpoint maintains session liveness. If a valid heartbeat is not received within **10 seconds** (with a 5-second buffer), **all open orders are cancelled**. ```typescript TypeScript theme={null} let heartbeatId = ""; setInterval(async () => { const resp = await client.postHeartbeat(heartbeatId); heartbeatId = resp.heartbeat_id; }, 5000); ``` ```python Python theme={null} import time heartbeat_id = "" while True: resp = client.post_heartbeat(heartbeat_id) heartbeat_id = resp["heartbeat_id"] time.sleep(5) ``` * Include the most recent `heartbeat_id` in each request. Use an empty string for the first request. * If you send an expired ID, the server responds with `400` and the correct ID. Update and retry. *** ## Next Steps Cancel single, multiple, or all open orders Attribute orders to your builder account for volume credit