Update Polymarket documentation (2026-02-19)
- 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
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,41 +2,532 @@
|
||||
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
|
||||
> Use this file to discover all available pages before exploring further.
|
||||
|
||||
# Making Your First Trade
|
||||
# Create Order
|
||||
|
||||
> How to buy shares.
|
||||
> Build, sign, and submit orders
|
||||
|
||||
Once you've [signed up](../get-started/how-to-signup) and [deposited funds](../get-started/how-to-deposit), you're ready to start trading on Polymarket. Here's a step-by-step guide to get you started.
|
||||
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.
|
||||
|
||||
## Video guide
|
||||
<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>
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/1lFgkHLqo28?si=i7e61-roRsOVeRMW" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen />
|
||||
***
|
||||
|
||||
## Walkthrough
|
||||
## Order Types
|
||||
|
||||
Before trading, you'll have to visit the [markets page](https://polymarket.com/markets) to see all available markets. Use the search, sort, and filter tools to narrow down your options and find a market that interests you.
|
||||
screen shot.
|
||||
| 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 |
|
||||
|
||||
<Steps>
|
||||
<Steps.Step>
|
||||
### Choose a Market
|
||||
* **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
|
||||
|
||||
Locate the 'buy' modal, on the right side of the screen. Click the outcome you want to buy (usually Yes or No), then enter the dollar amount you wish to invest.
|
||||
</Steps.Step>
|
||||
***
|
||||
|
||||
<Steps.Step>
|
||||
### Buy Shares
|
||||
## Limit Orders
|
||||
|
||||
Click **Buy** and confirm the transaction in your wallet. Once your trade goes through, you'll receive a notification confirming its success.
|
||||
The simplest way to place a limit order — create, sign, and submit in one call:
|
||||
|
||||
<Tip>Congrats, you're officially a Polymarket trader!</Tip>
|
||||
</Steps.Step>
|
||||
<CodeGroup>
|
||||
```typescript TypeScript theme={null}
|
||||
import { ClobClient, Side, OrderType } from "@polymarket/clob-client";
|
||||
|
||||
<Steps.Step>
|
||||
### Share your trade
|
||||
const response = await client.createAndPostOrder(
|
||||
{
|
||||
tokenID: "TOKEN_ID",
|
||||
price: 0.5,
|
||||
size: 10,
|
||||
side: Side.BUY,
|
||||
},
|
||||
{
|
||||
tickSize: "0.01",
|
||||
negRisk: false,
|
||||
},
|
||||
OrderType.GTC,
|
||||
);
|
||||
|
||||
You'll also see a bet slip to share on social media. We love sending \$\$\$ to traders who post their trades on Twitter and tag us!
|
||||
</Steps.Step>
|
||||
</Steps>
|
||||
console.log("Order ID:", response.orderID);
|
||||
console.log("Status:", response.status);
|
||||
```
|
||||
|
||||
Simple, right? If you think you've got the hang of it, it's time to learn about more advanced trading and order types. [Limit Orders](../trading/limit-orders/).
|
||||
```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>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user