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
Clone our complete examples: github.com/dwellir-public/hyperliquid-orderbook-server-code-examples
How to Subscribe
Send a subscription message to the WebSocket endpoint:
{
"method": "subscribe",
"subscription": {
"type": "bbo",
"coin": "BTC"
}
}Subscription Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | Yes | - | Must be "bbo" |
coin | string | Yes | - | 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:
| Market | Format | Example | Notes |
|---|---|---|---|
| Standard perpetual | Symbol | "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
{
"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:
encoding = 10 * outcome + sideOnly 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
{
"channel": "bbo",
"data": {
"coin": "BTC",
"time": 1751427259657,
"bbo": [
{"px": "106217.0", "sz": "0.001", "n": 1},
{"px": "106233.0", "sz": "0.26739", "n": 3}
]
}
}| Field | Type | Description |
|---|---|---|
channel | string | Always "bbo" for this subscription type |
data.coin | string | Trading pair symbol |
data.time | number | Snapshot block time, Unix milliseconds |
data.bbo | array | Two-element array [bid, ask], one level each, not the nested levels: [[...], [...]] of l2Book |
bbo[0] | object | null | Best bid (highest buy price), or null if no resting bids |
bbo[1] | object | null | Best ask (lowest sell price), or null if no resting asks |
Level Object Fields
| Field | Type | Description |
|---|---|---|
px | string | Price level |
sz | string | Total size at this price level |
n | number | Number 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:
{"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,bbois 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 (unliketrades/l4Book). - Timestamp:
timeis 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 - pcounterpart is folded in), consistent withl2Book.
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:
{
"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.
| nSigFigs | BTC Example | Effect |
|---|---|---|
| 5 | $106,217 | Most granular - individual price points |
| 4 | $106,200 | Moderate aggregation |
| 3 | $106,000 | Coarse aggregation |
| 2 | $110,000 | Very 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.
| Source | bid_px | ask_px | Format |
|---|---|---|---|
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
# 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?
- Volume Calculator - Estimate monthly message volume
- Contact Sales - Get your WebSocket credentials
- Dashboard - Manage your subscription
Stream institutional-grade Hyperliquid order book data with Dwellir's ultra-low latency infrastructure.
L2 Order Book
Stream aggregated Level 2 order book data from Hyperliquid. Real-time bid/ask levels with configurable depth and price aggregation.
L4 Order Book
Stream Level 4 order book data from Hyperliquid with individual order visibility. Access user addresses, order IDs, timestamps, and full order parameters.