Orders API
The Orders API provides order entry and management capabilities for trading on markets.
Authentication RequiredAll Orders API endpoints require Ed25519 signature authentication. See the Authentication guide for details on signing requests.
Base URL
https://api.polymarket.us
Endpoints
Order Entry
| Method | Endpoint | Description |
|---|
POST | /v1/orders | Create a new order |
POST | /v1/order/preview | Preview order before submission |
POST | /v1/order/close-position | Close an existing position |
Order Query
| Method | Endpoint | Description |
|---|
GET | /v1/orders/open | Get all open orders |
GET | /v1/order/{orderId} | Get a specific order by ID |
Order Management
| Method | Endpoint | Description |
|---|
POST | /v1/order/{orderId}/modify | Modify an existing order |
POST | /v1/order/{orderId}/cancel | Cancel a specific order |
POST | /v1/orders/open/cancel | Cancel all open orders |
Order Types
All enum values are passed as strings in the request body:
| Value | Description |
|---|
ORDER_TYPE_LIMIT | Limit order at specified price |
ORDER_TYPE_MARKET | Market order executed at best available price |
Example:
{
"type": "ORDER_TYPE_LIMIT"
}
Order Intent
Orders require an intent indicating position direction. Pass these as string values:
| Value | Description |
|---|
ORDER_INTENT_BUY_LONG | Buy YES shares (go long on Yes outcome) |
ORDER_INTENT_SELL_LONG | Sell YES shares (close long Yes position) |
ORDER_INTENT_BUY_SHORT | Buy NO shares (go long on No outcome) |
ORDER_INTENT_SELL_SHORT | Sell NO shares (close long No position) |
Example - Buy NO shares:
{
"marketSlug": "your-market-slug",
"type": "ORDER_TYPE_LIMIT",
"price": { "value": "0.45", "currency": "USD" },
"quantity": 10,
"tif": "TIME_IN_FORCE_GOOD_TILL_CANCEL",
"intent": "ORDER_INTENT_BUY_SHORT"
}
Understanding Price with Order Intent
Only the long side (YES) is directly tradable. The short side (NO) is synthetic exposure created through positions in the long side. The price.value field always represents the long side’s price, regardless of which order intent you use. In the market slug, the first team is always the long/YES side and the second team is the short/NO side. A common mistake is attempting to buy both YES at 0.60 and NO at 0.40, which causes a self-match error. Since YES and NO prices must sum to $1.00, buying NO at 0.40 is equivalent to buying YES at 0.60 - you’re placing two buy orders at the same price level on the same instrument. If you want exposure to both sides, use different price levels (e.g., buy YES at 0.55 and buy NO at 0.50).
Example: For market aec-cbb-usc-iowa-2026-01-28:
- YES (long side) = USC
- NO (short side) = Iowa
price.value always refers to USC’s price
How This Affects Your Orders:
| You Want To | Order Intent | price.value |
|---|
| Buy USC at 0.83 | ORDER_INTENT_BUY_LONG | 0.83 |
| Sell USC at 0.83 | ORDER_INTENT_SELL_LONG | 0.83 |
| Buy Iowa at 0.83 | ORDER_INTENT_BUY_SHORT | 0.17 |
| Sell Iowa at 0.83 | ORDER_INTENT_SELL_SHORT | 0.17 |
In binary markets, YES and NO are inverses: buying NO at 0.83 is equivalent to buying YES at 0.17 (1.00 - 0.83). Since price.value always represents the YES side, you must set it to 0.17 when trading Iowa (NO) at 0.83. To trade the NO side at any price X, set price.value = 1.00 - X.
Price Validation
Orders must have price.value between 0.01 and 0.99 (the exchange’s absolute price limits).
Invalid prices (below 0.01 or above 0.99) are restricted at the exchange level. Since the order is sent to the exchange, you will still receive an orderID, but the order will never fill because it gets rejected during validation.
Example:
{
"price": {"value": "45", "currency": "USD"} // Invalid - will receive orderID but order rejected
}
Always validate price bounds client-side before submission to avoid unnecessary orderIDs for rejected orders.
Tick Size by Product Type
Not all products share the same minimum price increment (tick size). Moneyline contracts (e.g., AEC, ATC) use a tick size of 0.01 (1 cent), while futures contracts such as Title Event Contracts (TEC) are decimalized and support finer price increments. Each instrument includes an orderPriceMinTickSize field — always check it before submitting orders, as prices that don’t align with the tick size will be rejected with ORD_REJECT_REASON_INVALID_PRICE_INCREMENT.
Order Side
The order side indicates buy or sell direction:
| Value | Description |
|---|
ORDER_SIDE_BUY | Buy order |
ORDER_SIDE_SELL | Sell order |
Order States
Orders progress through these states:
PENDING_NEW → PARTIALLY_FILLED → FILLED
↓
CANCELED / REJECTED / EXPIRED
| Value | Description |
|---|
ORDER_STATE_PENDING_NEW | Order received, not yet processed by matching engine |
ORDER_STATE_PENDING_REPLACE | Modify request received, not yet processed |
ORDER_STATE_PENDING_CANCEL | Cancel request received, not yet processed |
ORDER_STATE_PENDING_RISK | Order pending risk approval |
ORDER_STATE_PARTIALLY_FILLED | Order partially executed |
ORDER_STATE_FILLED | Order fully executed |
ORDER_STATE_CANCELED | Order canceled |
ORDER_STATE_REPLACED | Order replaced via modify |
ORDER_STATE_REJECTED | Order rejected by exchange |
ORDER_STATE_EXPIRED | Order expired (GTD orders) |
Time in Force
| Value | Description |
|---|
TIME_IN_FORCE_GOOD_TILL_CANCEL | GTC - Remains active until filled or canceled |
TIME_IN_FORCE_GOOD_TILL_DATE | GTD - Expires at specified goodTillTime |
TIME_IN_FORCE_IMMEDIATE_OR_CANCEL | IOC - Fills immediately available quantity, cancels rest |
TIME_IN_FORCE_FILL_OR_KILL | FOK - Must fill entirely or cancel completely |
Manual Order Indicator
Required to indicate whether the order is placed by a human or automated system:
| Value | Description |
|---|
MANUAL_ORDER_INDICATOR_MANUAL | Order placed manually by a user |
MANUAL_ORDER_INDICATOR_AUTOMATIC | Order placed by an automated trading system |
Execution Types
Execution events returned in synchronous order responses:
| Value | Description |
|---|
EXECUTION_TYPE_PARTIAL_FILL | Order partially filled |
EXECUTION_TYPE_FILL | Order fully filled |
EXECUTION_TYPE_CANCELED | Order canceled |
EXECUTION_TYPE_REPLACE | Order replaced/modified |
EXECUTION_TYPE_REJECTED | Order rejected |
EXECUTION_TYPE_EXPIRED | Order expired |
EXECUTION_TYPE_DONE_FOR_DAY | Order done for the trading day |
Order Reject Reasons
If an order is rejected, the reason will be one of:
| Value | Description |
|---|
ORD_REJECT_REASON_UNKNOWN_MARKET | Unknown or invalid market |
ORD_REJECT_REASON_EXCHANGE_CLOSED | Exchange/market is closed |
ORD_REJECT_REASON_INCORRECT_QUANTITY | Invalid quantity |
ORD_REJECT_REASON_INVALID_PRICE_INCREMENT | Price not on valid increment |
ORD_REJECT_REASON_INCORRECT_ORDER_TYPE | Invalid order type for market |
ORD_REJECT_REASON_PRICE_OUT_OF_BOUNDS | Price outside valid range |
ORD_REJECT_REASON_NO_LIQUIDITY | No liquidity for market order |
Slippage Tolerance
For market orders or close position orders, you can specify slippage tolerance:
{
"slippageTolerance": {
"currentPrice": { "value": "0.50", "currency": "USD" },
"ticks": 5
}
}
| Field | Type | Description |
|---|
currentPrice | Amount | Reference price for slippage calculation |
bips | integer | Slippage tolerance in basis points (1 bip = 0.01%) |
ticks | integer | Slippage tolerance in price ticks (takes priority over bips) |
Default Values
slippageTolerance is optional and defaults to:
- Market orders: Unlimited (no slippage protection by default)
- Limit orders: Not applicable (price is fixed)
Slippage tolerance defines the maximum price movement you’ll accept. For example, if you submit a market order to buy at current price 0.50 with ticks: 5, the order will reject if the best ask moves above 0.55 before execution.
Real-Time Order UpdatesAfter submitting orders via REST, use the WebSocket Private Stream to receive real-time updates on order status, fills, and cancellations.
Complete Create Order Example
{
"marketSlug": "super-bowl-lix-chiefs-vs-eagles",
"type": "ORDER_TYPE_LIMIT",
"price": {
"value": "0.55",
"currency": "USD"
},
"quantity": 100,
"tif": "TIME_IN_FORCE_GOOD_TILL_CANCEL",
"intent": "ORDER_INTENT_BUY_LONG",
"manualOrderIndicator": "MANUAL_ORDER_INDICATOR_MANUAL",
"participateDontInitiate": false
}
Rate Limits
The API enforces the following rate limits to ensure system stability:
Global Limit
- 2,000 requests per 10 seconds across all endpoints
Per-Endpoint Limits
| Endpoint | Method | Rate Limit |
|---|
/v1/orders (place order) | POST | 400 requests per 10 seconds |
/v1/orders/{uuid}/cancel | POST | 400 requests per 10 seconds |
/v1/orders/{uuid}/modify | POST | 400 requests per 10 seconds |
/v1/orders/close-position | POST | 200 requests per 10 seconds |
/v1/orders/open | GET | 50 requests per 10 seconds |
/v1/orders/* (query orders) | GET | 50 requests per 10 seconds |
Rate Limit ExceededWhen rate limits are exceeded, the API returns HTTP status 429 Too Many Requests. Both global and per-endpoint limits apply concurrently - the more restrictive limit takes precedence.
Notes:
- Rate limits are enforced at the edge (Cloudflare) before requests reach the API
- Limits are applied per IP address
- Implement exponential backoff and request throttling in your application
Best Practices
- Use string enum values - All enums are passed as strings (e.g.,
"ORDER_TYPE_LIMIT", not 1)
- Use WebSocket for updates - Subscribe to order updates instead of polling
- Preview before submit - Use the preview endpoint for order validation
- Handle rejects - Implement proper error handling for rejected orders
- Use asynchronous execution for limit orders - For market-making and resting limit orders, avoid
synchronousExecution: true as it waits up to 10 seconds for final order state. Instead, submit orders asynchronously (the default) and poll with GET /v1/order/{orderId} to check status (~100ms). Only use synchronousExecution: true for immediately-fillable orders where you need to wait for fill confirmation.
- Specify manual order indicator - Required for regulatory compliance
- Respect rate limits - Implement request throttling to stay within rate limits and avoid 429 errors