Skip to Content

Orders

All order endpoints require authentication. See Authentication.

Rate limit: v1-auth: 120 req / 60 s per IP

Sell-order inversion. Internally, a YES sell at price P is stored as a NO buy at price 100 - P. The API always returns orders in the user-facing form you submitted: side and price reflect what you intended, not what is stored.


GET /api/v1/orders

Lists your orders. Up to 200 orders are returned per call (no pagination cursor; use status to narrow the result).

Auth: Required

Query parameters

ParamTypeDefaultDescription
marketIdUUIDFilter to a specific market
statusstring"open""open" returns open + partially_filled; "filled" returns fully filled; "cancelled" returns cancelled; "all" returns all statuses

Response

{ "data": [ { "id": "d4e5f6a7-b8c9-0123-def0-234567890123", "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "marketTitle": "Will Reform Party win the most seats?", "side": "yes", "price": 55, "quantity": 100, "filledQuantity": 40, "status": "partially_filled", "orderType": "buy", "cancelReason": null, "expiresAt": null, "createdAt": "2026-01-10T09:00:00.000Z", "sharesAhead": 230 } ], "meta": { "pageSize": 1 } }
FieldTypeDescription
idUUID stringOrder identifier
userIdUUID stringYour user id
marketIdUUID stringMarket the order is on
marketTitlestringMarket title (for display)
side"yes" | "no"Side you are buying or selling
priceintegerYour order price (1–99) in user-facing form
quantityintegerTotal shares ordered
filledQuantityintegerShares already matched
statusstringopen | partially_filled | filled | cancelled
orderType"buy" | "sell"Order type
cancelReasonstring | nullWhy it was cancelled; null if not cancelled
expiresAtISO 8601 | nullExpiry time; null = Good Until Cancelled
createdAtISO 8601When the order was placed
sharesAheadintegerShares ahead of this order in the queue

POST /api/v1/orders

Places a new order and runs the matching engine. Returns the created order, any fills, any orders cancelled by the match (e.g. fully consumed resting orders), and your updated balance.

Auth: Required

Request body

{ "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "side": "yes", "price": 55, "quantity": 100, "orderType": "buy" }
FieldTypeRequiredDescription
marketIdUUIDYesTarget market
side"yes" | "no"YesSide to buy or sell
priceinteger 1–99 | nullConditionalLimit price. Required for buy orders without budgetCents. For market-sell orders set to null.
quantityinteger 1–10000ConditionalShares to trade. Required for sell orders and buy orders without budgetCents.
budgetCentsinteger > 0ConditionalEUR-cent budget for market-buy orders. Mutually exclusive with quantity.
orderType"buy" | "sell"NoDefault "buy"
idempotencyKeyUUIDNoSupply the same UUID to safely retry without double-placing. Valid for 24 hours.
expiresAtISO 8601 datetimeNoWhen the order auto-cancels. Must be in the future. Omit for Good Till Cancelled.

Buy orders: supply exactly one of quantity or budgetCents.
Sell orders: supply quantity. Set price = null for a market sell (fills at any available bid).

Response

{ "order": { "id": "d4e5f6a7-b8c9-0123-def0-234567890123", "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "side": "yes", "price": 55, "quantity": 100, "filledQuantity": 20, "status": "partially_filled", "orderType": "buy", "cancelReason": null, "expiresAt": null, "createdAt": "2026-01-15T14:32:00.000Z" }, "fills": [ { "id": "e5f6a7b8-c9d0-1234-ef01-345678901234", "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "buyOrderId": "d4e5f6a7-b8c9-0123-def0-234567890123", "sellOrderId": "c3d4e5f6-a7b8-9012-cdef-123456789012", "buyerId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "sellerId": "f6a7b8c9-d0e1-2345-f012-456789012345", "price": 55, "quantity": 20, "createdAt": "2026-01-15T14:32:00.000Z" } ], "cancelledOrders": [], "balance": { "total": 987600, "available": 987600 }, "feeCents": 110 }
FieldTypeDescription
orderobjectThe placed order in user-facing form
fillsarrayTrades generated by this order (may be empty if no matching liquidity)
cancelledOrdersarrayOrders cancelled as a side effect of this match (e.g. resting orders cancelled due to insufficient funds, expired orders, or overextended sell positions)
balance.totalintegerYour EUR-cent balance after the transaction
balance.availableintegerCurrently always equal to total; reserved for a future margin model
feeCentsinteger | nullTaker fee charged for this order, in EUR-cents. 0 if nothing filled. null on idempotent replay. See Fees.

balance.total already reflects the fee, so for a buy: spent = price × quantity + feeCents.

Status code: 201 on new order, 200 on idempotent replay.

Errors

StatusBodyWhen
400{ "error": "...", "code": "INSUFFICIENT_BALANCE" }Not enough balance or position
400{ "error": "...", "code": "INSUFFICIENT_LIQUIDITY" }Budget buy with no matching liquidity
400{ "error": "...", "code": "SELF_TRADE_BLOCKED" }The order would match your own resting order on the opposite side. Cancel or amend that order first.
400{ "error": "Market is not open for trading" }Market status is not open
400{ "error": "Market not found" }Unknown marketId
503{ "error": "...", "code": "CONFLICT_RETRY" }Transient lock conflict. Safe to retry.

PATCH /api/v1/orders/:id

Amends an open or partially-filled order. You can change price, quantity, or both.

Auth: Required

Path parameters

ParamTypeDescription
idUUIDOrder to amend (must belong to you)

Request body

Supply at least one field:

{ "price": 60, "quantity": 80 }
FieldTypeDescription
priceinteger 1–99New limit price in user-facing form
quantityinteger 1–10000New total quantity (must be ≥ filled quantity)

Amendment rules:

  • Quantity decrease only: amended in place, queue position preserved.
  • Price change or quantity increase: cancel-replace, where the resting order is cancelled and a new order is placed at the new price/quantity. Queue position is lost; the new order is re-matched immediately.

Response

Quantity decrease only (in-place, queue position preserved):

{ "order": { "id": "d4e5f6a7-b8c9-0123-def0-234567890123", "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "side": "yes", "price": 55, "quantity": 80, "filledQuantity": 40, "status": "partially_filled", "orderType": "buy", "cancelReason": null, "expiresAt": null, "createdAt": "2026-01-10T09:00:00.000Z" }, "amended": true, "queuePositionChanged": false }

Price change or quantity increase (cancel-replace, queue position lost):

{ "order": { "id": "e5f6a7b8-c9d0-1234-ef01-345678901234", "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "side": "yes", "price": 60, "quantity": 80, "filledQuantity": 0, "status": "open", "orderType": "buy", "cancelReason": null, "expiresAt": null, "createdAt": "2026-01-10T09:15:00.000Z" }, "fills": [], "amended": true, "queuePositionChanged": true, "cancelledOrderId": "d4e5f6a7-b8c9-0123-def0-234567890123", "feeCents": 0 }
FieldTypeDescription
orderobjectUpdated order
amendedbooleanfalse if nothing changed
queuePositionChangedbooleantrue when cancel-replace was used
cancelledOrderIdUUID | undefinedId of the cancelled order on cancel-replace
fillsarray | undefinedNew fills generated by the replacement order
feeCentsinteger | undefinedTaker fee charged for the replacement order, in EUR-cents. Present only on cancel-replace; 0 if it didn’t fill. See Fees.

Errors

StatusBodyWhen
400{ "error": "Cannot amend order with status: ..." }Order is not open or partially_filled
400{ "error": "Cannot reduce quantity below filled amount (N)" }New quantity < filled quantity
400{ "error": "Market is not open for trading" }Market closed during amendment
400{ "error": "...", "code": "INSUFFICIENT_BALANCE" }Insufficient funds for price/quantity increase
404{ "error": "Order not found" }Unknown id or not yours
503{ "error": "...", "code": "CONFLICT_RETRY" }Transient lock conflict. Safe to retry.

POST /api/v1/orders/cancel-batch

Cancels up to 100 orders in one call. Each cancel runs in its own transaction, so partial success is preserved. One bad id does not roll back the rest.

Auth: Required

Request body

{ "orderIds": [ "d4e5f6a7-b8c9-0123-def0-234567890123", "e5f6a7b8-c9d0-1234-ef01-345678901234" ] }
FieldTypeRequiredDescription
orderIdsUUID[]Yes1–100 order ids to cancel. Duplicates are deduplicated.

Response

{ "cancelled": [ { "id": "d4e5f6a7-b8c9-0123-def0-234567890123", "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "side": "yes", "price": 55, "quantity": 100, "filledQuantity": 40, "status": "cancelled", "orderType": "buy", "cancelReason": "user_cancelled", "expiresAt": null, "createdAt": "2026-01-10T09:00:00.000Z" } ], "failures": [ { "orderId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "code": "not_cancellable" } ], "balance": { "total": 992400, "available": 992400 } }
FieldTypeDescription
cancelledarrayOrders cancelled by this call, in user-facing form
failuresarrayOne entry per id that could not be cancelled
failures[].orderIdUUID stringThe id that failed
failures[].codestringnot_found (unknown id or not yours) | not_cancellable (already filled or cancelled) | internal (unexpected server error)
balanceobject | nullBalance after the batch; null if the post-cancel balance refresh failed

Status code: 200, including when every id is in failures.


DELETE /api/v1/orders/:id

Cancels a resting order. Open buy orders do not reserve balance, so the cancel leaves your balance unchanged. Balance changes only when an order fills.

Auth: Required

Path parameters

ParamTypeDescription
idUUIDOrder to cancel (must belong to you)

Response

{ "order": { "id": "d4e5f6a7-b8c9-0123-def0-234567890123", "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "side": "yes", "price": 55, "quantity": 100, "filledQuantity": 40, "status": "cancelled", "orderType": "buy", "cancelReason": "user_cancelled", "expiresAt": null, "createdAt": "2026-01-10T09:00:00.000Z" }, "balance": { "total": 992400, "available": 992400 } }

Errors

StatusBodyWhen
400{ "error": "Cannot cancel order with status: ..." }Order already filled or cancelled
404{ "error": "Order not found" }Unknown id or not yours