Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

WebSocket

Real-time market data and user event streaming via WebSocket.

Subscription Types

TypeDataAuth
tradesReal-time tradesNo
l2BookOrder book updatesNo
bboBest bid/offerNo
candleCandlestick updatesNo
allMidsAll mid pricesNo
activeAssetCtxAsset context (funding, OI)No
userEventsUser fills, liquidationsYes
userFillsUser trade fillsYes
userFundingsUser funding paymentsYes
orderUpdatesOrder status changesYes
notificationSystem notificationsYes
webData2Extended web dataYes
activeAssetDataUser asset data (leverage, margin)Yes

Protocol Details

Connection

wss://api.hyperliquid.xyz/ws     (mainnet)
wss://api.hyperliquid-testnet.xyz/ws  (testnet)

Ping/Pong

Hyperliquid uses app-level ping/pong (not WebSocket protocol-level):

  • Server sends: Ping (plain text)
  • Client must respond: {"method":"pong"}
  • Timeout: ~30 seconds without pong → disconnect

Subscribe

{"method":"subscribe","subscription":{"type":"trades","coin":"BTC"}}

Unsubscribe

{"method":"unsubscribe","subscription":{"type":"trades","coin":"BTC"}}

Message Format

All messages arrive as JSON with a channel wrapper:

{"channel":"trades","data":[{"coin":"BTC","side":"B","px":"97432.5","sz":"0.1","time":1234567890}]}

The SDK's ws_types.extractData() strips the outer wrapper — decode functions receive the data value directly.

SDK Usage

const Ws = hlz.hypercore.ws;
 
// The WS module provides subscription type definitions
// Actual WebSocket connection is managed by the terminal/CLI layer
// using websocket.zig for the transport

Thread Safety

  • WebSocket reads are blocking — run in a dedicated thread
  • Use shutdown(fd) to break out of a blocking read (for coin/interval switches)
  • Do not use SO_RCVTIMEO with TLS on macOS (causes segfaults)
  • Parse messages outside the lock, apply results under the lock