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

# Build with the L2 Order Book

> Stream self-contained L2 order book snapshots for top-of-book quotes and depth analytics on Hyperliquid HyperCore.

The `l2Book` channel streams real-time **L2 order book** data — bids and asks aggregated into price levels by significant figures. Each message is self-contained, so it's the simplest channel to consume: you don't maintain local state between messages. Use it for top-of-book quotes, spread monitoring, and depth analytics.

<Info>
  For high-frequency book tracking across many assets, prefer
  [`l2BookDiff`](/guides/hyperliquid/websockets/l2-book-diff) — it sends only
  changed levels and is billed at a fraction of the per-minute rate.
</Info>

## Subscribe

```json theme={null}
{
  "method": "subscribe",
  "subscription": { "type": "l2Book", "coin": "HYPE" }
}
```

`coin` is optional — omit it to stream **all** assets on one subscription (billed at the higher wildcard rate; see [pricing](/guides/hyperliquid/websockets/overview#pricing)).

## Message shape

Each message carries the aggregated book for a coin. Levels are a two-element array — `[bids, asks]` — and each level is `{ px, sz, n }`.

```json theme={null}
{
  "channel": "l2Book",
  "data": {
    "coin": "HYPE",
    "levels": [
      [{ "px": "0.50", "sz": "100", "n": 5 }, { "px": "0.49", "sz": "250", "n": 8 }],
      [{ "px": "0.51", "sz": "200", "n": 3 }, { "px": "0.52", "sz": "120", "n": 4 }]
    ]
  }
}
```

| Field    | Meaning                                      |
| -------- | -------------------------------------------- |
| `px`     | Price level, as a string.                    |
| `sz`     | Total size resting at that level.            |
| `n`      | Number of individual orders at that level.   |
| `levels` | Two-element array: `[bidLevels, askLevels]`. |

## Consume it

Because each message is a complete snapshot, you can read top-of-book directly — no state to maintain:

```javascript theme={null}
ws.on("message", (raw) => {
  const msg = JSON.parse(raw.toString());
  if (msg.channel !== "l2Book") return;

  const [bids, asks] = msg.data.levels;
  const bestBid = bids[0]; // highest bid
  const bestAsk = asks[0]; // lowest ask
  const spread = Number(bestAsk.px) - Number(bestBid.px);

  console.log(`${msg.data.coin} spread: ${spread}`);
});
```

## When to use L2 vs. L2 diff

| Use `l2Book` when…                                 | Use [`l2BookDiff`](/guides/hyperliquid/websockets/l2-book-diff) when… |
| -------------------------------------------------- | --------------------------------------------------------------------- |
| You want the simplest integration (no local state) | You track the full book at high frequency                             |
| You watch a few assets and care about top-of-book  | You subscribe to many assets or the wildcard stream                   |
| Bandwidth and CU cost aren't a concern             | You want bandwidth proportional to what changed                       |
