Skip to main content
Order IDs on BULK are deterministic: they are derived from the signed transaction (action, account, nonce, and action index). You do not need to supply a client order ID. You can compute the order ID before or after sending the request, and use the official library to do it for you.

Why deterministic?

  • No client order ID required - The exchange assigns a unique ID from the transaction contents.
  • Know the ID before the node responds - Useful for optimistic UI and local tracking.
  • Reproducible - Same action + account + nonce + index always yields the same order ID.

Computing order IDs

You can compute order IDs yourself from the protocol formula, or use bulk-keychain so you don’t have to implement the binary encoding. The official signing library bulk-keychain can compute order IDs for you in Node.js, browser (WASM), Rust, and Python. Single-order and batch (group) transactions are supported. After signing, the returned object includes the order ID(s): TypeScript (Node.js):
Python:
Rust:
For multi-order (grouped) transactions, enable batch order ID computation so you get an ID per order. See the bulk-keychain README for signGroup, prepareGroup, and batch order ID options. You can also compute an order ID without signing (e.g. for display or lookup) using the library’s compute_order_id / computeOrderId helpers with order fields, nonce, and account.

Option 2: Compute from the protocol

Order IDs are the base58-encoded SHA-256 hash of:
  • seqno: Zero-based index of the order-producing action in the actions array (0 for a single-order tx).
  • single_action: Canonical bincode of that one action (same encoding used for signing).
  • For limit/market actions, px and sz use fixed-point: round(value * 1e8) as u64.
Implementing this requires the same canonical action encoding as the rest of the protocol; using bulk-keychain avoids that.

Order IDs versus trade IDs

An orderId identifies one order action. One order can produce multiple fills, and each fill is a separate execution. Authenticated account fill surfaces identify an execution with tradeId, a lossless "<slot>:<event-sequence>" string. Maker, taker, and isolated-account views of the same execution share the value. Treat it as opaque and network-local: gaps are normal in one account’s view, and the value is not portable across forks or networks. tradeId is available on paginated account fill history and account WebSocket fill updates. Public trades.<symbol> market-data updates do not currently include it.

Summary