Skip to navigation

Orders

An order’s applied image (msgType orderUpdate)

URL — No public environment serves this socket yet.

Topic order

Request parameters

ParameterTypeRequiredDescription
opstringYessubscribe
reqIdstringYesEchoed byte-exact on the answer. Printable ASCII, escape-free; anything else answers MALFORMED.
paramsobjectYes
> topicsarray of stringsYesorder

Response parameters

ParameterTypeRequiredDescription
opstringYesOne of subscribe, unsubscribe.
reqIdstringYesEchoed byte-exact on the answer. Printable ASCII, escape-free; anything else answers MALFORMED.
successbooleanYestrue

Push data parameters · orderUpdate

live and terminal are the forward-compatible reads: a status appended to the platform’s schema later arrives with both booleans already set, so a client that buckets on them never mis-buckets a status it has not heard of. Bucket on those, not on status.

cancelRequested is live and a cancel in flight — a fact about an order, not a different kind of order.

Two voices explain a row, and a client shows both. message is the platform’s own words for reason; venueText is whatever the venue said, verbatim. They are not alternatives: where the venue is the one that decided, message is the framing (“the venue rejected this order”) and venueText is the substance (“insufficient margin”). Where the platform decided — OWNER_TIMEOUT, INSTRUCTION_FRESHNESS_EXPIRED, RECONCILE_PROOF — no venue said anything and message is the only text there is. Render message, then venueText after it when present. Both are null on the ordinary path, where a row states no reason at all.

What the image holds. Every order of the organization this member retains, keyed by orderId: every live order whatever its age, and a terminal order whose last venue timestamp — or its acceptance, when the venue stated none — falls inside the served window, 24 hours by default and a per-deployment setting. A terminal order older than the window is not in a new image, though a delta for it would still arrive; it is not gone, it is out of scope, and order history is a query lane’s job rather than this one’s.

How a row leaves. Only by the platform releasing it under its own retention, and that release rides no wire — there is no removal message and no tombstone. A client learns a row is gone by re-subscribing and rebuilding its map from the image, which is exactly what part: 1 clearing the map is for. Nothing else ever removes a row; a terminal order stays in your map, and terminal is what marks it.

