Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.polymarket.us/llms.txt

Use this file to discover all available pages before exploring further.

Orders API

The Orders API provides order entry and management capabilities for trading on markets.
Authentication RequiredAll Orders API endpoints require API key authentication. See the Authentication guide for details on signing requests.

Base URL

https://api.polymarket.us

Endpoints

Order Entry

MethodEndpointDescription
POST/v1/ordersCreate a new order
POST/v1/order/previewPreview order before submission
POST/v1/order/close-positionClose an existing position

Order Query

MethodEndpointDescription
GET/v1/orders/openGet all open orders
GET/v1/order/{orderId}Get a specific order by ID

Order Management

MethodEndpointDescription
POST/v1/order/{orderId}/modifyModify an existing order
POST/v1/order/{orderId}/cancelCancel a specific order
POST/v1/orders/open/cancelCancel all open orders

Batched Operations

Up to 20 orders per call.
MethodEndpointDescription
POST/v1/orders/batchedCreate up to 20 orders in a single request
POST/v1/orders/batched/cancelCancel up to 20 specific orders by ID
POST/v1/orders/batched/modifyModify up to 20 existing orders (each forwarded to the exchange as a cancel-replace)
Note: /v1/orders/open/cancel cancels all of your open orders (optionally filtered by market). Use /v1/orders/batched/cancel when you want to cancel a specific list of order IDs.
Batched responses do not confirm per-entry success.
  • Gateway validation is atomic: if any entry fails request-shape checks (missing orderId, batch > 20, etc.), the whole batch is rejected with 400.
  • The exchange processes entries independently. An unknown orderId in a batched cancel or modify is silently ignored.
  • canceledOrderIds and modifiedOrderIds echo the request; they do not certify that each ID was acted on. For real outcomes, subscribe to the Private WebSocket order stream and watch for EXECUTION_TYPE_REPLACE, EXECUTION_TYPE_CANCELED, and EXECUTION_TYPE_REJECTED.
  • createdOrderIds from /v1/orders/batched are real exchange-assigned IDs, but per-order accept/fill/reject events still come via the order stream.

Order Types

All enum values are passed as strings in the request body:
ValueDescription
ORDER_TYPE_LIMITLimit order at specified price
ORDER_TYPE_MARKETMarket 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:
ValueDescription
ORDER_INTENT_BUY_LONGBuy YES shares (go long on Yes outcome)
ORDER_INTENT_SELL_LONGSell YES shares (close long Yes position)
ORDER_INTENT_BUY_SHORTBuy NO shares (go long on No outcome)
ORDER_INTENT_SELL_SHORTSell 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"
}

Alternative: Outcome Side + Action

Instead of intent, you can specify the equivalent outcomeSide + action pair. Both forms are accepted on CreateOrder and the batched variants. If both are sent, outcomeSide+action wins.
outcomeSideactionEquivalent intent
OUTCOME_SIDE_YESORDER_ACTION_BUYORDER_INTENT_BUY_LONG
OUTCOME_SIDE_YESORDER_ACTION_SELLORDER_INTENT_SELL_LONG
OUTCOME_SIDE_NOORDER_ACTION_BUYORDER_INTENT_BUY_SHORT
OUTCOME_SIDE_NOORDER_ACTION_SELLORDER_INTENT_SELL_SHORT
Example: same “buy NO shares” order, expressed with outcomeSide + action:
{
  "marketSlug": "your-market-slug",
  "type": "ORDER_TYPE_LIMIT",
  "price": { "value": "0.45", "currency": "USD" },
  "quantity": 10,
  "tif": "TIME_IN_FORCE_GOOD_TILL_CANCEL",
  "outcomeSide": "OUTCOME_SIDE_NO",
  "action": "ORDER_ACTION_BUY"
}
The Order returned by GET /v1/order/{orderId} and GET /v1/orders/open includes both intent and outcomeSide+action, so you can read whichever you prefer. The price-vs-side rules below apply to both forms.

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 ToOrder Intentprice.value
Buy USC at 0.83ORDER_INTENT_BUY_LONG0.83
Sell USC at 0.83ORDER_INTENT_SELL_LONG0.83
Buy Iowa at 0.83ORDER_INTENT_BUY_SHORT0.17
Sell Iowa at 0.83ORDER_INTENT_SELL_SHORT0.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:
ValueDescription
ORDER_SIDE_BUYBuy order
ORDER_SIDE_SELLSell order

