Hyperliquid WebSocket
A direct order-book feed from our own Hyperliquid node over WebSocket — up to 1000 levels per side, pushed on every block. Native Hyperliquid protocol, so existing client code works after swapping the URL.
// updated 2026-09-09
A direct feed of the Hyperliquid order book from our own node, over one WebSocket connection. It speaks the native Hyperliquid WebSocket protocol: the same subscribe envelope, the same field names, the same channel / data response shape. Client code written against the Hyperliquid documentation works here after you change the URL and add the auth header — see where this differs for the short list of exceptions.
One flat tier. Streaming is billed monthly with no per-message fees. See Pricing.
Why a node feed instead of the public API
The public Hyperliquid API rebuilds the book on a timer. Our feed pushes a frame on every book change, which on Hyperliquid means on every block.
| Supanode | Public Hyperliquid API | |
|---|---|---|
| Depth per side | up to 1000 levels | 20 levels |
| Frames per 90 seconds, BTC | 1049 | 18 |
| Median gap between frames | 61 ms — the block time | 5423 ms |
Measured on 9 September 2026, both feeds read at the same time from the same machine.
What makes this feed different
- Depth to 1000 levels. The public API gives 20. Providers running the same order-book software stop at 100. We serve up to 1000 per side.
- Block-rate updates. A frame per book change, not per timer tick. The median gap is the network's own block time.
- The whole set of streams on one connection. The full book, incremental updates, best bid and offer, trades, the per-order book with owner addresses, and order statuses.
Endpoint
wss://toy.hl.supanode.xyz:48080/ws
The node runs in Tokyo. The scheme is wss:// — plain ws:// and http:// do not work.
Authentication
Send your key as an HTTP header on the WebSocket handshake:
x-token: YOUR_KEY
The header name is not case sensitive, so X-Token also works. There is no login call and no query parameter.
| Handshake | Result |
|---|---|
Valid key in x-token | 101 Switching Protocols |
| No key | 401 Unauthorized |
| Key that is not yours | 403 Forbidden |
A browser cannot connect directly. The browser WebSocket API cannot set request headers, so the key cannot be sent from page JavaScript. Connect from your backend and pass the data to the browser yourself. Query-parameter keys (?token=, ?apikey=), Authorization: Bearer and x-api-key are not accepted.
How a subscription works
One connection carries as many subscriptions as you need. Each one is a small JSON message.
Subscribe:
{ "method": "subscribe", "subscription": { "type": "l2Book", "coin": "BTC" } }
The server answers with a subscriptionResponse, then streams frames until you unsubscribe or the connection closes:
{ "channel": "subscriptionResponse",
"data": { "method": "subscribe", "subscription": {"coin":"BTC","type":"l2Book"} } }
Unsubscribe:
{ "method": "unsubscribe", "subscription": { "type": "l2Book", "coin": "BTC" } }
Repeat the subscription object exactly. Unsubscribe matches on the whole object, including nLevels. If you subscribed with "nLevels": 100, you must unsubscribe with "nLevels": 100 as well. An object that does not match is ignored and the stream keeps running.
Check the acknowledgement on coin and type, not on the whole object. The subscriptionResponse echoes the fields the server recognised. If you sent extra fields, they will not come back, even though the stream starts normally. A client library that compares the answer to the request field by field will read that as a failed subscription when nothing is wrong.
Where this differs from the public API
The protocol is theirs, so client code written against the Hyperliquid documentation works here — with four differences worth knowing before you start.
| Supanode | Public Hyperliquid API | |
|---|---|---|
| Authentication | x-token header on the handshake | none |
Depth, nLevels | up to 1000 | up to 20 |
| Incremental book | l2Diff channel | not available |
bbo frame | two fields, bid and ask | one field bbo, holding a list of two |
l2Book frame | carries nLevels | no such field |
| Unsubscribe | the subscription object must match exactly, including nLevels | matches without it |
Naming a market
- Perpetuals use the plain symbol:
BTC,ETH,SOL,HYPE. - Spot pairs use
@<index>fromspotMeta, for example@107.
Keep-alive
The server does not ping you. Two ways to keep the connection alive, both supported:
- standard WebSocket protocol ping frames — the server answers with pong;
- an application message
{"method":"ping"}— the server answers{"channel":"pong"}.
A connection with no subscriptions is not closed for being idle.
After a reconnect
Subscriptions are not restored. Send them again on the new connection.
Next steps
Every stream, its subscribe message and a real frame.
What is capped today, and what is still being built.
Working code: connect, build the book, survive a drop.
External references
- Hyperliquid WebSocket subscriptions — the protocol this feed implements.