ParameterTypeRequiredDescription
eventstringYesorder
msgTypestringYesorderUpdate
topicstringYesorder
seqstringYesThe stream position, as a decimal string — an int64 a JSON number would truncate.
seqTsstringYesThe stream timestamp, epoch-ns as a decimal string.
isSnapshotbooleanYesOne of true, false.
snapshotIdstringNoPresent on a snapshot part only, and the same on every part of one image; the next image of any topic carries a different one. Opaque — compare it for equality and nothing else. It is not a sequence, a version or a timestamp, and its shape may change; a client that ordered by it would be relying on how a member happens to mint it. Use it to keep two images apart. A repeat subscribe re-pushes the image — that is the resync, and there is no separate op — so a client can start image N+1 while N is still arriving, and without a name on each part it cannot tell which last: true closes which, nor stop a straggling part of N landing in the map N+1 just cleared. Discard any part whose snapshotId is not the one you are currently applying.
partintegerNoPresent on a snapshot part only; 1-based.
lastbooleanNoPresent on a snapshot part only. The image is complete when true — including for an empty channel, which is still one part.
dataarray of objectsYesOne order’s applied image, keyed by orderId. Upsert by that key into the map part: 1 cleared.
> orderIdstringYesThe upsert key, as a decimal string — an int64.
> versionstringYes
> clientOrderIdstring, nullableYesThe id the submitter chose; null when it sent none.
> accountIdintegerYes
> accountstring, nullableYesThe account’s display name; null when the referenced row is not held.
> instrumentIdstringYesAn instrument, by the platform’s own id — an int64 as a decimal string, because a JSON number cannot hold one. One id space across this wire and the HTTP lane, and the same one both order doors take: the id you read here is the id you send, on submitOrder and on POST /orders alike. It is the platform’s own reference-data key and nothing else’s. It is not a venue symbol, and it is not an id from any other system — in particular it does not equal an immix-api v2 Instrument.id, and there is no arithmetic that maps between them. A client holding v2 ids resolves through the symbol, once, at cutover: instrument beside this field carries the platform symbol (OKX@BTC/USDT), which is what both systems can be joined on. The id is the stable address and the symbol is the convenience: a symbol is reference data’s to change and this id is not.
> instrumentstring, nullableYes
> credentialIdintegerYes
> userIdintegerYesWho SUBMITTED, never restamped. Attribution of a cancel is a different question and this field does not answer it.
> sidestringYesOne of UNKNOWN, BUY, SELL.
> orderTypestringYesOne of UNKNOWN, LIMIT, MARKET.
> timeInForcestringYesGTD is reserved and never appears on this wire in v1. One of UNKNOWN, GTC, IOC, FOK, GTD.
> postOnlybooleanYes
> reduceOnlybooleanYesAlways false in v1; the platform refuses reduceOnly outright.
> pricestring, nullableYesExact decimal at the record’s price scale, trailing zeros kept. Null for a MARKET order, which has no price rather than a zero one.
> qtystringYes
> statusstringYesDo NOT bucket on this. A status appended to the platform’s schema later is a value you have not heard of; bucket on live and terminal, which arrive already set for it. One of UNKNOWN, QUEUED, INSTRUCTED, OPEN, PARTIALLY_FILLED, FILLED, CANCELED, REJECTED, EXPIRED, INSTRUCTION_EXPIRED, EXPIRED_UNCONFIRMED, NOT_FOUND_AT_VENUE.
> livebooleanYes
> terminalbooleanYes
> cancelRequestedbooleanYesLive, with a cancel in flight — a fact about an order, not a different kind of order.
> transitionstringYesAdvisory. On a snapshot row it reads SNAPSHOT: the durable transition belongs to a fact, and a snapshot is not one. One of UNKNOWN, SUBMITTED, INSTRUCTED, ACKNOWLEDGED, OPENED, TRADE, CANCEL_REQUESTED, CANCEL_REJECTED, CANCELED, REJECTED, EXPIRED, INSTRUCTION_EXPIRED, EXPIRED_UNCONFIRMED, NOT_FOUND_AT_VENUE, RECONCILE_REQUESTED, RESTATED, SNAPSHOT.
> reasonstring, nullableYesNull when the record states no reason. One of USER_REQUESTED, VENUE_INITIATED, POST_ONLY_WOULD_CROSS, MMP, SELF_TRADE_PREVENTED, IOC_REMAINDER, FOK_UNFILLED, UNSUPPORTED_AT_VENUE, VENUE_REJECTED, INSTRUCTION_FRESHNESS_EXPIRED, RECONCILE_PROOF, OWNER_TIMEOUT, VENUE_REFERENCE_MISSING.
> venueCodeinteger, nullableYes
> messagestring, nullableYesThe platform’s own words for reason — display text, null exactly when reason is null. Branch on reason, the stable name; this sentence may be reworded in any release and carries no numbers. Show it beside venueText, never instead of it. The two are different voices: this one is the platform’s, venueText is the venue’s. Where the venue is the one that decided — VENUE_REJECTED above all — this reads “the venue rejected this order” and the venue’s own text holds why (“insufficient margin”). A client that rendered one or the other would hide the informative half exactly when it mattered. Render message, and render venueText after it when it is present.
> venueTextstring, nullableYesWhatever the venue said, verbatim — the venue’s voice, never the platform’s. Display it; do not parse it. Null whenever no venue said anything, which includes every reason the platform decides for itself (OWNER_TIMEOUT, INSTRUCTION_FRESHNESS_EXPIRED, RECONCILE_PROOF): for those, message is the only text there is.
> cumQtystringYes
> leavesQtystringYes
> avgPxstring, nullableYesNull with no fills.
> lastFillQtystring, nullableYes
> lastFillPxstring, nullableYes
> venueCumQtystring, nullableYesNull means the venue never reported a cumulative. A reported cumulative of zero is a value, and says something different.
> executionsCompletebooleanYes
> acceptedAtNsstring, nullableYesEpoch-ns as a decimal string; null when the stamp is unset.
> instructedAtNsstring, nullableYes
> cancelRequestedAtNsstring, nullableYes
> venueTsNsstring, nullableYes
> tradingPolicyIdinteger, nullableYes
> tradingPolicyVersionstring, nullableYes
> venueOrderIdstring, nullableYesThe venue’s own id for the order; null before the venue names one.

Push data parameters · orderRejected

The order topic’s second shape. A submitOrder or cancelOrder that was offered and then refused at admission arrives here, correlated by the clientOrderId you sent (or by orderId for a cancel that named one). This is the other half of the offer contract: an ack told you the command reached the stream, and one of orderUpdate status: QUEUED or orderRejected tells you what became of it.

It is never in a snapshot, and isSnapshot is false here by construction. A refusal is a fact no fold holds: nothing was minted, so there is no row to retain or restore. A client that replaces its blotter on last: true will not get its refusals back — they are live-only, and history is a query lane’s job. Do not key a map on them.

