Skip to main content

Orders API

Orders are the primary trading mechanism. Operators place orders on behalf of their players. The matching engine automatically matches compatible buy and sell orders.

Authentication: All routes require X-Api-Key header.

Place Order

Submit a new order to the matching engine.

POST /api/v1/orders

Request Body:

FieldTypeRequiredDescription
marketIdstringYesMarket UUID
outcomeIdstringYesOutcome UUID
playerIdstringYesOperator-defined player identifier
sidestringYesBUY or SELL
typestringYesMARKET or LIMIT
sharesnumberYesNumber of shares (min: 1, max: 100,000)
pricenumberConditionalShare price (required for LIMIT orders, range: 0.01–0.99)
transactionIdstringNoOperator-provided reference/idempotency key
expiresAtstring (ISO 8601)NoOrder expiration time
Player Balance Validation

The prediction engine does not check player balances. Your backend must verify that the player can afford the order before submitting it. The cost of a BUY order is shares * price for LIMIT orders.

Example — Limit Buy Order:

curl -X POST https://polymarket.sandbox.playbatman.com/api/v1/orders \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"marketId": "market-uuid",
"outcomeId": "outcome-uuid",
"playerId": "player-123",
"side": "BUY",
"type": "LIMIT",
"shares": 50,
"price": 0.65,
"transactionId": "op-txn-001"
}'

Response (201 Created):

{
"success": true,
"data": {
"order": {
"id": "order-uuid",
"marketId": "market-uuid",
"outcomeId": "outcome-uuid",
"operatorId": "operator-uuid",
"playerId": "player-123",
"side": "BUY",
"type": "LIMIT",
"shares": "50",
"price": "0.65",
"filledShares": "30",
"avgFillPrice": "0.60",
"remainingShares": "20",
"status": "PARTIAL",
"transactionId": "op-txn-001",
"expiresAt": null,
"createdAt": "2026-02-18T22:00:00.000Z",
"updatedAt": "2026-02-18T22:00:00.000Z"
},
"trades": [
{
"id": "trade-uuid",
"marketId": "market-uuid",
"outcomeId": "outcome-uuid",
"buyOrderId": "order-uuid",
"sellOrderId": "counter-order-uuid",
"buyerOperatorId": "operator-uuid",
"sellerOperatorId": "other-operator-uuid",
"price": "0.60",
"shares": "30",
"buyerFee": "0.36",
"sellerFee": "0.36",
"createdAt": "2026-02-18T22:00:00.000Z"
}
],
"status": "PARTIAL",
"filledShares": "30",
"avgFillPrice": "0.60",
"remainingShares": "20"
}
}

Order Matching Behavior

When you place an order:

  1. LIMIT BUY — Matches against existing sell orders priced at or below your limit price, starting from the lowest ask. Unmatched shares remain in the order book.
  2. LIMIT SELL — Matches against existing buy orders priced at or above your limit price, starting from the highest bid. Unmatched shares remain in the order book.
  3. MARKET BUY — Matches against the best available sell orders at any price until the requested shares are filled or liquidity is exhausted.
  4. MARKET SELL — Matches against the best available buy orders at any price until the requested shares are filled or liquidity is exhausted.

Order Statuses

StatusDescription
PENDINGOrder is in the book, no shares matched yet
PARTIALSome shares matched, remainder still in the book
FILLEDAll shares fully matched
CANCELLEDOrder cancelled by operator or system
EXPIREDOrder expired (passed expiresAt)
REJECTEDOrder rejected (e.g., no liquidity for market order)

Cancel Order

Cancel an open order.

DELETE /api/v1/orders/{orderId}

Only orders with status PENDING or PARTIAL can be cancelled.

Example:

curl -X DELETE https://polymarket.sandbox.playbatman.com/api/v1/orders/{orderId} \
-H "X-Api-Key: your-api-key"

Response:

{
"success": true,
"data": {
"id": "order-uuid",
"status": "CANCELLED",
"remainingShares": "0",
...
}
}

Get Order

Retrieve a single order by ID.

GET /api/v1/orders/{orderId}

Response: Same shape as the order object in the Place Order response.

List Orders

List orders for your operator account with optional filters.

GET /api/v1/orders

Query Parameters:

ParameterTypeDescription
playerIdstringFilter by player ID
marketIdstringFilter by market
outcomeIdstringFilter by outcome
sidestringFilter by side (BUY or SELL)
typestringFilter by type (MARKET or LIMIT)
statusstringComma-separated statuses
cursorstringPagination cursor
limitnumberPage size

Example — Get all open orders for a player:

curl "https://polymarket.sandbox.playbatman.com/api/v1/orders?playerId=player-123&status=PENDING,PARTIAL" \
-H "X-Api-Key: your-api-key"

Response:

{
"success": true,
"data": {
"orders": [ ... ],
"total": 5,
"hasMore": false,
"nextCursor": null
}
}

Validation Rules

RuleDetails
Market must be OPENOrders rejected if market is in any other status
Trading window activeCurrent time must be between tradingStartsAt and tradingEndsAt
Valid outcomeOutcome must belong to the specified market
Share range1 to 100,000 (configurable)
Price range0.01 to 0.99 (configurable, LIMIT orders only)
SELL position checkOperator must hold enough shares to sell
playerId requiredMust be a non-empty string

Error Codes

CodeDescription
ORDER_NOT_FOUNDOrder with the given ID does not exist
ORDER_INVALID_PRICEPrice outside allowed range
ORDER_INVALID_SHARESShares outside allowed range
ORDER_CANNOT_CANCELOrder is not in a cancellable status
ORDER_NO_LIQUIDITYNo matching orders available (market orders)
MARKET_NOT_OPENMarket is not open for trading
POSITION_INSUFFICIENT_SHARESNot enough shares to sell