Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tiagosiebler/bitmart-api/llms.txt

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

The BitMart SDK streams all futures WebSocket data through a single WebsocketClient. Public topics — ticker, order book depth, kline candlesticks, and trades — connect automatically without credentials. Private topics (orders, positions, and asset balances) require your API key, secret, and memo. All futures topics use the 'futures' market identifier in subscribe() and data arrives on the 'update' event. The client connects to the V2 futures WebSocket endpoint by default, which also supports a demo trading environment.
Futures symbols use no underscore separator. Use BTCUSDT, ETHUSDT, etc. — not BTC_USDT. This is different from the spot market format.

Setup

import { WebsocketClient } from 'bitmart-api';

const client = new WebsocketClient();

client.on('update', (data) => {
  console.log('Received:', JSON.stringify(data));
});

client.on('response', (data) => {
  console.log('Response:', data);
});

client.on('exception', (data) => {
  console.error('Exception:', data);
});

Public Futures Topics

Public topics provide live market data and do not require authentication.

Topic Reference

Topic formatDescription
futures/tickerAll futures tickers — best bid/ask and 24 h stats for every contract
futures/depth5:{symbol}Order book snapshot — top 5 bid and ask levels
futures/depth20:{symbol}Order book snapshot — top 20 bid and ask levels
futures/depth50:{symbol}Order book snapshot — top 50 bid and ask levels
futures/trade:{symbol}Real-time executed trade feed
futures/klineBin1m:{symbol}1-minute candlestick (OHLCV)
futures/klineBin3m:{symbol}3-minute candlestick
futures/klineBin5m:{symbol}5-minute candlestick
futures/klineBin15m:{symbol}15-minute candlestick
futures/klineBin30m:{symbol}30-minute candlestick
futures/klineBin1h:{symbol}1-hour candlestick
futures/klineBin2h:{symbol}2-hour candlestick
futures/klineBin4h:{symbol}4-hour candlestick
futures/klineBin1d:{symbol}1-day candlestick
futures/klineBin1w:{symbol}1-week candlestick

Ticker

The futures/ticker topic streams data for all contracts simultaneously — no symbol suffix is required.
client.subscribe('futures/ticker', 'futures');

Order Book Depth

client.subscribe('futures/depth5:BTCUSDT', 'futures');

Trades

client.subscribe('futures/trade:BTCUSDT', 'futures');

Kline / Candlestick

Futures kline topics use the klineBin prefix and lowercase interval suffixes. Multiple symbols and intervals can be batched into a single subscribe() call, which is more efficient than separate calls.
// 1-minute candles for BTCUSDT
client.subscribe('futures/klineBin1m:BTCUSDT', 'futures');
Available intervals
Topic suffixInterval
klineBin1m1 minute
klineBin3m3 minutes
klineBin5m5 minutes
klineBin15m15 minutes
klineBin30m30 minutes
klineBin1h1 hour
klineBin2h2 hours
klineBin4h4 hours
klineBin1d1 day
klineBin1w1 week

Private Futures Topics

Private topics deliver account-level updates. The WebsocketClient authenticates the private connection automatically when credentials are provided — no manual login step is required.
Private topics require apiKey, apiSecret, and apiMemo to be set in the WebsocketClient constructor. Without them, subscriptions to private topics will not deliver data.

Topic Reference

Topic formatDescription
futures/orderAll order events: new, cancelled, partially filled, filled
futures/positionAll position updates across all contracts
futures/asset:{currency}Asset/balance update for a specific settlement currency
futures/order and futures/position topics do not take a symbol suffix — they deliver events for all contracts on the account. To filter by contract, inspect the symbol field in the received message data.

Order Updates

import { WebsocketClient } from 'bitmart-api';

const client = new WebsocketClient({
  apiKey: process.env.API_KEY!,
  apiSecret: process.env.API_SECRET!,
  apiMemo: process.env.API_MEMO!,
});

client.on('update', (data) => {
  if (data.group === 'futures/order') {
    console.log('Futures order update:', JSON.stringify(data.data));
  }
});

client.subscribe('futures/order', 'futures');

Position Updates

client.subscribe('futures/position', 'futures');

Asset / Balance Updates

