Order Book WebSocket API
Overview
Dwellir provides a high-performance WebSocket server delivering real-time order book data from Hyperliquid with ultra-low latency. This service offers Level 2 (L2), Level 4 (L4), and trades streaming directly from Hyperliquid nodes, significantly faster than public API endpoints.
Key Features
- Ultra-low latency - Direct node connectivity eliminates public API overhead
- Full order book depth - Access to L4 data with individual order visibility
- Real-time streaming - WebSocket push model for immediate updates
- Efficient compression - Optimized bandwidth usage for high-frequency data
- Institutional grade - Professional infrastructure with monitoring and support
Hosted Service by Dwellir
For production use cases requiring minimum latency, Dwellir offers hosted WebSocket servers with:
- Direct Hyperliquid node connectivity for fastest possible data access
- Geographic distribution for optimal routing
- Professional infrastructure and 24/7 monitoring
- Significantly faster than public API endpoints (~10-50ms improvement)
📧 Contact: ben@dwellir.com for access to hosted instances
Quick Start
- Python
- JavaScript
import json
import asyncio
import websockets
async def connect_orderbook():
# Contact ben@dwellir.com for server details
uri = "wss://your-instance.dwellir.com/ws"
async with websockets.connect(uri) as websocket:
# Subscribe to BTC L2 book
await websocket.send(json.dumps({
"method": "subscribe",
"subscription": {
"type": "l2Book",
"coin": "BTC",
"nLevels": 25
}
}))
# Process real-time updates
async for message in websocket:
data = json.loads(message)
if data["channel"] == "l2Book":
print(f"BTC spread: {calculate_spread(data['data'])}")
asyncio.run(connect_orderbook())
const WebSocket = require('ws');
// Contact ben@dwellir.com for server details
const ws = new WebSocket('wss://your-instance.dwellir.com/ws');
ws.on('open', () => {
// Subscribe to ETH trades and order book
ws.send(JSON.stringify({
method: 'subscribe',
subscription: {
type: 'trades',
coin: 'ETH'
}
}));
});
ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.channel === 'trades') {
console.log(`ETH trade: ${message.data[0].sz} @ ${message.data[0].px}`);
}
});
API Documentation
WebSocket Endpoint
wss://<your-instance>.dwellir.com/ws
The server exposes a single WebSocket endpoint for all data streaming. Clients send JSON messages to manage subscriptions and receive real-time market data updates.
Connection Management
- Connect to the WebSocket endpoint
- Subscribe to desired data streams
- Receive real-time updates
- Handle reconnections gracefully
Message Protocol
Client → Server Messages
Subscribe to Data Stream
{
"method": "subscribe",
"subscription": {
// Subscription configuration (see types below)
}
}
Unsubscribe from Data Stream
{
"method": "unsubscribe",
"subscription": {
// Same subscription object used to subscribe
}
}
Server → Client Messages
Subscription Confirmation
{
"channel": "subscriptionResponse",
"data": {
"method": "subscribe",
"subscription": {
// Echoed subscription details
}
}
}
Error Messages
{
"channel": "error",
"data": "Descriptive error message"
}
Common errors:
"Invalid subscription: coin not found"
- Unsupported trading pair"Invalid subscription: n_levels too high"
- Exceeds 100 level limit"Already subscribed"
- Duplicate subscription attempt"Order book not ready"
- Server still initializing
Subscription Types
1. Trades Stream
Real-time trade executions for a specific coin.
Subscribe
{
"type": "trades",
"coin": "BTC"
}
Response Stream
{
"channel": "trades",
"data": [
{
"coin": "BTC",
"side": "A", // "A" = Ask (sell), "B" = Bid (buy)
"px": "106296.0", // Execution price
"sz": "0.00017", // Trade size
"time": 1751430933565, // Unix timestamp (ms)
"hash": "0xde93a8a0...", // Transaction hash
"tid": 293353986402527, // Trade ID
"users": [
"0xcc0a3b6e...", // Buyer address
"0xc64cc00b..." // Seller address
]
}
]
}
2. L2 Order Book
Level 2 order book with price level aggregation.
Subscribe
{
"type": "l2Book",
"coin": "BTC",
"nSigFigs": 3, // Optional: 2-5, price aggregation
"nLevels": 50, // Optional: 1-100, default 20
"mantissa": 5 // Optional: 2 or 5, requires nSigFigs=5
}
Response Stream
{
"channel": "l2Book",
"data": {
"coin": "BTC",
"time": 1751427259657,
"levels": [
[ // Bid levels [price, size, order count]
{"px": "106217.0", "sz": "0.001", "n": 1},
{"px": "106215.0", "sz": "0.001", "n": 1},
{"px": "106213.0", "sz": "0.27739", "n": 1}
],
[ // Ask levels
{"px": "106233.0", "sz": "0.26739", "n": 3},
{"px": "106258.0", "sz": "0.001", "n": 1},
{"px": "106270.0", "sz": "0.49128", "n": 2}
]
]
}
}
3. L4 Order Book
Level 4 order book with individual order visibility - the most detailed market microstructure data available.
Subscribe
{
"type": "l4Book",
"coin": "BTC"
}
Initial Snapshot
{
"channel": "l4Book",
"data": {
"coin": "BTC",
"time": 1751427259657,
"height": 123456,
"levels": [
[ // Bid orders (individual)
{
"user": "0xcc0a3b6e...",
"coin": "BTC",
"side": "B",
"limitPx": "106200.0",
"sz": "0.5",
"oid": 12345678,
"timestamp": 1751427259657,
"triggerCondition": "",
"isTrigger": false,
"triggerPx": "",
"isPositionTpsl": false,
"reduceOnly": false,
"orderType": "limit",
"tif": "GTC",
"cloid": null
}
],
[ // Ask orders (individual)
// Individual ask order objects
]
]
}
}
Incremental Updates
{
"channel": "l4Book",
"data": {
"time": 1751427259657,
"height": 123457,
"orderStatuses": [
// Order status changes (fills, cancellations)
],
"bookDiffs": [
// Order book modifications (new, update, remove)
]
}
}
Implementation Examples
Python: Market Making Bot
import json
import asyncio
import websockets
from decimal import Decimal
class MarketMaker:
def __init__(self, uri, coin):
self.uri = uri
self.coin = coin
self.best_bid = None
self.best_ask = None
async def start(self):
async with websockets.connect(self.uri) as ws:
# Subscribe to L2 book
await ws.send(json.dumps({
"method": "subscribe",
"subscription": {
"type": "l2Book",
"coin": self.coin,
"nLevels": 10
}
}))
async for message in ws:
await self.handle_message(json.loads(message))
async def handle_message(self, msg):
if msg["channel"] == "l2Book":
data = msg["data"]
bids = data["levels"][0]
asks = data["levels"][1]
if bids and asks:
self.best_bid = Decimal(bids[0]["px"])
self.best_ask = Decimal(asks[0]["px"])
spread = self.best_ask - self.best_bid
# Market making logic
if spread > Decimal("2"):
await self.place_orders()
async def place_orders(self):
# Implement order placement logic
print(f"Placing orders: Bid {self.best_bid + 1}, Ask {self.best_ask - 1}")
# Run market maker
maker = MarketMaker("wss://your-instance.dwellir.com/ws", "ETH")
asyncio.run(maker.start())
JavaScript: Trade Analytics
const WebSocket = require('ws');
class TradeAnalytics {
constructor(uri, coins) {
this.uri = uri;
this.coins = coins;
this.volumeTracker = {};
this.vwapTracker = {};
}
connect() {
this.ws = new WebSocket(this.uri);
this.ws.on('open', () => {
// Subscribe to trades for multiple coins
this.coins.forEach(coin => {
this.ws.send(JSON.stringify({
method: 'subscribe',
subscription: { type: 'trades', coin }
}));
this.volumeTracker[coin] = 0;
this.vwapTracker[coin] = { volume: 0, value: 0 };
});
});
this.ws.on('message', (data) => {
const msg = JSON.parse(data);
if (msg.channel === 'trades') {
this.processTrades(msg.data);
}
});
}
processTrades(trades) {
trades.forEach(trade => {
const coin = trade.coin;
const size = parseFloat(trade.sz);
const price = parseFloat(trade.px);
// Update volume
this.volumeTracker[coin] += size;
// Update VWAP
this.vwapTracker[coin].volume += size;
this.vwapTracker[coin].value += size * price;
const vwap = this.vwapTracker[coin].value / this.vwapTracker[coin].volume;
console.log(`${coin} - Volume: ${this.volumeTracker[coin].toFixed(4)}, VWAP: ${vwap.toFixed(2)}`);
});
}
}
// Initialize analytics
const analytics = new TradeAnalytics(
'wss://your-instance.dwellir.com/ws',
['BTC', 'ETH', 'SOL']
);
analytics.connect();
TypeScript: Order Book Imbalance
interface L2Level {
px: string;
sz: string;
n: number;
}
interface OrderBookData {
coin: string;
time: number;
levels: [L2Level[], L2Level[]]; // [bids, asks]
}
class OrderBookImbalance {
private ws: WebSocket;
private imbalanceThreshold = 0.7;
constructor(private uri: string) {}
async connect(): Promise<void> {
this.ws = new WebSocket(this.uri);
this.ws.onopen = () => {
this.subscribe('BTC', 50);
};
this.ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.channel === 'l2Book') {
this.calculateImbalance(msg.data);
}
};
}
private subscribe(coin: string, levels: number): void {
this.ws.send(JSON.stringify({
method: 'subscribe',
subscription: {
type: 'l2Book',
coin,
nLevels: levels
}
}));
}
private calculateImbalance(data: OrderBookData): void {
const bidVolume = this.sumVolume(data.levels[0]);
const askVolume = this.sumVolume(data.levels[1]);
const totalVolume = bidVolume + askVolume;
if (totalVolume > 0) {
const imbalance = bidVolume / totalVolume;
if (imbalance > this.imbalanceThreshold) {
console.log(`BUY PRESSURE: ${(imbalance * 100).toFixed(2)}% bid volume`);
} else if (imbalance < (1 - this.imbalanceThreshold)) {
console.log(`SELL PRESSURE: ${((1 - imbalance) * 100).toFixed(2)}% ask volume`);
}
}
}
private sumVolume(levels: L2Level[]): number {
return levels.reduce((sum, level) => sum + parseFloat(level.sz), 0);
}
}
Performance & Technical Specifications
Latency Characteristics
Based on real-world benchmarking of 2,662 matched trades:
Metric | Public API | Dwellir WebSocket | Improvement |
---|---|---|---|
Mean Latency | 367.60ms | 338.88ms | 28.72ms faster (8.5%) |
Median Latency | 263.00ms | 212.00ms | 51.00ms faster (24.1%) |
Min Latency | 90.00ms | 77.00ms | 13.00ms faster (16.9%) |
Max Latency | 9,118.00ms | 1,977.00ms | 7,141.00ms faster (361.2%) |
Performance Victory Rate
In head-to-head comparison:
- WebSocket has lower latency: 75.5% (2,010 out of 2,662 trades)
The WebSocket server delivers data faster in 3 out of 4 cases, with significantly more consistent performance and protection against extreme latency spikes.
Throughput Capabilities
- Message Rate: Handles thousands of updates per second
- Concurrent Subscriptions: Multiple coins and data types per connection
- Compression: Levels 0-9 configurable for bandwidth optimization
- Connection Limit: Contact for dedicated capacity requirements
Data Guarantees
- Ordering: Updates delivered in blockchain order
- Consistency: Block-level atomicity for state changes
- Reliability: Automatic reconnection with state recovery
- Completeness: No dropped messages under normal conditions
Use Cases
High-Frequency Trading
- Direct L4 book access for optimal order placement
- Minimal latency for arbitrage opportunities
- Full market depth visibility for advanced strategies
Market Making
- Real-time spread monitoring and adjustment
- Order book imbalance detection
- Individual order tracking via L4 data
- Inventory management with position tracking
Analytics & Research
- Complete trade history streaming
- Order flow analysis and toxicity detection
- Market microstructure studies
- Volume and liquidity profiling
Risk Management
- Real-time position monitoring
- Liquidity assessment for large orders
- Market impact modeling
- Volatility tracking and alerts
Best Practices
Connection Management
import asyncio
import websockets
import logging
class ResilientWebSocket:
def __init__(self, uri):
self.uri = uri
self.reconnect_delay = 5
async def connect_with_retry(self):
while True:
try:
async with websockets.connect(self.uri) as ws:
logging.info("Connected to WebSocket")
await self.handle_connection(ws)
except Exception as e:
logging.error(f"Connection error: {e}")
await asyncio.sleep(self.reconnect_delay)
async def handle_connection(self, ws):
# Your message handling logic here
pass
Rate Limiting & Throttling
- Batch subscription requests when connecting
- Implement exponential backoff for reconnections
- Monitor message queue depth to detect backpressure
Data Processing
- Use separate threads/processes for heavy computations
- Implement ring buffers for high-frequency updates
- Consider using binary protocols for internal distribution
Get Started with Dwellir
Hosted WebSocket Service
Dwellir offers production-ready WebSocket servers with:
✅ Direct node connectivity - Fastest possible data access
✅ Geographic distribution - Servers in key trading locations
✅ 99.99% uptime SLA - Enterprise reliability
✅ Dedicated support - Direct access to engineering team
✅ Custom configurations - Tailored to your requirements
Contact Us
Ready to integrate ultra-low latency Hyperliquid data into your trading systems?
📧 Email: ben@dwellir.com
🌐 Website: dwellir.com
📊 Dashboard: dashboard.dwellir.com
Get in touch for:
- API credentials and server endpoints
- Custom data requirements
- Enterprise pricing
- Technical integration support
- Performance benchmarks for your use case
Open Source
For self-hosting options and implementation details, see the Hyperliquid Order Book Server repository.
Access institutional-grade Hyperliquid market data with Dwellir's ultra-low latency WebSocket infrastructure. Contact us → to get started.