Order resource. This guide walks
through the full lifecycle: submit an order, poll for status, interpret the
fields that appear as it executes, and cancel if needed.
Prerequisites
- A funded ParlayX account. See Deposit.
- A ParlayX API key.
-
A market to trade, identified by its
venueand theoutcomeIdof the side you want. There are two ways to get theoutcomeId:- Search Markets returns matching
markets with their
venueandmarketId— but not outcomes. Pass themarketIdto Get Market to read the market’s outcomes, each with itsoutcomeId. - Find Market Matches returns the
outcomes (with
outcomeId) directly, for a market matched across venues.
marketId, exactly as discovery returns it. - Search Markets returns matching
markets with their
1. Submit an order
Submit one or more orders with POST /v1/orders. The response returns an aggregator-issuedorderId — keep it; it is the only handle you need
for everything that follows.
marketOrders is a single venue order. venue, type
("market", "limit", "stop", or "stop_limit"), outcomeId, side,
amount (in USDC), and timeInForce are required; Limitless orders also carry
the marketId from the lookup. timeInForce is an object tagged by type (e.g.
{ "type": "FOK" }); a "GTD" order carries its expiresAt inside it. A
"limit" order additionally requires a limitPrice; a "stop" order requires
a triggerPrice and fires a market child when the price crosses it; a
"stop_limit" requires both a triggerPrice and a child limitPrice and fires
a resting limit child (see
Stop orders). See
Pricing and Execution for the per-venue order
shapes and price guards.
The marketOrders array can mix order types freely — a single submit can carry,
say, a market buy, a resting limit, and a stop together. They share one orderId
and are read and cancelled as one order.
Each order must be worth at least $1 in notional. For an
amount-sized
order that is the amount itself; for an order sized in shares with a
limitPrice, it is shares × limitPrice. Orders below the minimum are
rejected at submission with a 400, so an undersized order fails fast
instead of resting unfilled.Idempotency-Key header is required: re-submitting the same key
with the same body returns the original orderId instead of placing a
duplicate order (safe to retry on network errors), while reusing it with a
different body is rejected with 422. Use a stable, unique value per
logical order.
2. Poll the order
Fetch the latest state with GET /v1/orders/, passing theorderId as a path parameter.
status is one of the terminal states (filled, cancelled,
or failed). A modest polling interval — for example, every one to two
seconds — is usually enough; updatedAt advances whenever fills or status
transitions occur.
3. Interpret the lifecycle
Every order moves through a curated six-state lifecycle. The samestatus enum is reported at the order level and on each market order.
The order-level
status is a roll-up of its market orders. Multi-venue
orders commonly show partial while individual market orders are still
moving between open, partial, and filled.
4. Read the result
TheOrder itself is type-agnostic — a container for one or more market
orders, mirroring the way you submit them. It carries the data you need to
settle and reconcile:
filledAmount— Total amount filled across all market orders, in USDC.executionCost— All-in cost to execute the order, in USDC: venue fees plus collateral conversion slippage. Gas is excluded — ParlayX covers it — and any recoverable leftover collateral is also excluded.marketOrders[]— The execution result for each market order you submitted, in the order submitted (mirroring the submit request’smarketOrders). Each entry carries its owntype(market,limit,stop, orstop_limit— the same discriminator you submitted): switch on it to know which fields the entry carries. Each entry echoes themarketInfoyou submitted —venueandoutcomeId, plusmarketIdon Limitless entries (Polymarket entries never carry one) — so you can match a result back to the market it traded without relying on array order. Each entry also reports its ownstatus,filledAmount,averagePrice(as an implied probability between 0 and 1,nulluntil it has a fill),executionCost, anderror. Astoporstop_limitentry adds one conditional field (conditionalStatus), described in Conditional orders below.createdAt/updatedAt— ISO-8601 timestamps.updatedAtadvances with every state or fill change.
executionCost replaces the previous fees field on both the order and
each market order. Order-level executionCost includes venue fees plus
collateral conversion slippage; per-market-order executionCost is the
venue fees charged on that market order only.Conditional orders
A conditional order (stop / stop_limit) can stand alone or be batched with
other market orders; either way each conditional is its own marketOrders entry
of that type. A conditional is one order end to end — the same orderId
you got at submit is the only handle you ever need, even after it fires. The
entry carries one field a market or limit entry does not:
conditionalStatus— the conditional’s own lifecycle:armed(watching, nothing resting),triggered(the level crossed and the fire is claimed),fired(it has placed its order), or the terminalcancelled,expired, andfailed.
armed/triggered, the entry rests nothing, so status reads open and
filledAmount is 0. Once fired, the order it places is rolled up onto this
same entry: status, filledAmount, averagePrice, and executionCost track
the placed order’s real execution — open then partial then filled (a
stop_limit’s resting limit can sit open/partial for a while before it
fills, or never if the market gapped past the limit). There is no second order
id to fetch; just keep reading the conditional’s orderId.
Failure reasons
When a market order ends infailed, its error field is an object with a
machine-readable code from a fixed vocabulary and a human-readable
message. Use the code to decide whether to retry, adjust, or surface
the error to the user. error is null whenever the market order is not in
the failed state.
5. Cancel an order
To stop a working order before it fully fills, call DELETE /v1/orders/, passing theorderId as a path parameter. The response is the same Order
resource, reflecting the post-cancel state.
- Cancellation is best-effort. Any size that fills before the cancel
reaches the venue is still reported in
filledAmount, and the terminalstatusmay end up aspartialrolling intocancelled, or asfilledif the order completed in the race. - Orders that are already terminal (
filled,cancelled, orfailed) cannot be cancelled. - After requesting a cancel, keep polling
GET /v1/orders/{orderId}untilstatusis terminal to confirm the final outcome.