> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xarchive.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Hyperliquid WebSocket API for Real-Time Market Data

> Use the 0xArchive WebSocket API for real-time Hyperliquid market data when event order and stream state matter.

Subscribe to live Hyperliquid and Lighter market data when your application needs continuing updates: a dashboard, a monitor, an alert, or a local order book. Use REST when one response is enough, and [WebSocket replay](/websocket/replay) when the job needs historical events in order.

## REST, live, or replay

| Need | Use |
| - | - |
| The latest snapshot | REST order-book, trades, or summary routes |
| Continuing live updates | A WebSocket subscription |
| Historical events in order | WebSocket replay |
| A backtest input file | REST history, or replay when sequence matters |
| Freshness evidence | [Data quality](/data-quality) routes before you trust the output |

## Run a live subscription

This Node.js script subscribes to live BTC trades, prints five messages, then unsubscribes and closes. It runs on any plan, including Free.

```javascript theme={"theme":"github-dark"}
import WebSocket from "ws";

const apiKey = process.env.OXARCHIVE_API_KEY;
if (!apiKey) throw new Error("Set OXARCHIVE_API_KEY");

const ws = new WebSocket("wss://api.0xarchive.io/ws", {
  headers: { Authorization: `Bearer ${apiKey}` }
});
const subscription = { channel: "trades", symbol: "BTC" };
let received = 0;

ws.onopen = () => ws.send(JSON.stringify({ op: "subscribe", ...subscription }));

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  if (message.type === "subscribed") console.log("subscribed", message.channel, message.symbol);
  if (message.type === "error") console.error(message.error_code, message.message);
  if (message.type === "data") {
    console.log(message.channel, message.symbol, message.data.length, "fill legs");
    if (++received === 5) ws.send(JSON.stringify({ op: "unsubscribe", ...subscription }));
  }
  if (message.type === "unsubscribed") ws.close();
};

ws.onclose = () => console.log("closed");
```

To build your own stream from it:

<Steps>
  <Step title="Choose the venue family">
    Pick Hyperliquid core, Hyperliquid Spot, HIP-3, HIP-4, or Lighter before choosing a channel. [WebSocket channels](/websocket/channels) lists the channels and symbol formats for each.
  </Step>

  <Step title="Start with one channel and one symbol">
    Confirm the consumer keeps up with one channel-symbol pair. Do not subscribe to every channel by default: a broad set can build a local backlog, stale UI, duplicate subscriptions after a reconnect, or incorrect local books, even when the server accepts every subscription.
  </Step>

  <Step title="Handle state changes">
    Track snapshots, updates, gaps, unsubscribes, and reconnects, and rebuild local state after a reconnect. [Keep-alive](/websocket/keep-alive) has the reconnect sequence.
  </Step>

  <Step title="Watch lag before widening">
    Watch consumer lag, queue depth, reconnect count, and gap events before you add channels or symbols.
  </Step>
</Steps>

If an alert or model depends on the stream, decide in advance what it does when a gap appears, when the socket reconnects, or when freshness falls outside your tolerance.

## First events by channel

The socket's `open` event confirms only transport and authentication. A subscription is active only after `subscribed` arrives; a refused command returns `error`. The first data event depends on the channel:

* **Ordinary channels** deliver `data` messages.
* **L4 channels** begin with an `l4_snapshot`, then ordered `l4_batch` messages. See [WebSocket L4 order book](/websocket/l4-orderbook).
* **Live Lighter channels** deliver `data` with Lighter payloads: a full top-20 book on `lighter_orderbook`, two fill legs per trade on `lighter_trades`, and a market-context object on `lighter_open_interest` and `lighter_funding`. See [Lighter channels](/websocket/lighter).

A live subscription never turns into a replay. For history on live Spot L2 and trade channels, use their REST history routes; every L4 family, including Spot, HIP-3, and HIP-4, replays from checkpoints.

After `unsubscribe`, wait for `unsubscribed` before removing the subscription from local state. After a close, rebuild state on the new connection rather than applying new updates to a book from before the close.

## Live Lighter channels

Lighter live subscriptions are available on `lighter_orderbook`, `lighter_trades`, `lighter_open_interest`, and `lighter_funding` through `wss://api.0xarchive.io/ws`. `lighter_candles` and `lighter_l3_orderbook` are replay-only, and all six Lighter channels support historical replay.

Lighter on Robinhood Chain live subscriptions are available on `rh_lighter_orderbook`, `rh_lighter_trades`, `rh_lighter_open_interest`, and `rh_lighter_funding` through `wss://api.0xarchive.io/ws`. `rh_lighter_candles` is replay-only, and all five Robinhood Chain channels support historical replay.

Use REST for current Lighter candles and L3 depth.

## Next step

Parse every command and event your client will handle with the [Protocol reference](/websocket/schema).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.