Docs

BBO (Best Bid/Offer) - Top of Book

Stream the best bid and best ask for any Hyperliquid trading pair. BBO gives you the top-of-book price with minimal bandwidth, ideal for price tracking, execution triggers, and spread monitoring.

How It Works

Hyperliquid's public API has a dedicated bbo WebSocket channel, and Dwellir mirrors it natively. Subscribe with {"type": "bbo", "coin": "BTC"} (coin only, no params) and receive the same {"channel": "bbo", ...} payload shape as the public feed. It's a drop-in target for clients written against the public API.

Under the hood bbo is l2Book top-of-book (nLevels=1) with always-on dedup: a message is emitted only when the top bid or ask actually changes, at most once per block. It is functionally equivalent to {"type": "l2Book", "nLevels": 1, "strict": true}, just in the public payload shape.

Stream the best bid and best ask for any trading pair with minimal bandwidth, ideal for price tracking, execution triggers, and spread monitoring.

Code Examples Repository

How to Subscribe

Send a subscription message to the WebSocket endpoint:

JSON
{
  "method": "subscribe",
  "subscription": {
    "type": "bbo",
    "coin": "BTC"
  }
}

Subscription Parameters

ParameterTypeRequiredDefaultDescription
typestringYes-Must be "bbo"
coinstringYes-Trading pair symbol (e.g., "BTC", "ETH", "xyz:MSTR", "@150", "#10")

No rounding params

Unlike l2Book, the bbo subscription takes only coin. It always serves raw top-of-book. nSigFigs, mantissa, and nLevels are ignored (not rejected), matching the public feed. If you need rounded or aggregated top-of-book, use the l2Book with nLevels=1 approach below instead.

Coin Format by Market Type

The coin field accepts different formats depending on the market:

MarketFormatExampleNotes
Standard perpetualSymbol"BTC", "ETH", "SOL"No prefix needed
HIP-3 perpetual (permissionless)xyz:<symbol>"xyz:MSTR"Use full label with xyz: prefix
Spot@<index>"@150"Spot asset index
HIP-4 outcome#<encoding>"#10", "#31"Encoded outcome + side

Subscription Examples

JSON
{
  "method": "subscribe",
  "subscription": {
    "type": "bbo",
    "coin": "BTC"
  }
}

HIP-3 Markets

For HIP-3 (permissionless perpetuals) markets, use the full coin label format with the xyz: prefix. For example, use "xyz:MSTR" for the MicroStrategy perpetual, not just "MSTR". Standard perpetuals like BTC and ETH do not require a prefix.

Spot Markets

For spot markets, use the @{index} format where the index is the spot asset index. For example, use "@150" for a specific spot market. Spot coins require the server's --include-spot flag.

HIP-4 Outcome Markets

HIP-4 outcome markets use the #<encoding> format. The encoding is derived from the outcome ID and binary side:

Text
encoding = 10 * outcome + side

Only side 0 and side 1 are valid. For example, "#10" is outcome 1, side 0; "#31" is outcome 3, side 1. The same encoding maps to three representations:

  • Outcome spot coin: #<encoding> (used here)
  • Outcome token name: +<encoding>
  • Outcome asset ID: 100_000_000 + encoding

Live outcome IDs are returned by the outcomeMeta info response. Outcome coins require the server's --include-outcomes flag.

The first websocket message after subscribing is a subscriptionResponse; subsequent messages carry the bbo payloads.

Response Field Reference

JSON
{
  "channel": "bbo",
  "data": {
    "coin": "BTC",
    "time": 1751427259657,
    "bbo": [
      {"px": "106217.0", "sz": "0.001", "n": 1},
      {"px": "106233.0", "sz": "0.26739", "n": 3}
    ]
  }
}
FieldTypeDescription
channelstringAlways "bbo" for this subscription type
data.coinstringTrading pair symbol
data.timenumberSnapshot block time, Unix milliseconds
data.bboarrayTwo-element array [bid, ask], one level each, not the nested levels: [[...], [...]] of l2Book
bbo[0]object | nullBest bid (highest buy price), or null if no resting bids
bbo[1]object | nullBest ask (lowest sell price), or null if no resting asks

Level Object Fields

FieldTypeDescription
pxstringPrice level
szstringTotal size at this price level
nnumberNumber of orders aggregated at this level

