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

# Stream Order Book Depth

> Connect to the book stream and read ten levels of order book depth

<Info>
  During development, the [developer endpoints](/get-started/endpoints) work without an API key. Access to the book stream in production is gated: [request an API key](/get-started/api-key) with book stream access, or have an existing key upgraded.
</Info>

This recipe connects to the [book stream](/resources/trading-api/websockets/book-stream) and reads ten levels of order book depth per side for a single pair. See [Market Data Streams](/spot/trading/market-data-streams) for how the book is built.

<Steps>
  <Step title="Set up">
    Import a WebSocket client, read the endpoint from the environment, and pick the pair to watch.

    <AccordionGroup>
      <Accordion title="Imports and config">
        ```typescript theme={null}
        import "dotenv/config";
        import WebSocket from "ws";

        const DFLOW_TRADE_API_WS_URL =
          process.env.DFLOW_TRADE_API_WS_URL ?? "wss://dev-quote-api.dflow.net";
        const DFLOW_API_KEY = process.env.DFLOW_API_KEY; // optional; not needed for dev

        const SOL_MINT = "So11111111111111111111111111111111111111112";
        const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Connect and subscribe">
    Open the connection to `/book-stream` and send a `subscribe` op once it is open. The book stream covers direct routes only.

    <AccordionGroup>
      <Accordion title="Connect and subscribe">
        ```typescript theme={null}
        const ws = new WebSocket(
          `${DFLOW_TRADE_API_WS_URL}/book-stream`,
          DFLOW_API_KEY ? { headers: { "x-api-key": DFLOW_API_KEY } } : undefined
        );

        ws.on("open", () => {
          ws.send(
            JSON.stringify({ op: "subscribe", base_mint: SOL_MINT, quote_mint: USDC_MINT })
          );
        });
        ```
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Render the book">
    Each update carries `mid`, `tick`, and ten levels per side. `b` and `a` are arrays of `{ price, cumulative_size_human }`, ordered nearest to spot outward, where the size is cumulative base from the spot to that level.

    <AccordionGroup>
      <Accordion title="Handle messages">
        ```typescript theme={null}
        ws.on("message", (data) => {
          const frame = JSON.parse(data.toString());
          for (const book of frame.updates ?? []) {
            if (book.e) {
              console.log(`${book.sb} / ${book.sq}: ${book.e}`);
              continue;
            }
            console.log(`\nslot ${frame.u}  mid ${book.mid}  tick ${book.tick}`);
            console.log("asks (low to high):");
            for (const level of [...book.a].reverse()) {
              console.log(`  ${level.price}\t${level.cumulative_size_human}`);
            }
            console.log("bids (high to low):");
            for (const level of book.b) {
              console.log(`  ${level.price}\t${level.cumulative_size_human}`);
            }
          }
        });

        ws.on("error", (err) => console.error("WebSocket error:", err));
        ws.on("close", () => console.log("Connection closed"));

        // demo only: stop after the first updates
        setTimeout(() => ws.close(), 6000);
        ```
      </Accordion>
    </AccordionGroup>
  </Step>
</Steps>

<Note>
  Book levels are approximations computed at runtime. The `cumulative_size_human`
  at each level is the total base size available from the spot out to that price.
</Note>

## Related Resources

<CardGroup cols={2}>
  <Card title="Market Data Streams" href="/spot/trading/market-data-streams" icon="signal-stream">
    How the streams work and when to use each.
  </Card>

  <Card title="Book Stream API" href="/resources/trading-api/websockets/book-stream" icon="plug">
    Messages, fields, and the depth format.
  </Card>

  <Card title="Stream Top-of-Book Quotes" href="/spot/recipes/stream-quotes" icon="signal-stream">
    Read live bid and ask for a pair.
  </Card>

  <Card title="Authenticate Requests" href="/resources/recipes/api-keys" icon="key">
    Authenticate requests for production rate limits.
  </Card>
</CardGroup>
