Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tiagosiebler/binance/llms.txt

Use this file to discover all available pages before exploring further.

When beautify: true is enabled, the formattedMessage and formattedUserDataMessage events emit values typed as the large union WsFormattedMessage or WsUserDataEvents. Each of those unions can represent dozens of different event shapes — klines, tickers, order updates, margin calls, and more. TypeScript’s type guard functions let you narrow from a broad union down to a single specific interface, enabling full type inference and autocomplete for each event’s fields. Without type guards you would need to manually inspect data.eventType and cast. With type guards, TypeScript narrows the type automatically in the if branch:
wsClient.on('formattedMessage', (data) => {
  // data: WsFormattedMessage (broad union)
  if (isWsFormattedKline(data)) {
    // data: WsMessageKlineFormatted (narrow — all kline fields available)
    console.log(data.kline.close); // ✅ typed as number
  }
});
All type guard functions are exported from the 'binance' package root. Import them alongside your event types.

How Type Guards Work

Each guard function follows the TypeScript type predicate pattern (data: WsFormattedMessage) => data is SpecificType. When the function returns true, TypeScript narrows data to the specific interface inside the if block. All guards take a WsFormattedMessage (or WsRawMessage for raw guards) as input and perform a lightweight runtime check — typically checking Array.isArray(data) and matching the eventType string.
import {
  isWsFormattedKline,
  type WsFormattedMessage,
  type WsMessageKlineFormatted,
} from 'binance';

function handleMessage(data: WsFormattedMessage) {
  if (isWsFormattedKline(data)) {
    // TypeScript now knows: data is WsMessageKlineFormatted
    const { symbol, kline } = data;
    console.log(symbol, kline.open, kline.close, kline.isFinal);
  }
}

Formatted Message Type Guards

These guards operate on WsFormattedMessage — the type emitted by the formattedMessage event.

Market Data Guards

FunctionNarrows ToMatches eventType
isWsFormattedKline(data)WsMessageKlineFormatted'kline'
isWsFormattedTrade(data)WsMessageTradeFormatted'trade'
isWsAggTradeFormatted(data)WsMessageAggTradeFormatted'aggTrade'
isWsFormatted24hrTicker(data)WsMessage24hrTickerFormatted'24hrTicker' (single symbol)
isWsFormatted24hrTickerArray(data)WsMessage24hrTickerFormatted[]Array of '24hrTicker' events
isWsFormattedRollingWindowTickerArray(data)WsMessage24hrTickerFormatted[]Array of rolling window ticker events ('1hTicker', '4hTicker', '1dTicker')
isWsFormattedMarkPriceUpdateEvent(data)WsMessageMarkPriceEventFormatted'markPriceUpdate' (single symbol)
isWsFormattedMarkPriceUpdateArray(data)WsMessageMarkPriceEventFormatted[]Array of 'markPriceUpdate' or 'markPrice' events
isWsFormattedForceOrder(data)WsMessageForceOrderFormatted'forceOrder' (liquidation)
isWsPartialBookDepthEventFormatted(data)WsMessagePartialBookDepthEventFormatted'partialBookDepth' and depth snapshot variants
isWsDiffBookDepthEventFormatted(data)WsMessageDiffBookDepthEventFormatted'depthUpdate'
isWsFormatted24hrTickerArray is deprecated — the !ticker@arr stream was deprecated by Binance on 2025-11-14 and will be retired on 2026-03-26. Use isWsFormatted24hrTicker with per-symbol subscriptions, or isWsFormattedRollingWindowTickerArray with !miniTicker@arr instead.

Deprecated Mark Price Guard

FunctionStatusReplacement
isWsFormattedMarkPriceUpdate(data)@deprecatedUse isWsFormattedMarkPriceUpdateEvent or isWsFormattedMarkPriceUpdateArray

User Data Type Guards

These guards narrow WsFormattedMessage or WsUserDataEvents to specific user data event shapes. They are most useful in formattedUserDataMessage handlers.

Top-Level User Data Guards

FunctionNarrows ToDescription
isWsFormattedUserDataEvent(data)WsUserDataEventsMatches any user data event — works for both listen-key and WS API user data streams.
isWsFormattedSpotUserDataEvent(data)WsMessageSpotUserDataEventFormattedMatches any Spot/Margin user data event.
isWsFormattedFuturesUserDataEvent(data)WsMessageFuturesUserDataEventFormattedMatches any USD-M Futures user data event.

Spot User Data Guards