Order States

Orders progress through these states:
PENDING_NEW → PARTIALLY_FILLED → FILLED

                CANCELED / REJECTED / EXPIRED
ValueDescription
ORDER_STATE_PENDING_NEWOrder received, not yet processed by matching engine
ORDER_STATE_NEWOrder accepted by matching engine and resting on the book
ORDER_STATE_PENDING_REPLACEModify request received, not yet processed
ORDER_STATE_PENDING_CANCELCancel request received, not yet processed
ORDER_STATE_PENDING_RISKOrder pending risk approval
ORDER_STATE_PARTIALLY_FILLEDOrder partially executed
ORDER_STATE_FILLEDOrder fully executed
ORDER_STATE_CANCELEDOrder canceled
ORDER_STATE_REPLACEDOrder replaced via modify (cancel-replace)
ORDER_STATE_REJECTEDOrder rejected by exchange
ORDER_STATE_EXPIREDOrder expired (GTD orders)

Time in Force

ValueDescription
TIME_IN_FORCE_DAYDAY - Expires at the end of the trading day
TIME_IN_FORCE_GOOD_TILL_CANCELGTC - Remains active until filled or canceled
TIME_IN_FORCE_GOOD_TILL_DATEGTD - Expires at specified goodTillTime
TIME_IN_FORCE_IMMEDIATE_OR_CANCELIOC - Fills immediately available quantity, cancels rest
TIME_IN_FORCE_FILL_OR_KILLFOK - Must fill entirely or cancel completely

Manual Order Indicator

Required to indicate whether the order is placed by a human or automated system:
ValueDescription
MANUAL_ORDER_INDICATOR_MANUALOrder placed manually by a user
MANUAL_ORDER_INDICATOR_AUTOMATICOrder placed by an automated trading system

Execution Types

Execution events returned in synchronous order responses:
ValueDescription
EXECUTION_TYPE_NEWOrder accepted (new working order confirmation)
EXECUTION_TYPE_PARTIAL_FILLOrder partially filled
EXECUTION_TYPE_FILLOrder fully filled
EXECUTION_TYPE_CANCELEDOrder canceled
EXECUTION_TYPE_REPLACEOrder replaced/modified
EXECUTION_TYPE_REJECTEDOrder rejected
EXECUTION_TYPE_EXPIREDOrder expired
EXECUTION_TYPE_DONE_FOR_DAYOrder done for the trading day

Order Reject Reasons

If an order is rejected, the reason will be one of:
ValueDescription
ORD_REJECT_REASON_EXCHANGE_OPTIONGeneric exchange-defined reason (used when no more specific code applies)
ORD_REJECT_REASON_UNKNOWN_MARKETUnknown or invalid market
ORD_REJECT_REASON_EXCHANGE_CLOSEDExchange/market is closed
ORD_REJECT_REASON_INCORRECT_QUANTITYInvalid quantity
ORD_REJECT_REASON_INVALID_PRICE_INCREMENTPrice not on valid increment
ORD_REJECT_REASON_INCORRECT_ORDER_TYPEInvalid order type for market
ORD_REJECT_REASON_PRICE_OUT_OF_BOUNDSPrice outside valid range
ORD_REJECT_REASON_NO_LIQUIDITYNo 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
  }
}
FieldTypeDescription
currentPriceAmountReference price for slippage calculation
bipsintegerSlippage tolerance in basis points (1 bip = 0.01%)
ticksintegerSlippage 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 a global rate limit of 20 requests per second per API key across all endpoints.
Rate Limit ExceededWhen rate limits are exceeded, the API returns HTTP status 429 Too Many Requests.
Notes:
  • Rate limits are enforced at the edge (Cloudflare) before requests reach the API
  • Limits are applied per API key
  • Implement exponential backoff and request throttling in your application

Best Practices

  1. Use string enum values - All enums are passed as strings (e.g., "ORDER_TYPE_LIMIT", not 1)
  2. Use WebSocket for updates - Subscribe to order updates instead of polling
  3. Preview before submit - Use the preview endpoint for order validation
  4. Handle rejects - Implement proper error handling for rejected orders
  5. 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.
  6. Specify manual order indicator - Required for regulatory compliance
  7. Respect rate limits - Implement request throttling to stay within rate limits and avoid 429 errors