Subscribe to balance changes for one or more settlement currencies. Multiple currencies can be batched in a single call.
client.subscribe('futures/asset:USDT', 'futures');

Demo Trading Environment

BitMart provides a simulated trading environment for futures. Set demoTrading: true when constructing the WebsocketClient to connect to the demo WebSocket endpoint (wss://openapi-wsdemo-v2.bitmart.com). API keys are shared between production and demo environments.
import { WebsocketClient } from 'bitmart-api';

const client = new WebsocketClient({
  apiKey: process.env.API_KEY!,
  apiSecret: process.env.API_SECRET!,
  apiMemo: process.env.API_MEMO!,
  demoTrading: true, // connect to simulated trading environment
});

client.on('open', (data) => {
  console.log('Demo WebSocket connected:', data?.wsKey);
});

client.on('authenticated', (data) => {
  console.log('Demo connection authenticated:', data?.wsKey);
});

client.on('update', (data) => {
  console.log('Demo update:', JSON.stringify(data));
});

// Public topics work in demo too
client.subscribe('futures/ticker', 'futures');

// Private topics in demo
client.subscribe(
  ['futures/asset:USDT', 'futures/order', 'futures/position'],
  'futures',
);
The demoTrading flag only affects the V2 futures WebSocket endpoints. Spot WebSocket connections are not affected and do not have a demo environment.

Handling the update Event

All incoming messages emit on the single 'update' event. Inspect data.group (or data.table depending on message type) to identify the originating topic and fan out to the appropriate handler.
import { WebsocketClient } from 'bitmart-api';

const client = new WebsocketClient({
  apiKey: process.env.API_KEY!,
  apiSecret: process.env.API_SECRET!,
  apiMemo: process.env.API_MEMO!,
});

client.on('update', (data) => {
  const topic: string = data.group ?? data.table ?? '';

  if (topic.startsWith('futures/klineBin')) {
    console.log('Kline update:', data.data);
    return;
  }

  switch (topic) {
    case 'futures/ticker':
      console.log('Ticker update:', data.data);
      break;
    case 'futures/depth5':
    case 'futures/depth20':
    case 'futures/depth50':
      console.log('Depth update:', data.data);
      break;
    case 'futures/trade':
      console.log('Trade update:', data.data);
      break;
    case 'futures/order':
      console.log('Order update:', data.data);
      break;
    case 'futures/position':
      console.log('Position update:', data.data);
      break;
    case 'futures/asset':
      console.log('Asset update:', data.data);
      break;
    default:
      console.log('Unhandled topic:', topic, data);
  }
});

// Mix of public and private topics
client.subscribe(
  [
    'futures/ticker',
    'futures/depth20:BTCUSDT',
    'futures/trade:BTCUSDT',
    'futures/klineBin1m:BTCUSDT',
    'futures/klineBin1h:BTCUSDT',
  ],
  'futures',
);

client.subscribe(
  ['futures/order', 'futures/position', 'futures/asset:USDT'],
  'futures',
);

Unsubscribing

Pass the same topic strings and 'futures' market to unsubscribe(). Unsubscribed topics are removed from the internal cache and won’t be re-subscribed after a reconnect.
// Single topic
client.unsubscribe('futures/ticker', 'futures');

// Multiple topics at once
client.unsubscribe(
  ['futures/klineBin1m:BTCUSDT', 'futures/depth5:BTCUSDT'],
  'futures',
);

Connection Events

EventWhen it fires
openWebSocket connection established
authenticatedPrivate connection successfully authenticated
responseServer acknowledgement of a subscribe/unsubscribe request
updateMarket data or account data received
reconnectConnection lost, attempting to reconnect
reconnectedReconnect successful (topics re-subscribed automatically)
closeConnection closed
exceptionAn error occurred
client.on('open', (data) => console.log('Connected:', data?.wsKey));
client.on('authenticated', (data) => console.log('Authenticated:', data?.wsKey));
client.on('reconnect', (data) => console.log('Reconnecting...', data));
client.on('reconnected', (data) => console.log('Reconnected:', data));
client.on('close', (data) => console.error('Closed:', data));
client.on('exception', (data) => console.error('Error:', data));

Build docs developers (and LLMs) love