Skip to main content
Subscribe with {"method":"subscribe","subscription":{"type":"orderCompletions"}} to receive one event each time an order ends after being executed, for every user on Hyperliquid, with or without a builder code. Add "users": ["0x...", ...] (up to 20,000 addresses) to receive only the orders placed by those wallets, and/or "builder": "0x..." to receive only the orders placed with that builder code. Filters are applied on our side; see Filters. A fill on its own does not tell you whether more fills are coming. This channel does: when the event arrives, the order is over.

What triggers an event

  • filled: the order is fully filled (sz is "0.0").
  • A final status after a partial fill: canceled, reduceOnlyCanceled, marginCanceled, selfTradeCanceled, … when part of the order was executed before it ended. Examples: an IOC or market order only partly filled, or a resting limit order canceled after a partial fill. sz is then the size left unfilled, so origSz − sz was executed.
  • The end of a TWAP that executed at least part of its size: finished, terminated, stopped (TWAP with a stop price) or error, with its executed size and notional (see TWAP ends).
Orders that end without any fill (cancels of untouched orders, rejections), TWAPs that end without executing anything, and intermediate states (open, triggered, activated) are not sent. For the full lifecycle of orders placed with your builder code, use orderUpdates with builder. Triggered TP/SL orders appear as their own completion, under the oid of the order you placed: status: "filled", orderType Stop Market / Take Profit Market (or their Limit variants), triggerCondition: "Triggered", with their fills. TWAP slices do not appear one by one (Hyperliquid writes no order status for them): you get the end of the TWAP, and the slice fills on allFills and userFills with their twapId.

Event shape

Same items as orderUpdates filtered by builder: Hyperliquid’s order, status and statusTimestamp, plus:
  • user: the wallet that placed the order;
  • builder: {"b": address, "f": fee in tenths of a basis point}, or null for an order without a builder code;
  • fills: the order’s fills in the 30 seconds before it ended (its last block included), in Hyperliquid’s fill shape: all of them for a market order. It can be [], for example when an order partially filled long before is canceled: those fills went out on allFills and userFills when they happened.

TWAP ends

A TWAP end has no order and no fills; it carries twapId and the TWAP’s state as twap, in Hyperliquid’s shape (executedSz and executedNtl are the size and notional actually executed, sz the size asked for; executedNtl / executedSz is the average price):
Tell the two kinds apart by the presence of twapId (TWAP end) or order (order completion). The users filter applies to both.

One event per order

An oid is unique across Hyperliquid and an order ends only once, so you receive one completion per oid (one per twapId for TWAPs). After a rare restart on our side, the events of the last second may be sent again: deduplicate on oid / twapId.

Filters

With both, an event is sent when it matches either (union): one connection can follow your builder code’s orders and a list of other wallets. Any other parameter is refused with an error (for example builders instead of builder), so a typo never silently turns the subscription into the full stream. The acknowledgement echoes the filters in force: {"type":"orderCompletions","users":15000,"builder":"0x..."}.

Subscribing with a list of wallets

  • Up to 20,000 addresses, 0x-prefixed, case-insensitive. The subscribe message must stay under 1 MB (20,000 addresses take about 900 KB).
  • The acknowledgement gives the number of addresses instead of echoing them: {"channel":"subscriptionResponse","data":{"method":"subscribe","subscription":{"type":"orderCompletions","users":15000}}}.
  • One orderCompletions subscription per connection: subscribing again replaces the list. {"method":"unsubscribe","subscription":{"type":"orderCompletions"}} stops it.

Volume and latency

About 60 to 100 events per second across all of Hyperliquid (October 2026), each about 1 s after its block (median 0.8–1.0 s, 95th percentile 1.3 s). There is no snapshot: it is a pure stream. To catch up after a disconnect, or to read a past window, use the REST counterpart POST /info with {"type":"orderCompletions","startTime":...} (Live Data REST API, Account History): same entries, paged, with the same optional users and builder filters, 90 days of history. Usage is billed as standard WebSocket events against your plan’s credits.

Orders and TWAPs that just ended after being executed, for every user on Hyperliquid (or the users of the subscription). Order completions: filled, or a final status after a partial fill (canceled, reduceOnlyCanceled, marginCanceled, ...; then sz is the size left unfilled), with Hyperliquid's order, status and statusTimestamp, plus user, builder ({b, f}, or null without a builder code) and fills (the order's fills in the 30 s before it ended). TWAP ends (finished, terminated, stopped, error, TWAP that executed something): twapId, status, statusTimestamp, user, builder: null and twap (Hyperliquid's TWAP state, with executedSz and executedNtl). No snapshot.

channel
enum<string>
required
Available options:
orderCompletions
data
object[]
required