FunctionNarrows ToeventType
isWsFormattedSpotUserDataExecutionReport(data)WsMessageSpotUserDataExecutionReportEventFormatted'executionReport'
isWsFormattedSpotOutboundAccountPosition(data)WsMessageSpotOutboundAccountPositionFormatted'outboundAccountPosition'
isWsFormattedSpotBalanceUpdate(data)WsMessageSpotBalanceUpdateFormatted'balanceUpdate'
isWsFormattedSpotUserDataListStatusEvent(data)WsMessageSpotUserDataListStatusEventFormatted'listStatus'

Futures User Data Guards

FunctionNarrows ToeventType
isWsFormattedFuturesUserDataAccountUpdate(data)WsMessageFuturesUserDataAccountUpdateFormatted'ACCOUNT_UPDATE'
isWsFormattedFuturesUserDataTradeUpdateEvent(data)WsMessageFuturesUserDataTradeUpdateEventFormatted'ORDER_TRADE_UPDATE'
isWsFormattedFuturesUserDataMarginCall(data)WsMessageFuturesUserDataMarginCallFormatted'MARGIN_CALL'
isWsFormattedFuturesAlgoUpdateEvent(data)WsMessageFuturesUserDataAlgoUpdateFormatted'ALGO_UPDATE'
isWsFormattedFuturesUserDataCondOrderTriggerRejectEvent(data)WsMessageFuturesUserDataCondOrderTriggerRejectEventFormatted'CONDITIONAL_ORDER_TRIGGER_REJECT'
isWsFormattedFuturesUserDataAccountConfigUpdateEvent(data)WsMessageFuturesUserDataAccountConfigUpdateEventFormatted'ACCOUNT_CONFIG_UPDATE'
isWsFormattedFuturesUserDataListenKeyExpired(data)WsMessageFuturesUserDataListenKeyExpiredFormatted'listenKeyExpired'

Connection Context Guards

These helpers check which product group a connection belongs to rather than narrowing a specific event type. Useful for routing logic when you have a single handler for multiple wsKey connections.
FunctionReturnsDescription
isWsSpotConnection(data)booleanReturns true if the event originated from a Spot/Margin connection.
isWsFuturesConnection(data)booleanReturns true if the event originated from a USD-M or COIN-M Futures connection.
isWSAPIWsKey(wsKey)wsKey is WSAPIWsKeyNarrows a WsKey to WSAPIWsKey — confirms the key is a WS API connection, not a stream connection.

Raw Message Type Guards

These guards operate on WsRawMessage — the unbeautified event type from the message event. They check Binance’s abbreviated event fields (e.g. data.e instead of data.eventType).
FunctionNarrows ToChecks
isAll24hrMiniTickerRaw(data)WsMessage24hrMiniTickerRaw[]Array where data[0].e === '24hrMiniTicker'
isAllRollingWindowTickerRaw(data)WsMessageRollingWindowTickerRaw[]Array where data[0].e is '1hTicker', '4hTicker', or '1dTicker'
is24hrMiniTickerRaw(data)WsMessage24hrMiniTickerRawSingle event: data.e === '24hrMiniTicker'
isKlineRaw(data)WsMessageKlineRawSingle event: data.e === 'kline'
isOrderTradeUpdateRaw(data)WsMessageFuturesUserDataOrderTradeUpdateEventRawSingle event: data.e === 'ORDER_TRADE_UPDATE'
isAlgoUpdateRaw(data)WsMessageFuturesUserDataAlgoUpdateRawSingle event: data.e === 'ALGO_UPDATE'
isAccountConfigUpdateRaw(data)WsMessageFuturesUserDataAccountConfigUpdateEventRawSingle event: data.e === 'ACCOUNT_CONFIG_UPDATE'
isAccountUpdateRaw(data)WsMessageFuturesUserDataAccountUpdateRawSingle event: data.e === 'ACCOUNT_UPDATE'
isWsEventStreamTerminatedRaw(data)WsEventStreamTerminatedRawSingle event: data.e === 'eventStreamTerminated'

Complete Example: formattedMessage Handler

The following example demonstrates a production-style handler that uses multiple type guards to route every event to a typed sub-handler.
import {
  WebsocketClient,
  isWsFormattedKline,
  isWsAggTradeFormatted,
  isWsFormattedTrade,
  isWsFormatted24hrTicker,
  isWsFormattedRollingWindowTickerArray,
  isWsFormattedMarkPriceUpdateEvent,
  isWsFormattedMarkPriceUpdateArray,
  isWsFormattedForceOrder,
  isWsPartialBookDepthEventFormatted,
  isWsDiffBookDepthEventFormatted,
  isWsFormattedUserDataEvent,
  isWsFormattedSpotUserDataExecutionReport,
  isWsFormattedSpotBalanceUpdate,
  isWsFormattedFuturesUserDataAccountUpdate,
  isWsFormattedFuturesUserDataTradeUpdateEvent,
  isWsFormattedFuturesUserDataMarginCall,
  isWsFormattedFuturesAlgoUpdateEvent,
  isWsFormattedFuturesUserDataListenKeyExpired,
} from 'binance';