Empty Side

A side with no resting orders serializes as null, so always null-check before reading a level:

JSON
{"channel": "bbo", "data": {"coin": "BTC", "time": 1751427259657, "bbo": [{"px": "106217.0", "sz": "0.001", "n": 1}, null]}}

Semantics

  • On-change only: a message is sent only when the top bid or ask changes (price, size, or order count). Identical top-of-book across blocks is suppressed.
  • Snapshot-based: like l2Book, bbo is computed from the per-block snapshot, not an incremental stream. A dropped broadcast recovers on the next snapshot, so a lagging client is not torn down (unlike trades/l4Book).
  • Timestamp: time is the snapshot's block time in milliseconds.
  • Outcome markets: for HIP-4 outcome coins, the top-of-book reflects the merged two-sided book (the 1 - p counterpart is folded in), consistent with l2Book.

Dwellir BBO vs Public Hyperliquid BBO

Dwellir's bbo subscription mirrors the public Hyperliquid bbo WebSocket channel: the same subscribe message and the same {"channel": "bbo", "data": {"coin", "time", "bbo": [bid, ask]}} payload shape. Clients written against the public feed work unchanged.

The difference is delivery, not data: Dwellir's bbo is snapshot-based and deduped (emitted only when top-of-book changes, at most once per block), so a lagging client recovers on the next snapshot instead of being torn down.

Aggregated Alternative: l2Book with nLevels=1

The native bbo subscription always serves raw top-of-book. When you instead want rounded or aggregated top-of-book (for example to reduce update frequency, or to keep a single unified l2Book payload shape across all depths), subscribe to l2Book with nLevels=1 and the desired nSigFigs:

JSON
{
  "method": "subscribe",
  "subscription": {
    "type": "l2Book",
    "coin": "BTC",
    "nSigFigs": 5,
    "nLevels": 1
  }
}

This returns exactly one bid and one ask level in the standard l2Book levels: [[bid], [ask]] shape (see the L2 Order Book page). nLevels is a Dwellir-specific optimisation not available on the public Hyperliquid API.

Understanding nSigFigs

nSigFigs controls price aggregation. Use 5 for full granularity (matching what the native bbo channel returns); lower values aggregate prices and may not reflect the true best level.

nSigFigsBTC ExampleEffect
5$106,217Most granular - individual price points
4$106,200Moderate aggregation
3$106,000Coarse aggregation
2$110,000Very coarse - major levels only

We tested l2Book(nLevels=1, nSigFigs=5) against the public bbo channel and confirmed 100% price match across BTC, ETH, and SOL.

Sourcebid_pxask_pxFormat
Dwellir l2Book(nLevels=1)"85.426""85.427"Same
Public Hyperliquid bbo"85.426""85.427"Same
Public Hyperliquid l2Book (top)"85.426""85.427"Same

Size Differences

Sizes (sz) may differ slightly between any two connections due to update timing. This is expected and applies to any two independent WebSocket connections.

Use Cases

Price Feeds & Tickers

Display live mid-price or last price with minimal data overhead.

Spread Monitoring

Track bid-ask spread in real-time for market quality assessment.

Execution Triggers

Fire orders when the best bid or ask crosses a threshold.

Multi-Coin Dashboards

Subscribe to BBO for many coins simultaneously with low bandwidth (1 level per coin vs 20).

Latency-Sensitive Strategies

Smaller payloads = faster parsing. BBO messages are ~10x smaller than full 20-level book updates.

Subscription Management

Switching Between BBO and Full Depth

Python
# Subscribe to BBO
await websocket.send(json.dumps({
    "method": "subscribe",
    "subscription": {"type": "bbo", "coin": "BTC"}
}))

# Later, switch to full depth (20 levels)
await websocket.send(json.dumps({
    "method": "unsubscribe",
    "subscription": {"type": "bbo", "coin": "BTC"}
}))

await websocket.send(json.dumps({
    "method": "subscribe",
    "subscription": {"type": "l2Book", "coin": "BTC", "nSigFigs": 5, "nLevels": 20}
}))

Get Access

Ready to integrate real-time Hyperliquid BBO data?


Stream institutional-grade Hyperliquid order book data with Dwellir's ultra-low latency infrastructure.