client.orders is the spot order surface: create, modify, cancel, list, and stream your orders.
Every method is authenticated and account-scoped, so each input accepts an optional account field ("main", "active", or { subaccountId }). See Account scoping for how the default
resolves.
The SDK validates input shape and decimal scale before a request leaves your process. Excess
precision is an error, never silently rounded: "0.123456789" on a pair with 6-decimal quantities
throws a CatalogConversionError from @polyester/sdk/catalogs. The same error occurs before
network I/O when a decimal exceeds its protobuf wire-format ceiling. These ceilings are not
exchange limits. The SDK does not automatically preflight tick, step, minimum-quantity, or
minimum-notional rules. A ValidationError message names the failing field path, such as items.0.symbolId for a batchCreate that puts symbolId on the request instead of each item.
Methods
| Method | Summary |
|---|---|
preview | Evaluate a full order intent without placing it. |
create | Place a limit or market order, optionally with attached risk. |
batchCreate | Place up to 20 orders with ordered per-item results. |
modify | Patch an open order's price, quantity, client id, or risk. |
batchReplace | Amend or replace up to 50 same-symbol orders, with an admission receipt. |
getBatchReplaceStatus | Read per-item execution status for a batch replace receipt. |
cancel | Cancel one order by orderId or clientOrderId. |
batchCancel | Cancel up to 50 explicit orders with per-item results. |
cancelAll | Cancel matching orders at once, with a dry-run preview. |
cancelAllAfter | Arm, refresh, or disable the account dead-man switch. |
listOpen | List currently open orders. |
listHistory | List historical orders with status and time filters. |
getDetails | Fetch an order and one page of its lineage executions. |
subscribe | Stream the account's live orders over the private WebSocket. |
preview(input, options?)
Evaluates one complete order intent against current market, policy, risk, and balance state without
creating an order, reserving funds, or claiming its clientOrderId. It takes the same NewOrderInput as create.
await client.catalog.ensureReady();
const symbolId = client.catalog.market.requireSymbolIdByPairSymbol("BTC-USDT");
const preview = await client.orders.preview({
symbolId,
side: "buy",
qty: "0.25",
execution: { type: "limit_gtc", price: "64250.5" },
});
if (!preview.admissible) {
console.error(preview.rejection?.code, preview.rejection?.violations);
}The result carries only the fields the venue actually resolved, so an omitted field means the venue did not decide it rather than that it decided zero:
import type { OrderErrorDetail } from "@polyester/sdk";
interface PreviewOrderResult {
admissible?: boolean;
rejection?: OrderErrorDetail;
resolvedBaseQty?: string; // decimal string
protectedPriceBound?: string; // decimal string
evaluatedAt: number; // epoch milliseconds
}create(input, options?)
Places a spot order and returns a CreateOrderResult. The input shape and decimal scale are
validated locally first.
const result = await client.orders.create({
symbolId,
side: "buy",
qty: "0.25",
execution: {
type: "limit_gtc",
price: "64250.5",
postOnly: true,
},
clientOrderId: crypto.randomUUID(),
});
console.log(result.orderId, result.acceptedAt);NewOrderInput
| Field | Type | Required | Notes |
|---|---|---|---|
symbolId | number | yes | Stable market ID, an integer from 1 through 4,294,967,295. |
side | "buy" | "sell" | yes | |
qty | decimal string | one of | Base-asset quantity. Strict precision. Use this or maxQuoteDebit, not both. |
maxQuoteDebit | decimal string | one of | Quote-asset spend cap. Only for BUY market_ioc and BUY limit_ioc. |
execution | OrderExecutionInput | yes | Exact execution behavior (see below). |
clientOrderId | string | no | Account-scoped duplicate guard; retained reuse returns a conflict. |
feeAsset | "quote" | "base" | no | Which asset pays the fee. Defaults to "quote". |
selfTradePreventionMode | "expire_taker" | "expire_maker" | "expire_both" | no | Behavior when your own orders would match. |
risk | RiskPolicyInput | no | Attached TP / SL / trailing legs (see below). |
account | AccountScope | no | Scope override. |
The SDK does not generate clientOrderId. Persist it before the first create when you may need to
reconcile an uncertain outcome. Reuse of a retained ID, including an identical request, returns CONFLICT_DUPLICATE_CLIENT_ORDER_ID; it does not replay the earlier result. That rejection's OrderErrorDetail carries existingOrderId, the order that already holds the client order ID,
when it is known. Reconcile by client order ID before deciding whether to resubmit. After an OutcomeUnknownError (detail.code ORDER_CREATE_OUTCOME_UNKNOWN) or an ambiguous timeout, call getDetails({ clientOrderId }); an immediate lookup miss does not prove admission failed. Without clientOrderId, the outcome may remain unknown. See Errors for the error classes.
OrderExecutionInput is a discriminated union:
{ type: "market_ioc", maxSlippage?, clientRefPrice? }{ type: "limit_gtc", price, postOnly? }{ type: "limit_gtd", price, expireAt, postOnly? }{ type: "limit_ioc", price }{ type: "limit_fok", price }
maxSlippage accepts { kind: "slippage", slippage: "0.25" }, { kind: "bps", bps: 50 }, or { kind: "none" }. Absolute slippage is a quote price delta with
up to nine decimal places, bounded by the catalog's maxQuoteSlippage wire ceiling. A bps value
is an integer from 1 through 10,000 for a buy and 1 through 9,999 for a sell.
limit_gtd is a good-til-date limit order. Its expireAt is an exact UTC epoch-millisecond
timestamp. The SDK accepts only integer milliseconds representable by the protocol; the venue
enforces the allowed lead-time window. Reads report a GTD order as timeInForce: "GTD" and include
its expireAt when supplied by the venue.
create returns an admission acknowledgment:
interface CreateOrderResult {
orderId: string;
clientOrderId: string;
acceptedAt: number; // epoch ms
acceptedAtNs: string;
resolvedBaseQty: string; // decimal string
submittedMaxQuoteDebit?: string; // decimal string, when sized by maxQuoteDebit
takeProfitTriggerId?: string;
stopLossTriggerId?: string;
trailingStopTriggerId?: string;
}Admission does not mean the order is working or filled. Use listOpen, getDetails, or subscribe for lifecycle state.
A refused order throws a typed error whose detail.code is an OrderErrorCode. For example, MAX_OPEN_ORDERS_PER_PAIR means the account already has its maximum resting orders in that market,
so cancel one first, and ACCOUNT_REPAIRING means new orders and changes are paused briefly while
cancels still work. See Errors for order error details.
client.catalog.orders.validateSpotOrderDecimalInput(...) returns a structured list of
violations, and getSpotOrderConstraints(pair) exposes tick, step, minimum, and wire
ceilings for building UI hints. Its decimal-string wire ceilings are maxPrice, maxQtyBase, maxNotionalQuote, and maxQuoteSlippage. The
validator does not enforce those maxima. The backend remains authoritative because exchange rules
and available balance can change. See the catalog reference.modify(input, options?)
Patches an open order and returns a ModifyOrderResult. Identify the order by orderId or clientOrderId, then supply the fields you want to change.
// Change price and quantity
await client.orders.modify({
symbolId,
orderId: order.orderId,
newPrice: "64100",
newQty: "0.2",
});
// Replace the attached risk
await client.orders.modify({
symbolId,
orderId: order.orderId,
risk: {
stopLoss: {
triggerPrice: "61000",
execution: { type: "market_ioc" },
},
},
});
// Clear the attached risk
await client.orders.modify({
symbolId,
orderId: order.orderId,
clearRisk: true,
});ModifyOrderInput takes the key (orderId or clientOrderId), a required symbolId, optional requestId and newClientOrderId, a behavior flag, and the patch: newPrice and/or newQty,
plus risk (replace) or clearRisk: true (mutually exclusive). modify generates a requestId automatically; pass your own stable value when you might retry the same logical change. An OutcomeUnknownError with ORDER_MODIFY_OUTCOME_UNKNOWN means the change may already have applied:
read the order before sending it again.
The result includes ts (epoch milliseconds) and exact tsNs (an epoch-nanosecond decimal
string). It is an acknowledgment: reconcile final state through a read or stream.
interface ModifyOrderResult {
actionTaken: "unspecified" | "AMENDED" | "REPLACED";
oldOrderId: string;
finalOrderId: string;
code: string;
ts: number;
tsNs: string;
takeProfitTriggerId?: string;
stopLossTriggerId?: string;
trailingStopTriggerId?: string;
}REPLACED issues a new working order. Cancel and later modifies use finalOrderId, not oldOrderId. AMENDED keeps the same id (oldOrderId === finalOrderId).
cancel(input, options?)
Cancels a single order by orderId or clientOrderId. symbolId is optional and speeds up
routing. The result has a status of "accepted" or "unspecified", plus ts (epoch
milliseconds) and exact tsNs; read or stream the order to confirm terminal state. An OutcomeUnknownError with ORDER_CANCEL_OUTCOME_UNKNOWN means the cancel may already have
applied: read the order back before retrying.
await client.orders.cancel({ orderId: order.orderId });
await client.orders.cancel({ clientOrderId: "my-key-123", symbolId });cancelAll(input, options?)
Cancels every open order matching optional symbolIds and side filters, returning a CancelAllOrdersResponse. Preview first with dryRun: true (counts matches without submitting
cancels).
const preview = await client.orders.cancelAll({ symbolIds: [symbolId], dryRun: true });
console.log(`${preview.matchedOrders} orders would be canceled`);
const result = await client.orders.cancelAll({ symbolIds: [symbolId], side: "buy" });
for (const { orderId, clientOrderId } of result.canceledOrders) {
console.log("cancel requested", orderId, clientOrderId);
}| Field | Type | Notes |
|---|---|---|
status | "submitted" | "dry_run" | "unspecified" | |
matchedOrders | number | Orders matching the filters. |
submittedCancels | number | |
failedCancels | number | |
canceledOrders | { orderId, clientOrderId }[] | Up to 200 orders whose cancellation was requested, oldest first. |
totalCanceled | number | Every order whose cancellation was requested. |
truncated | boolean | true when totalCanceled counts more orders than canceledOrders. |
listingStatus | "included" | "not_retained_read_open_orders" | "unspecified" | Whether this response lists canceledOrders. |
ts | number | Epoch milliseconds. |
A retry with the same requestId and criteria returns the original counts with listingStatus: "not_retained_read_open_orders" and an empty canceledOrders. That does not mean
nothing was canceled: read open orders instead. Read each order's final state from subscribe or
the order reads.
Omit symbolIds (or pass []) to match every symbol. It accepts at most 100 positive IDs;
duplicates are ignored and ordering is immaterial. This is separate from cancelAllAfter, whose
single symbolId filter scopes the dead-man switch.
cancelAll generates a requestId when omitted. Reuse it with the same criteria only when
retrying an ambiguous request. Completed results are retained for at least two minutes; use a fresh
ID for each new cancellation. An orders detail with code CANCEL_REQUEST_EXPIRED means that
replay window has elapsed.
cancelAllAfter(input, options?)
Controls the account dead-man switch. timeoutSec: 0 disables it; an integer from 10 through 120
arms or refreshes it. Optional symbolId and side fields narrow which orders are canceled on
expiry.
const heartbeat = await client.orders.cancelAllAfter({
timeoutSec: 15,
symbolId,
requestId: crypto.randomUUID(),
});
console.log(heartbeat.status, heartbeat.expiresAt, heartbeat.expiresAtNs);
await client.orders.cancelAllAfter({ timeoutSec: 0 });status is "armed", "disabled", or "unspecified". expiresAt and ts are epoch
milliseconds. expiresAtNs and tsNs are exact decimal strings for bot reconciliation. An armed
switch returns its recorded effectiveScope: { accountId, symbolId?, side? }, where an unset symbolId or side covers all of them. effectiveScope is absent while the switch is disabled.
For each deliberate refresh, create a new requestId. If that refresh has an ambiguous outcome,
retry it with the same ID.
Batch mutations
Batch calls are best effort, not atomic. They preserve input order and return one result per item.
Do not treat an accepted create or cancel as final lifecycle state; reconcile through listOpen, getDetails, or subscribe.
const created = await client.orders.batchCreate({
requestId: "quote-set-42",
items: [
{
symbolId,
side: "buy",
qty: "0.01",
execution: { type: "limit_gtc", price: "64000", postOnly: true },
clientOrderId: "quote-bid-42",
},
{
symbolId,
side: "sell",
qty: "0.01",
execution: { type: "limit_gtc", price: "65000", postOnly: true },
clientOrderId: "quote-ask-42",
},
],
});
for (const result of created.results) {
if (result.status === "rejected") console.error(result.clientOrderId, result.error?.code);
}A rejected item is status: "rejected". error can be missing when the server omitted a structured
detail. Do not assume result.error.code is always there.
batchReplace amends or replaces 1 to 50 orders on a single symbol, so the batch carries one symbolId rather than a symbol per item. Each item targets an existing order by orderId or clientOrderId, and every target in the batch must be unique. Patch fields match modify: newPrice, newQty, newClientOrderId, risk, and clearRisk.
const receipt = await client.orders.batchReplace({
symbolId,
requestId: "move-quotes-43",
items: [
{ clientOrderId: "quote-bid-42", newPrice: "64100" },
{ clientOrderId: "quote-ask-42", newPrice: "64900" },
],
});
console.log(receipt.batchRequestId, receipt.status, receipt.acceptedCount);Admission is not execution. The receipt tells you what the venue accepted, index-stable against the
items you sent. Read the durable per-item outcome afterwards with getBatchReplaceStatus, keyed by
the batchRequestId from the receipt:
const status = await client.orders.getBatchReplaceStatus({
batchRequestId: receipt.batchRequestId,
});
for (const item of status.items) {
console.log(item.itemIndex, item.phase, item.replacementOrderId ?? item.code);
}import type { BatchReplaceOrdersResult, OrderErrorDetail } from "@polyester/sdk";getBatchReplaceStatus returns the same batchRequestId and counts, plus an items array whose
entries carry a phase of "admitted", "working", "rejected", or "terminal", the resulting orderStatus, and updatedTs / updatedTsNs.
Admission and status items both carry actionTaken: "REPLACED", "AMENDED", or "unspecified". Each item follows the API's default amend-or-replace rule:
- An item that keeps the order's price, does not raise its total quantity and keeps its client
order ID amends the order in place:
"AMENDED". The order keepsoldOrderIdand its queue priority,replacementOrderIdisundefined, andorderStatusdescribesoldOrderId. A new total quantity at or below the filled quantity ends the order at its filled quantity. - A new price, a larger total quantity or a new client order ID replaces the order:
"REPLACED". A successor takesreplacementOrderId, with its queue priority reset; use that ID from then on.
Cancellations stay a separate, order-explicit call:
await client.orders.batchCancel({
requestId: "cancel-quotes-43",
items: [{ clientOrderId: "quote-bid-42" }, { clientOrderId: "quote-ask-42" }],
});Batch limits are 20 creates, 50 replacements, and 50 cancellations. The SDK rejects larger
requests instead of silently chunking them because chunking changes idempotency and reconciliation
boundaries. For batchCreate, requestId is the idempotency boundary and the SDK generates one
when omitted; provide and reuse a stable value for an ambiguous retry. Within 15 minutes, the same
payload and account-scoped requestId replay each decided item's original result and timestamp
and retry the unresolved items, never admitting an item twice; a different payload with that requestId returns CONFLICT_IDEMPOTENCY_KEY_REUSE. After 15 minutes the ID is free and a repeat
can place its orders again, so read the items back instead. Per-item clientOrderId values are
optional correlation identifiers and must be unique when supplied.
listOpen(input?, options?)
Returns { orders, nextPageToken } for currently open orders. Filters: symbolId (a numeric
array), triggerId, side, pagination, and risk-inclusion flags. The list is paginated. Drain it
with nextPageToken the same way as listHistory. A single page is not the full book.
let pageToken = "";
const open = [];
do {
const page = await client.orders.listOpen({ symbolId: [symbolId], pageToken, limit: 100 });
open.push(...page.orders);
pageToken = page.nextPageToken;
} while (pageToken !== "");listHistory(input?, options?)
Same result shape as listOpen, plus status, triggerId, and nanosecond time-range filters.
Page through it with the returned token:
let pageToken = "";
do {
const page = await client.orders.listHistory({ pageToken, limit: 100 });
console.log(page.orders.length);
pageToken = page.nextPageToken;
} while (pageToken !== "");getDetails(input, options?)
Fetches one physical order and one bounded page of executions in its lineage through that order's
generation, or null if it is not found. Execution history is eventually consistent and need not
equal the order's cumulative quantities.
let pageToken = "";
do {
const details = await client.orders.getDetails({
orderId: order.orderId,
limit: 100,
pageToken,
});
if (!details) break;
console.log(details.order.status, details.trades.length, details.transfers.length);
pageToken = details.nextPageToken;
} while (pageToken !== "");Pass the returned nextPageToken as pageToken with the same orderId. trades contain executions
from the requested order's lineage through its generation; transfers are settlement transfers for
the matches on that page. A transfer can recur across pages, so deduplicate it by txId. For
state-only polling, set includeExecutionHistory: false and omit limit and pageToken. executionsComplete is true once the trades across every page add up to the filled quantity;
while it is false, read again for the rest.
Every order and trade can carry optional lineage: { id, generation }. The lineage id identifies
the logical order across replacements; generation starts at 1 and identifies its physical version.
subscribe(input)
Streams an account's orders over the private WebSocket (/v1/ws/private). Takes an accountId plus the standard handler fields and the optional order-view callbacks below, and returns an
idempotent unsubscribe function. accountId must be the account's base58 public ID, the root
account's or a subaccount's; anything else throws ValidationError. See the realtime client reference for the shared handler
contract.
import type { Order } from "@polyester/sdk";
const orders = new Map<string, Order>();
const unsubscribe = client.orders.subscribe({
accountId,
onSnapshot: (snapshot) => {
orders.clear();
for (const order of snapshot) orders.set(order.orderId, order);
},
onEvent: (order) => {
const held = orders.get(order.orderId);
if (!held || order.version > held.version) orders.set(order.orderId, order);
},
onRemoved: (orderIds) => {
for (const orderId of orderIds) orders.delete(orderId);
},
onStale: (stale, orderIds) => console.warn("order view behind", stale, orderIds),
onError: (ctx) => console.error(ctx.channel, ctx.error),
});
// later
unsubscribe();| Callback | Receives |
|---|---|
onEvent | One changed order, complete. Keep the copy with the higher version; equal versions are identical. |
onSnapshot | The account's full live view (open orders, orders not yet on the book, and recently ended orders), when the subscription starts and after a server resync. Replace local order state with it. When omitted, each snapshot order goes to onEvent. |
onRemoved | IDs of orders that left the live view and remain only in history. These are not cancellations. Without onSnapshot, it also receives the orders a resync snapshot no longer contains. |
onStale | (stale, orderIds?): true while the live view is behind, false once it caught up. When orderIds is set, only those orders show an earlier state and the rest of the view is current. A later call replaces the earlier one. |
A new order arrives with version 0 while it is still pending, then 1 from its first book state
and higher for each later execution-state change. Orders on symbols missing from the catalog are
skipped, as in the order reads. Subscriptions to the same account share one server subscription,
and one that joins later starts from the current live view. One connection carries up to 64
accounts.
The first onOpen confirms the subscription. Wait for it before a write that depends on observing
this stream. After a sequence gap, an expired token, a dropped heartbeat, or a reconnect, the
stream resumes from its last cursor and reports the interruption through onClose and onOpen,
not onError; token fetch failures along the way still reach onError. Reconnects back off from
0.5 to 10 seconds with jitter. Close codes 4400 and 4403 end the stream instead of reconnecting.
Without usable auth, subscribe calls onError when supplied and throws otherwise.
Order updates carry no reason code: read rejectReason on a rejected order and cancelReason on
a canceled order or on the replaced update of an order a replace ended.
Attached risk
create and modify accept a risk object that attaches take-profit, stop-loss, or
trailing-stop legs that activate when the order fills.
await client.orders.create({
symbolId,
side: "buy",
qty: "0.1",
execution: { type: "limit_gtc", price: "64000" },
risk: {
takeProfit: {
triggerPrice: "70000",
execution: { type: "limit_gtc", price: "69950" },
},
stopLoss: {
triggerPrice: "60000",
execution: { type: "market_ioc" },
},
oco: true, // one-cancels-other between the two legs
},
});RiskPolicyInput
Valid combinations: takeProfit + stopLoss, takeProfit + trailingStop, or any single leg. oco: true makes a pair one-cancels-other, so it requires takeProfit plus exactly one stop leg.
On a single leg it is rejected rather than ignored.
takeProfit/stopLoss:{ triggerPrice, execution, triggerPriceSource? }, whereexecutionis{ type: "market_ioc" }or{ type: "limit_gtc", price }.trailingStop:{ trailingDistance, maxSlippage?, activationPrice?, limitPrice?, triggerPriceSource? }; its child executes as market IOC. A selling order's trailing stop buys back, solimitPrice, the most the buy-back pays per unit, is required when the order sells and must be omitted when it buys. It must be at leastactivationPricewhen both are set. The SDK rejects a side mismatch withValidationErroroncreate;modifyandbatchReplacepasslimitPricethrough and the API checks it against the order's side.triggerPriceSourceis"last"(the default when omitted) or"index"."index"watches the market's index price and waits while it is stale. Spot markets do not support"mark", which the SDK rejects withValidationError.- Distances and slippage take a tagged shape:
{ kind: "distance", distance: "500" },{ kind: "slippage", slippage: "0.25" }, or{ kind: "bps", bps: 50 }. AtrailingDistancebpsvalue is an integer from 1 through 10,000; a trailing stop'smaxSlippagebpsis 1 through 9,999 on either side.{ kind: "none" }is valid formaxSlippageonly;trailingDistancerequires a real distance.
Attached exits never trade with the order they protect. When an exit fires while its order still
rests, the order's unfilled remainder is canceled first with cancelReason: "attached_exit_fired";
fills before the cancel stand. When self-trade prevention expires the exit's child against another
of the account's resting orders, the exit's trigger reports a "fire_refused" event with fireRefusalReason: "self_trade_prevented" and stays live. Once the other order is gone or no
longer first in line at the best price, the exit fires again if its condition still holds. That
event's childSeq names the expired child order. See trigger events.
Attached risk on reads
Orders come back with an optional attachedRisk holding the configured legs plus oco. Each leg
decodes the same fields as its input, including triggerPriceSource and, on a selling order's
trailing stop, limitPrice. Legs with only a "not_configured" state are omitted, and attachedRisk is absent when none remain. A
stop-loss and a trailing stop can both be present when the venue reports both. getDetails includes the legs and their live state by default; includeAttachedRisk and includeAttachedRiskState turn either off. Each leg carries an optional state:
interface AttachedRiskLegState {
status:
| "unspecified"
| "not_configured"
| "created"
| "armed"
| "running"
| "completed"
| "canceled"
| "failed"
| "paused";
armedTs?: number; // epoch ms
armedTsNs?: string; // exact, decimal string
terminalTs?: number; // epoch ms
terminalTsNs?: string; // exact, decimal string
triggerId?: string;
childOrderId?: string;
}triggerId is the standalone trigger the leg armed, and childOrderId is the order it placed
when it fired. Both are absent until they exist.
For risk that is not tied to a parent order, use standalone triggers.
The Order shape
List and stream results, and getDetails().order, share one parsed shape. Prices and quantities
are decimal strings; timestamps are epoch milliseconds. Create/modify inputs use the tagged execution union above; the read model still exposes derived orderType / timeInForce labels
plus optional market slippage fields when present.
import type { Order } from "@polyester/sdk";totalQty is the current accepted total quantity, including an accepted amendment. Retain the
original request if you need the initially submitted quantity; cumQty and leavesQty remain the
filled and working quantities. inheritedCumQty is the filled quantity carried over from
predecessors when a replacement was accepted ("0" when none). status is "partial" when a working order has a non-zero filled
quantity. That label is SDK-only; the wire status stays "working". version is the per-order
state version: 0 while the order is pending, 1 from its first book state, and higher for every
later execution-state change. Fee totals are not covered by it. Parsed enums include "unspecified" when the server omits a label or sends an unknown enum value.
Execution totals are exact:
avgPxis the average execution price, up to 18 decimal places.cumQuoteis the quote amount the fills used before fees,"0"with no fills.feeTotalis{ amount, isRebate, qty }, the net fee in the order'sfeeAsset. It covers every fill oncefeeTotal.qtyequalscumQty. Order history andgetDetails(with execution history, the default) include it; open orders andsubscribeupdates leave it out.
A rejected order carries rejectReason, the OrderErrorCode the Orders API returns for the same
refusal, such as "TWAP_CAPACITY_REACHED". A canceled order carries cancelReason. Both are
omitted for every other status. A code newer than this SDK build reads as "UNSPECIFIED" or "unspecified": treat it as a generic refusal or cancel.
cancelReason | Meaning |
|---|---|
user_request | A cancel the account sent: cancel, batchCancel, or cancelAll. |
ioc_remainder, market_remainder | The unfilled remainder of an immediate-or-cancel or market order. |
stp_expire_maker, stp_expire_taker, stp_expire_both | Self-trade prevention canceled the resting order, the incoming order, or both. |
replaced | A replace ended this order and created its successor. |
gtd_expired | A good-til-date order reached its expiry time. |
qty_at_or_below_filled | An amend or replace set the total quantity at or below the filled quantity. |
pair_drain | The market was disabled. Show it as "market disabled", not as a user cancel. |
market_halted | The exchange halted the market. Show it as "market halted". Fills before the cancel stand. |
attached_risk_refused | The market refused one of the order's attached legs, so its remainder and other legs were canceled. |
attached_exit_fired | An attached exit fired while the order still rested. |
cancel_all_after | The dead-man switch reached its deadline without a heartbeat. |
account_repair | The exchange canceled it while recovering the account. |
twap_rollover | A TWAP canceled this slice at the next slice's due time; its remainder moves to later slices. |
strategy_cancel | A trigger-placed order canceled because its trigger ended or another leg took over the exit. |
system | The exchange canceled it for a reason it does not name. |
lineage is optional metadata linking a physical order to its logical replacement chain, and expireAt is the epoch-millisecond expiry reported for GTD orders.
Orders on symbols missing from the catalog are filtered out of list responses rather than failing
the page.
Related
- Trading guide for the task-oriented walkthrough.
- Triggers for standalone automations.
- Trades for your fills.
- Requests and idempotency for retry
semantics and
clientOrderId. - Errors for validation and precision error types.