const wsClient = new WebsocketClient({
  api_key: 'YOUR_API_KEY',
  api_secret: 'YOUR_API_SECRET',
  beautify: true,
});

wsClient.on('formattedMessage', (data) => {
  // --- Market data events ---

  if (isWsFormattedKline(data)) {
    const { symbol, kline } = data;
    console.log(`[Kline] ${symbol} ${kline.interval}: O=${kline.open} H=${kline.high} L=${kline.low} C=${kline.close} V=${kline.volume} final=${kline.final}`);
    return;
  }

  if (isWsAggTradeFormatted(data)) {
    console.log(`[AggTrade] ${data.symbol} price=${data.price} qty=${data.quantity} maker=${data.maker}`);
    return;
  }

  if (isWsFormattedTrade(data)) {
    console.log(`[Trade] ${data.symbol} price=${data.price} qty=${data.quantity}`);
    return;
  }

  if (isWsFormatted24hrTicker(data)) {
    console.log(`[24hrTicker] ${data.symbol} close=${data.closePrice} change=${data.priceChangePercent}%`);
    return;
  }

  if (isWsFormattedRollingWindowTickerArray(data)) {
    for (const ticker of data) {
      console.log(`[RollingTicker] ${ticker.symbol} ${ticker.eventType}`);
    }
    return;
  }

  if (isWsFormattedMarkPriceUpdateEvent(data)) {
    console.log(`[MarkPrice] ${data.symbol} markPrice=${data.markPrice} fundingRate=${data.fundingRate}`);
    return;
  }

  if (isWsFormattedMarkPriceUpdateArray(data)) {
    for (const mp of data) {
      console.log(`[MarkPriceArray] ${mp.symbol} markPrice=${mp.markPrice}`);
    }
    return;
  }

  if (isWsFormattedForceOrder(data)) {
    const { liquidationOrder } = data;
    console.log(`[Liquidation] ${liquidationOrder.symbol} side=${liquidationOrder.side} qty=${liquidationOrder.originalQuantity}`);
    return;
  }

  if (isWsPartialBookDepthEventFormatted(data)) {
    console.log(`[PartialDepth] ${data.symbol} bids=${data.bids.length} asks=${data.asks.length}`);
    return;
  }

  if (isWsDiffBookDepthEventFormatted(data)) {
    console.log(`[DiffDepth] ${data.symbol} finalUpdateId=${data.finalUpdateId}`);
    return;
  }

  // --- User data events (also available via formattedUserDataMessage) ---

  if (isWsFormattedUserDataEvent(data)) {
    if (isWsFormattedSpotUserDataExecutionReport(data)) {
      console.log(`[Spot Order] ${data.symbol} ${data.side} ${data.orderStatus} orderId=${data.orderId}`);
      return;
    }

    if (isWsFormattedSpotBalanceUpdate(data)) {
      console.log(`[Balance Update] asset=${data.asset} delta=${data.balanceDelta}`);
      return;
    }

    if (isWsFormattedFuturesUserDataAccountUpdate(data)) {
      console.log(`[Futures Account Update] reason=${data.updateData.updateType}`);
      return;
    }

    if (isWsFormattedFuturesUserDataTradeUpdateEvent(data)) {
      const { order } = data;
      console.log(`[Futures Order Update] ${order.symbol} status=${order.orderStatus} side=${order.side}`);
      return;
    }

    if (isWsFormattedFuturesUserDataMarginCall(data)) {
      console.log(`[Margin Call] positions at risk: ${data.positions.length}`);
      return;
    }

    if (isWsFormattedFuturesAlgoUpdateEvent(data)) {
      console.log(`[Algo Update] algoId=${data.algoOrder.algoId} status=${data.algoOrder.algoStatus}`);
      return;
    }

    if (isWsFormattedFuturesUserDataListenKeyExpired(data)) {
      console.warn('[Listen Key Expired] reconnecting user data stream...');
      return;
    }
  }
});

// Subscribe to some streams
wsClient.subscribeKlines('BTCUSDT', '1m', 'spot');
wsClient.subscribeMarkPrice('BTCUSDT', 'usdm');
wsClient.subscribeUsdFuturesUserDataStream();
For formattedUserDataMessage-only handlers, you can also use the guards directly without the top-level isWsFormattedUserDataEvent check — the user data event listener already pre-filters to WsUserDataEvents.

Build docs developers (and LLMs) love