b2a29fe51f
- Added new documentation URLs from llms.txt index - Updated TARGET.md with 244 total documentation pages - Scraped new pages for trading, concepts, and API reference sections - Updated changelog and new index pages
534 lines
16 KiB
Markdown
534 lines
16 KiB
Markdown
> ## 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.
|
|
|
|
<Info>
|
|
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.
|
|
</Info>
|
|
|
|
***
|
|
|
|
## 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:
|
|
|
|
<CodeGroup>
|
|
```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"])
|
|
```
|
|
</CodeGroup>
|
|
|
|
### Two-Step: Sign Then Submit
|
|
|
|
For more control, you can separate signing from submission. This is useful for batch orders or custom submission logic:
|
|
|
|
<CodeGroup>
|
|
```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)
|
|
```
|
|
</CodeGroup>
|
|
|
|
***
|
|
|
|
## GTD Orders (Expiring)
|
|
|
|
GTD orders auto-expire at a specified time. Useful for quoting around known events.
|
|
|
|
<CodeGroup>
|
|
```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
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
<Note>
|
|
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`.
|
|
</Note>
|
|
|
|
***
|
|
|
|
## Market Orders
|
|
|
|
Market orders execute immediately against resting liquidity using FOK or FAK types:
|
|
|
|
<CodeGroup>
|
|
```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)
|
|
```
|
|
</CodeGroup>
|
|
|
|
* **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:
|
|
|
|
<CodeGroup>
|
|
```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,
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
***
|
|
|
|
## 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.
|
|
|
|
<CodeGroup>
|
|
```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)
|
|
```
|
|
</CodeGroup>
|
|
|
|
* 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:
|
|
|
|
<CodeGroup>
|
|
```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,
|
|
),
|
|
])
|
|
```
|
|
</CodeGroup>
|
|
|
|
***
|
|
|
|
## 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 |
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript theme={null}
|
|
const tickSize = await client.getTickSize("TOKEN_ID");
|
|
```
|
|
|
|
```python Python theme={null}
|
|
tick_size = client.get_tick_size("TOKEN_ID")
|
|
```
|
|
</CodeGroup>
|
|
|
|
### Negative Risk
|
|
|
|
Multi-outcome events (3+ outcomes) use the Neg Risk CTF Exchange. Pass `negRisk: true` for these markets.
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript theme={null}
|
|
const isNegRisk = await client.getNegRisk("TOKEN_ID");
|
|
```
|
|
|
|
```python Python theme={null}
|
|
is_neg_risk = client.get_neg_risk("TOKEN_ID")
|
|
```
|
|
</CodeGroup>
|
|
|
|
<Tip>
|
|
Both values are also available on the market object: `minimum_tick_size` and
|
|
`neg_risk`.
|
|
</Tip>
|
|
|
|
***
|
|
|
|
## 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})
|
|
$$
|
|
|
|
<Warning>
|
|
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.
|
|
</Warning>
|
|
|
|
### 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**.
|
|
|
|
<CodeGroup>
|
|
```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)
|
|
```
|
|
</CodeGroup>
|
|
|
|
* 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
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Cancel Orders" icon="xmark" href="/trading/orders/cancel">
|
|
Cancel single, multiple, or all open orders
|
|
</Card>
|
|
|
|
<Card title="Order Attribution" icon="tag" href="/trading/orders/attribution">
|
|
Attribute orders to your builder account for volume credit
|
|
</Card>
|
|
</CardGroup>
|