Switch on msgType. Both shapes carry event: order and topic: order, because they are the same subscription; msgType is the discriminator and it is a const on both.

ParameterTypeRequiredDescription
eventstringYesorder
msgTypestringYesorderRejected
topicstringYesorder
seqstringYesThe stream position, as a decimal string — an int64 a JSON number would truncate.
seqTsstringYesThe stream timestamp, epoch-ns as a decimal string.
isSnapshotbooleanYesfalse
dataarray of objectsYesOne refused command. Not an order — do not upsert it into the blotter map. A refused submit minted nothing, so orderId is null; a refused cancel names the order it addressed. observedValue and limitValue are the refusal’s detail pair — what the command carried and the bound it breached — and unit says what they measure. Both legs are decimal strings at the scale the reason states, and all three are null together when the reason is about identity, capability or state rather than a quantity. Whether a pair is stated is a property of the refusing arm, not of the reason: the same reason can refuse bare on one arm and with a measured pair on another, so read the pair’s own nullness and never infer it from reason. unit is derived by this edge, not carried by the platform’s schema, which is precisely why it is on the wire: without it a client would have to guess from magnitude whether a 5 is basis points or a count of orders. reason is the stable name — switch on it. message is display text for a human and may be reworded in any release; never branch on it.
> commandstringYesWhich command was refused. ATTRIBUTE is an internal attribution command that no client op produces — it can never answer your submitOrder or cancelOrder, and a client may treat it exactly as it treats a value it does not know. Tolerate an unknown value: this enum is appended to as the owner’s surface grows. One of UNKNOWN, SUBMIT, CANCEL, ATTRIBUTE.
> reasonstringYesWhy the owner refused. A closed enum that is appended to — tolerate an unknown value and fall back to message. The first failing check wins, deterministically, so exactly one reason describes a refusal. One of UNKNOWN, CLIENT_ORDER_ID_CONFLICT, ORG_MISMATCH, ACCOUNT_NOT_ACTIVE, CAPABILITY_DENIED, INSTRUMENT_NOT_LIVE, CREDENTIAL_UNAVAILABLE, CONNECTION_DOWN, TRADING_POLICY_MISSING, TRADING_HALTED, INVALID_FIELD, UNSUPPORTED_AT_VENUE, NO_REFERENCE_PRICE, TICK_SIZE_VIOLATION, QTY_STEP_VIOLATION, QTY_BOUND_BREACH, MIN_NOTIONAL_BREACH, TICKET_QTY_CAP_EXCEEDED, TICKET_NOTIONAL_CAP_EXCEEDED, COLLAR_BREACH, OPEN_ORDER_CEILING, RATE_CEILING, UNKNOWN_ORDER, ORDER_TERMINAL, PRICE_BOUND_BREACH, ORDER_STATUS_UNKNOWN, ORG_NOT_ACTIVE, FILL_PRECISION_OVERFLOW.
> messagestringYesDisplay text for reason. Display only.
> clientOrderIdstring, nullableYesThe id you sent, echoed. Null for a command that carried none — a cancel by orderId.
> orderIdstring, nullableYesThe order the command addressed, as a decimal string. Null for a refused submit: no order was minted.
> accountIdinteger, nullableYesNull when the refusing check fired before the account resolved.
> accountstring, nullableYesThe account’s display name; null when unresolvable here.
> instrumentIdstring, nullableYesA decimal string; null when the refusing check fired before resolution.
> instrumentstring, nullableYesThe instrument’s symbol; null when unresolvable here.
> userIdintegerYesThe acting user the edge stamped; 0 for a machine.
> observedValuestring, nullableYesWhat the refused command carried, as a decimal string at the reason’s own scale. Null when the reason states no pair.
> limitValuestring, nullableYesThe bound it breached, in the same unit and at the same scale.
> unitstring, nullableYesWhat the pair measures — derived by this edge so the numbers are self-describing. Null whenever the pair is null. It is also null for INVALID_FIELD even when a pair is stated: that reason covers arms whose observed value is a price on one and a quantity on another, and the reason alone cannot say which, so no unit is claimed rather than one guessed. Treat a null unit beside a non-null pair as “unlabelled”, never as a default unit. One of PRICE, QTY, NOTIONAL, BPS, NS, COUNT.
> tradingPolicyIdinteger, nullableYesThe policy in scope when the refusal fired; null when the refusing check ran before policy resolution.
> tradingPolicyVersionstring, nullableYesThe policy’s version as a decimal string; null when none resolved.