Skip to main content
Watch Hyperliquid transactions before they are in a block. The mempool channel streams each signed action our Hyperliquid node receives from its peers, such as orders, cancels, modifies, TWAPs, leverage changes and transfers, as soon as it arrives. It covers every Hyperliquid product: perps, HIP-3, HIP-4 and Spot.

See pending actions

Orders, cancels and modifies as they reach our node, before they are in a block.

Join to outcomes

Match a pending order to its l4_orders event by client order id, and a cancel by order id.

Know the sender

Recover the signing wallet from the signature, then resolve it to the trading account.
Pending is not executed. A transaction on this channel is not yet in a block, and it can still be rejected, expire or never land. On liquid perps most post-only orders are rejected, because they would cross the book; From pending to outcome shows where rejections appear.
The channel is live only. It has no replay, no history, no REST route and no export, and it is never stored: a message you miss while not subscribed cannot be fetched later.

Connect

Connect to wss://stream.0xarchive.io/ws, the only endpoint that serves mempool. It takes the same API key and the same protocol as wss://api.0xarchive.io/ws: send the key in the opening handshake as Authorization: Bearer $OXARCHIVE_API_KEY, as WebSocket connection describes. The stream endpoint also serves l4_orders, so one connection carries both sides of the join below. The mempool channel is included with the Pro, Scale and Enterprise plans. It is the one channel that is not on every plan: every other channel and route is on every plan, Free included.
Most other channels are served only on wss://api.0xarchive.io/ws, so a client that also needs them keeps a second connection there.

Subscribe

symbol is optional on this channel and on no other. Leave it out to receive every pending transaction our Hyperliquid node receives, or name one market to receive only the actions that reference it. Spell it as on the other channels: BTC for perps, xyz:XYZ100 for HIP-3, HYPE-USDC for Spot (HYPE/USDC is accepted too), and the outcome side coin, such as #49720, for HIP-4.
Every pending action our node receives:
The server confirms it with null in coin and symbol:
Only the actions that reference BTC, sent as a separate message:
The confirmation carries the canonical spelling, such as HYPE-USDC for a subscribe sent as HYPE/USDC:
A symbol subscription receives every action whose asset ids include that market. An action that references several markets, such as an order batch on BTC and ETH, is sent whole to the subscribers of each. An unknown symbol returns error_code invalid_symbol. To stop, send unsubscribe with the same fields: without symbol it stops the unfiltered stream, with symbol that symbol’s subscription.

What arrives

Each data message carries one batch of transactions, sent as soon as the node receives it from a peer. coin and symbol are the subscription’s symbol, or null on the unfiltered stream, and data holds one item per signed action:
action.type names the action, and its fields follow Hyperliquid’s exchange API. The ones you join on: Other common types are scheduleCancel, twapOrder, twapCancel, updateLeverage, updateIsolatedMargin, noop, evmRawTx, and transfers such as usdSend, spotSend, usdClassTransfer and sendAsset. Hyperliquid adds types over time, so pass over a type you do not recognize instead of failing on it. The same signed action can occasionally arrive twice. Deduplicate on signature when you count or store actions.

From pending to outcome

Subscribe to l4_orders for the same market on the same connection. Its events show what the exchange did with pending orders and cancels:
1

Orders: join on the client order id

An l4_orders event carries cloid when the order was placed with one, the same value as c on the pending order, whether it came in orders[] or as the new order of a modify or batchModify. Its first event for that cloid is the order’s outcome: open (resting), filled, canceled (for example an immediate-or-cancel order that did not fill), or on Spot and HIP-4 a rejection. An order placed without a client order id can only be matched approximately, on market, side, price and size.
2

Cancels: join on the order id

A cancel names the order by o. If the cancel succeeds, a canceled event for that oid follows; if the order already filled or was canceled, none does. A cancelByCloid names the order by cloid.
3

Rejections: know where they show

On Spot and HIP-4, a rejected order appears on l4_orders with the reason as its status, such as badAloPxRejected. On perps and HIP-3, l4_orders carries accepted orders only: a pending order whose cloid never arrives there within a few seconds was not accepted: the exchange refused it, or it expired.
Not every order passes through the mempool on its way to a block. Most orders reach our node this way, but some reach a block without being gossiped to it first, so some l4_orders events have no pending action before them. This Python script follows BTC orders and counts how many the exchange accepted. It uses the websockets package (pip install websockets).

Who sent it

The signer’s address is not included, but every item carries what it takes to recover it: the action exactly as signed, the nonce, the vault address, the expiry and the signature. Keep action with its keys in the order received; JSON parsers in Python and JavaScript do this by default.
1

Recover the signer

Orders, cancels, modifies and leverage changes are exchange actions, signed as Hyperliquid’s Agent typed data over a hash of the action. This function recovers the address that signed one, with msgpack and eth-account (pip install msgpack eth-account):
Transfers such as usdSend and spotSend are user-signed actions with their own typed data, so this function does not apply to them.
2

Resolve the account

Market makers and bots usually sign with an API wallet that acts for their account. Resolve the account in this order: the vault_address when the action has one; otherwise the account an API wallet acts for, from Hyperliquid’s userRole info request; otherwise the signer itself.
Cache the answer per signer and refresh it from time to time. Where the action has a matching l4_orders event, its user confirms the account.

Volume and limits

The unfiltered stream carries every pending transaction our Hyperliquid node receives, several megabytes per second before compression. Most of it is market makers’ post-only quotes. Use a client that negotiates permessage-deflate compression, as most WebSocket libraries do by default, and subscribe with a symbol where the job allows it.
  • Unfiltered capacity: unfiltered subscriptions are limited across the service. When they are full, a subscribe without symbol returns error_code rate_limited with The unfiltered mempool stream is at capacity. Subscribe with a symbol, or try again later. Symbol subscriptions are not limited this way.
  • Slow consumers: as on any channel, a connection that reads too slowly is closed after an error with error_code slow_consumer. Read each message off the socket promptly and do heavy work elsewhere.
  • Plan limits: the unfiltered stream and each symbol count as one subscription toward your plan’s limit per connection, and a connection accepts at most 10 subscribe or unsubscribe operations per second. See WebSocket limits.
  • Credits: each data message is billed like any other WebSocket message; see Credits. The unfiltered stream sends many messages, so check its usage in the dashboard after a short run.

Errors

Errors arrive as error messages with a stable error_code. The connection stays open after each of these except slow_consumer. The channel has no replay: a replay command for mempool returns an error. Errors lists every code.

Next step

L4 order book

Follow order events and book changes with the l4_orders and l4_diffs channels.
Last modified on October 8, 2026