Skip to main content

Ticker Stream

Get 24-hour statistics updated every 200ms.
{
  "method": "subscribe",
  "subscription": [{
    "type": "ticker",
    "symbol": "BTC-USD"
  }]
}
Update Frequency: Every 200ms

Candles Stream

Real-time candlestick data with historical backfill.
{
  "method": "subscribe",
  "subscription": [{
    "type": "candle",
    "symbol": "BTC-USD",
    "interval": "1m"
  }]
}
Supported Intervals: 10s, 1m, 5m, 15m, 1h, 4h, 1d Initial Response: Up to 5000 historical candles Updates: Interval Based

Trades Stream

Real-time trades feed
{
  "method": "subscribe",
  "subscription": [{
    "type": "trades",
    "symbol": "BTC-USD"
  }]
}
Initial Response: None (stateless) Updates: Real-time on every fill Trade Fields:
FieldDescription
sSymbol
pxExecution price
szSize traded
timeTimestamp (milliseconds)
sidetrue if taker bought, false if sold
makerMaker public key (base58)
takerTaker public key (base58)
liqLiquidation flag (optional)

L2 Snapshot Stream

Periodic full order book snapshots.
{
  "method": "subscribe",
  "subscription": [{
    "type": "l2Snapshot",
    "symbol": "BTC-USD",
    "nlevels": 10,
    "aggregation": 0.5
  }]
}
Parameters:
  • nlevels (optional): Number of price levels per side
  • aggregation (optional): Price bucket size in quote currency
Update Frequency: Every 200ms Structure: levels[0] = bids (descending), levels[1] = asks (ascending)

L2 Delta Stream

Real-time incremental order book updates with initial snapshot.
L2 Delta sends an initial snapshot (latest cached book state) on subscription, then real-time delta updates for every price level change.
{
  "method": "subscribe",
  "subscription": [{
    "type": "l2Delta",
    "symbol": "BTC-USD"
  }]
}
Initial Response: Latest cached book state (if available) Updates: Real-time on every price level change Delta Format:
  • Each delta update contains changes to a single price level
  • Only ONE side (bids or asks) will have levels per update (the other is empty [])
  • levels[0] = bids (highest to lowest)
  • levels[1] = asks (lowest to highest)
  • Each level: {px, sz, n} where n is always 0 for deltas
  • sz: 0 means remove the level

Risk Metrics Stream

Subscribe to coin-based risk metrics including lambda surfaces, leverage curves, and power-law coefficients used for risk calculations.
{
  "method": "subscribe",
  "subscription": [{
    "type": "risk",
    "symbol": "BTC-USD"
  }]
}
Initial Response: Latest cached risk metrics (if available) Updates: Event-driven (only when asset risk changes) Risk Metrics Fields:
FieldDescription
symbolMarket symbol
timestampTimestamp in milliseconds
regimeRisk regime index (-4 to 4)
leverageArray of leverage knot points
lambdaBuyLambda values for buy side at each leverage point
lambdaSellLambda values for sell side at each leverage point
buyCoefAPower-law coefficient a for buy side (λ = a × leverage^b)
buyCoefBPower-law coefficient b for buy side
sellCoefAPower-law coefficient a for sell side
sellCoefBPower-law coefficient b for sell side

Frontend Context Stream

Aggregated market context for all symbols. Ideal for dashboard views.
{
  "method": "subscribe",
  "subscription": [{
    "type": "frontendContext"
  }]
}
Initial Response: Latest cached ticker data for all symbols Updates: Every 2 seconds Context Fields:
FieldDescription
symbolMarket symbol
volume24h trading volume (base currency)
fundingCurrent funding rate
oiOpen interest (base currency)
lastPriceLast traded price
priceChange24h price change (absolute)
priceChangePercent24h price change (percentage)

Multiple Subscriptions

Subscribe to multiple streams at once:
{
  "method": "subscribe",
  "subscription": [
    {"type": "ticker", "symbol": "BTC-USD"},
    {"type": "trades", "symbol": "BTC-USD"},
    {"type": "candle", "symbol": "BTC-USD", "interval": "1m"},
    {"type": "l2Snapshot", "symbol": "BTC-USD", "nlevels": 20},
    {"type": "l2Delta", "symbol": "BTC-USD"},
    {"type": "risk", "symbol": "BTC-USD"},
    {"type": "frontendContext"}
  ]
}
Response:
{
  "type": "subscriptionResponse",
  "topics": [
    "ticker.BTC-USD",
    "trades.BTC-USD",
    "candle.BTC-USD.1m",
    "l2snapshot.BTC-USD",
    "l2delta.BTC-USD",
    "risk.BTC-USD",
    "frontendContext"
  ]
}

Example Implementation

const WebSocket = require('ws');

const ws = new WebSocket('wss://exchange-wss.bulk.trade');

ws.on('open', () => {
  console.log('Connected to Bulk Exchange');
  
  // Subscribe to multiple streams
  ws.send(JSON.stringify({
    method: 'subscribe',
    subscription: [
      { type: 'ticker', symbol: 'BTC-USD' },
      { type: 'trades', symbol: 'BTC-USD' },
      { type: 'frontendContext' }
    ]
  }));
});

ws.on('message', (data) => {
  const message = JSON.parse(data);
  
  if (message.type === 'subscriptionResponse') {
    console.log('Subscribed to:', message.topics);
    return;
  }
  
  switch(message.type) {
    case 'ticker':
      console.log('Ticker:', message.data.ticker);
      break;
    case 'trades':
      console.log('Trade:', message.data.trades);
      break;
    case 'frontendContext':
      console.log('Context:', message.data.ctx);
      break;
  }
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error);
});