Back to Binance JavaScript SDK
SpotFuturesPortfolio MarginMarket Data StreamsUser data StreamsWebSocket API

Binance API JavaScript Tutorial for Node.js and TypeScript

Build Binance API integrations without writing your own request signing, listen-key renewal, WebSocket health checks, reconnect loops, response matching, or endpoint routing.

first-binance-call.ts
public REST API
import { MainClient } from 'binance';

const client = new MainClient();

async function main() {
  const serverTime = await client.getServerTime();
  const exchangeInfo = await client.getExchangeInfo({ symbol: 'BTCUSDT' });
  const ticker = await client.getSymbolPriceTicker({ symbol: 'BTCUSDT' });
  const orderBook = await client.getOrderBook({ symbol: 'BTCUSDT', limit: 10 });
  const candles = await client.getKlines({
    symbol: 'BTCUSDT',
    interval: '1m',
    limit: 5,
  });

  console.log({
    serverTime,
    symbol: exchangeInfo.symbols?.[0]?.symbol,
    ticker,
    orderBook,
    candles,
  });
}

main().catch(console.error);

API surface map

One Binance SDK, all product groups

The Binance JavaScript SDK covers Spot, Margin, Wallet, Futures, Portfolio Margin, WebSockets, and WebSocket API workflows. Pick the client for the product you are using; authentication, async calls, events, and TypeScript types work consistently across the SDK.

Your app

Bot, dashboard, worker, tool

Any Node.js or JavaScript-compatible service that needs to integrate with Binance APIs, including but not limited to market data, account state, or order management.

Binance APIs

Spot, margin, wallet, and account REST APIs

USD-M and COIN-M Futures REST APIs

Portfolio Margin REST APIs

Public streams, user data, and WebSocket APIs

What this tutorial covers

Start with the right Binance API client

The guide starts with public calls, then moves into private account streams, trading commands, environments, reconnects, and the checks you need before production.

Client selection

Map Spot, margin, Futures, Portfolio Margin, streams, and WebSocket API commands to the right SDK client.

Auth and environments

Use HMAC, RSA, or Ed25519 keys, and keep live, demo, and testnet credentials separate.

Streams and user data

Set up public streams, Spot user data, listen-key flows, reconnect handling, and REST API backfills.

Production guardrails

Plan for client order IDs, timestamp windows, rate-limit state, large integers, logging, and staged rollout.

Start building

First REST API calls, streams, user data, and WebSocket API commands, with just a few lines of code.

Run one of these first to verify the client, keys, and stream setup. The full guide below explains the surrounding workflow.

import { MainClient } from 'binance'; const client = new MainClient(); async function main() {  const serverTime = await client.getServerTime();  const exchangeInfo = await client.getExchangeInfo({ symbol: 'BTCUSDT' });  const ticker = await client.getSymbolPriceTicker({ symbol: 'BTCUSDT' });  const orderBook = await client.getOrderBook({ symbol: 'BTCUSDT', limit: 10 });  const candles = await client.getKlines({    symbol: 'BTCUSDT',    interval: '1m',    limit: 5,  });   console.log({    serverTime,    symbol: exchangeInfo.symbols?.[0]?.symbol,    ticker,    orderBook,    candles,  });} main().catch(console.error);

Workflow diagrams

REST API calls, WebSocket streams, and WebSocket API commands behave differently

They can all touch the same account state, but they connect, fail, and recover in different ways. These diagrams show the workflows handled by the Binance JavaScript SDK and the components handled by you.

REST API client routing

Choose the client from the Binance product group first, then add credentials, symbols, and start working on features.

Choose product groupYour code
Instance matching clientYour code
Call SDK methodYour code
Build and sign requestSDK handles
Route request to APISDK handles
Process and respondBinance
Parse response JSONSDK handles
Handle result/exceptionYour code

User data stream recovery

Private streams provide updates on any state changes on your account. After reconnects, use the REST API to verify the state you missed.

subscribeUserDataStream()Your code
Authenticate or create listen keySDK handles
on(formattedUserDataMessage)Event
on(reconnecting)Event
Pause risky actionsYour code
Reconnect and resubscribeSDK handles
Backfill account state over REST APIYour code
Resume processingYour code

WebSocket API command flow

Send lower-latency commands through a persistent WebSocket API connection. Maximum benefit with Ed25519 keys.

Call and await SDK methodYour code
Open WS API connectionSDK handles
Authenticate session or sign requestSDK handles
Send command with request IDSDK handles
Receive response eventEvent
Resolve promiseSDK handles
Handle resultYour code

Production rollout

Before this runs unattended

Stress test your integration with a sandbox or testnet environment, and run it alongside the official Binance UI to compare behavior. Thoroughly test different failure scenarios, including network interruptions, expired listen keys, and API errors, before leaving any integration run unattended.

Keep Live, Demo, Spot testnet, and Futures testnet credentials separate.

Backfill account state (balances, positions, orders, etc) after private stream reconnects.

While MainClient covers many of the primary product groups, other product groups have their own dedicated REST API clients, such as: USDMClient, CoinMClient, and PortfolioClient.

Use the Binance SDK order ID utilities for every Custom Order ID field: prefer generateNewOrderId() for newClientOrderId/clientAlgoId values, and use getOrderIdPrefix() only when building your own random suffix.

Watch timestamp drift, recvWindow behavior, and REST API rate-limit headers before scaling polling.

Prefer Ed25519 keys for latency-sensitive WebSocket API sessions where your account setup supports them.

Find the right section

Start with the part of Binance you are integrating

Browse all examples

Choose the REST API client

Use MainClient for Spot, margin, wallet, and account APIs. Use separate clients for USD-M Futures, COIN-M Futures, and Portfolio Margin.

Read section

Handle account events

Use WebSocket API user data for Spot, and listen-key managed streams where Binance still requires them.

Read section

Use WebSocket API commands

Use WebsocketAPIClient when you want request/response calls over an already-open WebSocket connection.

Read section

Use the Binance SDK across REST APIs, WebSockets, and WebSocket API commands

This tutorial focuses on the paths teams usually need first: Spot, Futures, Portfolio Margin, public streams, private user data, WebSocket API commands, environments, reconnects, and rollout checks.

This guide walks through key pieces of a Binance REST API, WebSocket & WebSocket API integration using binance, the Binance JavaScript and TypeScript SDK by Siebly.io.

The SDK handles request building and connectivity for you, including request signing, WebSocket management, healthchecks, heartbeats, product-specific user data startup, listen-key refreshes where Binance still uses them, resubscribe behavior, and WebSocket API response mapping so your code can stay focused on the workflow you are automating. This guide will walk you through installation and client selection, then moves through public calls, private auth, REST API calls, streams, user data, and the WebSocket API.

Key links


Why use the SDK

A stable Binance integration is more than a handful of HTTP requests. Binance splits behavior across product groups, transports, key types, and environments:

  • Spot, Margin, Wallet, Convert, Earn, and Sub-Account APIs live behind the main REST API client, but not all of them share the same endpoint prefix or permission model.
  • Some of these product groups expect API calls to reach different subdomains.
  • USD-M Futures and COIN-M Futures have separate REST API clients, symbols, endpoint prefixes, and WebSocket endpoints.
  • Both have their own subdomains as well.
  • Portfolio Margin uses a dedicated REST API client and its own account model.
  • Public streams, private user data streams, and WebSocket API commands are different flows.
  • Private REST API and WebSocket API requests must be signed.
  • User data streams can involve listen keys, WebSocket API subscriptions, token refreshes, and reconnect handling.

Most of that work is handled for you, while the grouping & naming stays close to Binance's API naming. The SDK gives you dedicated REST API clients for the major product groups, WebsocketClient for streaming, WebsocketAPIClient for awaitable WebSocket API requests. It also includes TypeScript definitions, ESM/CJS support, proxy support, and optional response beautification.


Install and API keys

If you do not have Node.js installed yet, install it first. The SDK is published to both GitHub and npm, and can therefore be installed with your favourite Node.js compatible package manager.

Install the SDK with npm:

npm install binance

Or use another npm-compatible package manager:

pnpm install binance
yarn add binance

Create API keys from the relevant Binance page:

Always use the minimum permissions needed for your scenario. Trading does not require withdrawal permissions. Analytics does not require trading permissions. Always require strict IP whitelisting for any API keys that you create.

The main auth and environment rules are:

  • Public market data does not require API keys.
  • Private REST APIs require api_key and api_secret.
  • Live, testnet, and demo trading credentials are separate, as they are separate environments.
  • API permissions must match the product and action your code is using.
  • HMAC keys are the common API key + secret flow. These are the "system generated" API keys, selected by default when creating new API keys for Binance.
  • RSA and Ed25519 keys use self-generated private keys.
  • Ed25519 is recommended for latency-sensitive integrations with the WebSocket API, as this enables session-based WebSocket API authentication, instead of having to authenticate every request.

All supported key types use the same SDK constructor shape. The SDK will automatically detect your key type and adjust request building and signing automatically:

const client = new MainClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

For HMAC, api_secret is your Binance API secret. For RSA or Ed25519, api_secret is your PEM private key.

Typical environment variables:

export BINANCE_API_KEY='your-api-key'
export BINANCE_API_SECRET='your-api-secret-or-private-key'

If you are only testing public endpoints, you do not need any keys at all.


Products and clients

Binance is not one single API. The SDK splits API clients around Binance's product groups:

Product groupAPI clientCommon usage
REST API: Spot, Margin, Wallet, Convert, Earn, Sub-accounts, Broker, AlphaMainClientSpot trading, account data, wallet flows, margin trading, transfers, savings/earn, sub-account management
REST API: USD-M FuturesUSDMClientUSDT/USDC margined futures market data, account data, positions, orders
REST API: COIN-M FuturesCoinMClientCoin-margined futures market data, account data, positions, orders
REST API: Portfolio MarginPortfolioClientPortfolio Margin account, UM/CM/margin orders, balances, positions
WebSocket streamsWebsocketClientPublic market data streams and private user data streams
WebSocket APIWebsocketAPIClientREST API-like Spot and Futures commands over persistent WebSocket API connections

As a rule of thumb:

  • Use MainClient when the Binance docs path starts with api/ or sapi/, including Spot and many account/wallet APIs.
  • Use USDMClient when the Binance docs path starts with fapi/.
  • Use CoinMClient when the Binance docs path starts with dapi/.
  • Use PortfolioClient when the Binance docs path starts with papi/.
  • Use WebsocketClient when you want to subscribe to streams and receive events.
  • Use WebsocketAPIClient when you want to send commands over WebSocket and await responses like REST API calls.

For a complete method map, see docs/endpointFunctionList.md. If any endpoints or properties seem to be missing, please open an issue on GitHub and we'll look into it. Targeted PRs are also welcome.

REST API, streams, listen keys, and WebSocket API

Binance uses several related but different integration patterns. It helps to keep them separate:

FlowSDK surfaceBest forWhat the SDK handles
REST APIMainClient, USDMClient, CoinMClient, PortfolioClientRequest/response calls, broad API coverage, occasional reads/writes, fallback reconciliationBase URLs, request signing, timestamps, response parsing, errors
Public WebSocket streamsWebsocketClient.subscribe(...)Live market data such as trades, klines, tickers, order book updatesConnection routing, subscribe requests, heartbeats, reconnects, resubscribe
Listen-key user data streamsWebsocketClient.subscribeUsdFuturesUserDataStream(), subscribeCoinFuturesUserDataStream(), portfolio helpersPrivate account events where Binance still uses listen keys, especially Futures and Portfolio Margin streamsListen-key creation, keepalive, refresh, reconnect, stream teardown
WebSocket API user dataWebsocketAPIClient.subscribeUserDataStream(...)Spot user data and some newer private stream flows without the old Spot listen-key workflowWebSocket API auth, subscription command, reconnect/resubscribe behavior
WebSocket API commandsWebsocketAPIClient methods or WebsocketClient.sendWSAPIRequest(...)Lower-latency request/response commands over an already-open WebSocket, such as order tests, order placement, cancellation, status, account readsWebSocket connection persistence, auth, request IDs, promise resolution, response/error correlation

The WebSocket API uses WebSocket transport for request/response commands such as order tests, order placement, cancellation, status, and account reads. Since much of this surface is a lower-latency alternative to REST, we've introduced the promise-driven WebsocketAPIClient. It lets you call a function, send a command over WS, and await the matched response without managing asynchronous WebSocket messaging or connection lifecycle details yourself.

const result = await wsApi.testSpotOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: '0.001',
  price: '10000',
  timeInForce: 'GTC',
  timestamp: Date.now(),
});

Use the REST API when you want maximum endpoint coverage, simple one-off calls, or reconciliation after reconnects. Use the WebSocket API when you want persistent connectivity, lower request overhead, WebSocket API-only features, or a promise-driven command path that can share the same event-driven architecture as your streams. With Ed25519 keys, authentication can happen once per WebSocket API connection, which can improve latency in mid-to-high frequency systems. Removing repeated authentication work from every request can save time cumulatively.


Start building: first calls

If you only want the fastest path to a working integration, start here.

1. First Spot REST API request

import { MainClient } from 'binance';

const client = new MainClient();

async function main() {
  const serverTime = await client.getServerTime();
  const exchangeInfo = await client.getExchangeInfo({ symbol: 'BTCUSDT' });
  const ticker = await client.getSymbolPriceTicker({ symbol: 'BTCUSDT' });
  const orderBook = await client.getOrderBook({ symbol: 'BTCUSDT', limit: 10 });
  const candles = await client.getKlines({
    symbol: 'BTCUSDT',
    interval: '1m',
    limit: 5,
  });

  console.log({
    serverTime,
    symbol: exchangeInfo.symbols?.[0]?.symbol,
    ticker,
    orderBook,
    candles,
  });
}

main().catch(console.error);

That confirms public Spot REST API access is wired correctly.

See also: Spot public REST API example

2. First public Spot WebSocket stream

import { WebsocketClient, WS_KEY_MAP } from 'binance';

const ws = new WebsocketClient({
  beautify: true,
});

ws.on('open', (data) => console.log('connected', data.wsKey, data.wsUrl));
ws.on('message', (data) => console.log('raw message', JSON.stringify(data)));
ws.on('formattedMessage', (data) => console.log('formatted', data));
ws.on('response', (data) => console.log('response', JSON.stringify(data)));
ws.on('reconnecting', (data) => console.log('reconnecting', data?.wsKey));
ws.on('reconnected', (data) => console.log('reconnected', data?.wsKey));
ws.on('exception', console.error);

ws.subscribe(['btcusdt@trade', 'btcusdt@bookTicker'], WS_KEY_MAP.main);

That gives you a live public Spot stream without any API keys.

See also: Spot trades WebSocket example

3. First private Spot user data stream

For Spot user data streams, prefer the WebSocket API user data flow. It avoids the older Spot listen-key flow and keeps the stream on a managed WebSocket API connection.

import { WebsocketAPIClient, WS_KEY_MAP } from 'binance';

const wsApi = new WebsocketAPIClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  beautify: true,
});

wsApi.getWSClient().on('message', (data) => {
  console.log('on message event: ', data.wsKey);
});

wsApi.getWSClient().on('open', (data) => {
  console.log('ws api open: ', data.wsKey);
});

wsApi.getWSClient().on('formattedUserDataMessage', (data) => {
  console.log('on formattedUserDataMessage: ', data);
});

wsApi.getWSClient().on('exception', console.error);

async function main() {
  await wsApi.subscribeUserDataStream(WS_KEY_MAP.mainWSAPI);
}

main().catch(console.error);

The SDK handles authentication and resubscribe behavior for the WebSocket API connection. With Ed25519 keys it can authenticate the WebSocket API session once. With HMAC or RSA keys it signs private WebSocket API commands individually, although that primarily matters in the context of sending regular commands (such as order submissions) via WebSocket API.

See also: Spot user data stream over WebSocket API

4. First Spot order over REST API

import { MainClient } from 'binance';

const client = new MainClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

async function placeOrder() {
  const orderRequest = {
    symbol: 'BTCUSDT',
    side: 'BUY',
    type: 'LIMIT',
    quantity: 0.001,
    price: 10000,
    timeInForce: 'GTC',
    newOrderRespType: 'FULL',
  } as const;

  // Validate the request without sending it to the matching engine.
  await client.testNewOrder(orderRequest);

  // Remove this comment when you are ready to place a real order.
  // const result = await client.submitNewOrder(orderRequest);
  // console.log(result);
}

placeOrder().catch(console.error);

Use testNewOrder() when you want to validate the request shape and signature without placing a live Spot order. Use submitNewOrder() only when you are ready to send the order.

See also: Spot private trading example

5. First USD-M Futures order

For strategy testing, demoTrading: true is usually more realistic than testnet because demo trading uses live market data with simulated trading.

import { USDMClient } from 'binance';

const client = new USDMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  demoTrading: true,
});

async function placeFuturesOrder() {
  const account = await client.getAccountInformation();
  console.log('demo futures account can trade:', account.canTrade);

  const result = await client.submitNewOrder({
    symbol: 'BTCUSDT',
    side: 'SELL',
    type: 'MARKET',
    quantity: 0.001,
  });

  console.log(result);
}

placeFuturesOrder().catch(console.error);

See also: USD-M Futures demo trading example

6. First WebSocket API request

The WebSocket API lets you send requests over a persistent WebSocket connection and await responses, similar to REST API calls. This is useful for lower-latency workflows and for WebSocket API-only features.

import { WebsocketAPIClient } from 'binance';

const wsApi = new WebsocketAPIClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

async function main() {
  const time = await wsApi.getSpotServerTime();

  const orderTest = await wsApi.testSpotOrder({
    symbol: 'BTCUSDT',
    side: 'BUY',
    type: 'LIMIT',
    quantity: '0.001',
    price: '10000',
    timeInForce: 'GTC',
    timestamp: Date.now(),
  });

  console.log({ time, orderTest });
}

main()
  .catch(console.error)
  .finally(() => wsApi.disconnectAll());

See also: WebSocket API client example


Spot, Margin, and Wallet REST API

Most Binance integrations start with MainClient. It covers Spot trading and many account APIs under Binance's main REST API families.

Create a public MainClient

import { MainClient } from 'binance';

const client = new MainClient();

Public calls do not require keys.

Create a private MainClient

If you plan on making private API calls, include API keys when creating the client:

import { MainClient } from 'binance';

const client = new MainClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  beautifyResponses: true,
});

Private REST API methods are signed automatically. You do not need to manually add timestamps, signatures, or X-MBX-APIKEY headers.

Common public Spot market data calls

const serverTime = await client.getServerTime();
const ping = await client.testConnectivity();
const exchangeInfo = await client.getExchangeInfo({ symbol: 'BTCUSDT' });
const orderBook = await client.getOrderBook({ symbol: 'BTCUSDT', limit: 10 });
const recentTrades = await client.getRecentTrades({
  symbol: 'BTCUSDT',
  limit: 10,
});
const aggregateTrades = await client.getAggregateTrades({
  symbol: 'BTCUSDT',
  limit: 10,
});
const candles = await client.getKlines({
  symbol: 'BTCUSDT',
  interval: '1m',
  limit: 10,
});
const averagePrice = await client.getAvgPrice({ symbol: 'BTCUSDT' });
const ticker = await client.getSymbolPriceTicker({ symbol: 'BTCUSDT' });
const bookTicker = await client.getSymbolOrderBookTicker({
  symbol: 'BTCUSDT',
});

Common private Spot account and order calls

const account = await client.getAccountInformation();
const balances = await client.getBalances();
const accountInfo = await client.getAccountInfo();
const openOrders = await client.getOpenOrders({ symbol: 'BTCUSDT' });
const allOrders = await client.getAllOrders({ symbol: 'BTCUSDT', limit: 10 });
const myTrades = await client.getAccountTradeList({
  symbol: 'BTCUSDT',
  limit: 10,
});
const tradeFee = await client.getTradeFee({ symbol: 'BTCUSDT' });
const apiPermissions = await client.getApiKeyPermissions();

See also:

Spot order examples

Market order:

await client.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'MARKET',
  quantity: 0.001,
  newOrderRespType: 'FULL',
});

Limit order:

await client.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: 0.001,
  price: 10000,
  timeInForce: 'GTC',
});

Limit maker order:

await client.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT_MAKER',
  quantity: 0.001,
  price: 10000,
});

Test an order without sending it:

await client.testNewOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: 0.001,
  price: 10000,
  timeInForce: 'GTC',
});

Cancel an order:

await client.cancelOrder({
  symbol: 'BTCUSDT',
  orderId: 123456789,
});

Custom client order IDs

You do not always need to set a custom client order ID. Most of the time, the cleanest option is to send the order without newClientOrderId or the equivalent custom ID field for that endpoint, and let the SDK handle the request normally:

await client.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'SELL',
  type: 'LIMIT',
  quantity: 0.001,
  price: 13000,
  timeInForce: 'GTC',
});

If your system needs to know the client order ID before the order is sent, but the ID does not need to carry any meaning, ask the REST API client to generate one:

const newClientOrderId = client.generateNewOrderId();

await client.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'SELL',
  type: 'LIMIT',
  quantity: 0.001,
  price: 13000,
  timeInForce: 'GTC',
  newClientOrderId,
});

generateNewOrderId() is available on every REST API client, including MainClient, USDMClient, CoinMClient, and PortfolioClient. The client already knows its product group, so the generated ID uses the right Binance-compatible prefix.

If you want to include a small piece of your own context in the client order ID, such as a take-profit marker or strategy step, use the product prefix from the client and append your suffix:

const prefix = client.getOrderIdPrefix();
const suffix = `tp1_${Date.now()}`;
const newClientOrderId = `${prefix}${suffix}`;
const validBinanceClientOrderId = /^[.A-Z:/a-z0-9_-]{1,32}$/;

if (!validBinanceClientOrderId.test(newClientOrderId)) {
  throw new Error(`Invalid Binance client order ID: ${newClientOrderId}`);
}

await client.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'SELL',
  type: 'LIMIT',
  quantity: 0.001,
  price: 13000,
  timeInForce: 'GTC',
  newClientOrderId,
});

The prefix returned by getOrderIdPrefix() is 10 characters long. For endpoints with Binance's common 32-character client order ID limit, that leaves 22 characters for your own suffix. Keep the suffix short and use only characters Binance allows for that field.

If you need to track richer metadata than will comfortably fit in the client order ID, do not try to squeeze it into these custom order ID fields. Instead, generate an ID with client.generateNewOrderId() before placing the order, use that value as the key for your own metadata, and store the metadata locally or in an external store such as Redis. Later, when order updates arrive through REST API polling or user data events, you can look up the richer context using the seen Binance client ID value like a primary key, while keeping the exchange-facing ID short and valid.

Regular Spot, Futures, and Portfolio orders usually use newClientOrderId; newer Futures algo or conditional flows may use clientAlgoId instead. Treat both fields, and any similar Binance custom order ID field, as the same kind of SDK-prefixed client ID. The same rule applies: omit it unless you need it, use generateNewOrderId() when any unique ID is fine, and use getOrderIdPrefix() when building your own value. Do not bypass the SDK prefix, length, or character checks just because the endpoint uses a different field name.

Margin REST API examples

Margin APIs also live on MainClient.

const marginAssets = await client.getAllMarginAssets();
const marginPairs = await client.getAllCrossMarginPairs();
const priceIndex = await client.queryMarginPriceIndex({ symbol: 'BTCUSDT' });

const crossMarginAccount = await client.queryCrossMarginAccountDetails();
const isolatedMarginAccount = await client.getIsolatedMarginAccountInfo({
  symbols: 'BTCUSDT',
});
const openMarginOrders = await client.queryMarginAccountOpenOrders({
  symbol: 'BTCUSDT',
});

Margin order:

await client.marginAccountNewOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: 0.001,
  price: 10000,
  timeInForce: 'GTC',
  isIsolated: 'FALSE',
  sideEffectType: 'NO_SIDE_EFFECT',
});

Borrow or repay:

await client.submitMarginAccountBorrowRepay({
  asset: 'USDT',
  symbol: 'BTCUSDT',
  amount: 25,
  type: 'BORROW',
  isIsolated: 'FALSE',
});

Margin permissions, collateral, interest, and liquidation behavior are account-specific. Keep margin trading code separate from ordinary Spot trading code even though both use MainClient.

Wallet and transfer examples

Wallet and transfer APIs also live on MainClient.

const balances = await client.getBalances();
const depositAddress = await client.getDepositAddress({
  coin: 'USDT',
  network: 'ETH',
});
const depositHistory = await client.getDepositHistory({ coin: 'USDT' });
const withdrawHistory = await client.getWithdrawHistory({ coin: 'USDT' });

const transferHistory = await client.getUniversalTransferHistory({
  type: 'MAIN_UMFUTURE',
});

Withdrawal calls are intentionally not shown as a quickstart. Use withdrawal permissions only when your system truly needs them, and isolate those keys from trading keys.


Futures REST API

Binance Futures are split into USD-M and COIN-M product groups. Use the dedicated client for the product you are integrating.

Create public Futures clients

import { CoinMClient, USDMClient } from 'binance';

const usdm = new USDMClient();
const coinm = new CoinMClient();

Public futures market data does not require keys.

Create private Futures clients

import { CoinMClient, USDMClient } from 'binance';

const usdm = new USDMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

const coinm = new CoinMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

Use demoTrading: true for Binance demo trading or testnet: true for testnet where supported:

const demoUsdm = new USDMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  demoTrading: true,
});

const testnetUsdm = new USDMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  testnet: true,
});

Do not enable both demoTrading and testnet on the same client.

Common public USD-M Futures market data calls

const serverTime = await usdm.getServerTime();
const exchangeInfo = await usdm.getExchangeInfo();
const orderBook = await usdm.getOrderBook({ symbol: 'BTCUSDT', limit: 10 });
const recentTrades = await usdm.getRecentTrades({
  symbol: 'BTCUSDT',
  limit: 10,
});
const candles = await usdm.getKlines({
  symbol: 'BTCUSDT',
  interval: '1m',
  limit: 10,
});
const markPrice = await usdm.getMarkPrice({ symbol: 'BTCUSDT' });
const fundingHistory = await usdm.getFundingRateHistory({
  symbol: 'BTCUSDT',
  limit: 10,
});
const ticker = await usdm.getSymbolPriceTicker({ symbol: 'BTCUSDT' });

Common public COIN-M Futures market data calls

const serverTime = await coinm.getServerTime();
const exchangeInfo = await coinm.getExchangeInfo();
const orderBook = await coinm.getOrderBook({
  symbol: 'BTCUSD_PERP',
  limit: 10,
});
const candles = await coinm.getKlines({
  symbol: 'BTCUSD_PERP',
  interval: '1m',
  limit: 10,
});
const markPrice = await coinm.getMarkPrice({ symbol: 'BTCUSD_PERP' });
const ticker = await coinm.getSymbolPriceTicker({ symbol: 'BTCUSD_PERP' });

See also:

Common private Futures account calls

const balance = await usdm.getBalance();
const account = await usdm.getAccountInformation();
const positions = await usdm.getPositions({ symbol: 'BTCUSDT' });
const openOrders = await usdm.getAllOpenOrders({ symbol: 'BTCUSDT' });
const tradeHistory = await usdm.getAccountTrades({
  symbol: 'BTCUSDT',
  limit: 10,
});
const income = await usdm.getIncomeHistory({
  symbol: 'BTCUSDT',
  limit: 10,
});

Futures order examples

Market order:

await usdm.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'SELL',
  type: 'MARKET',
  quantity: 0.001,
});

Limit order:

await usdm.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: 0.001,
  price: 10000,
  timeInForce: 'GTC',
});

Reduce-only limit order:

await usdm.submitNewOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: 0.001,
  price: 10000,
  timeInForce: 'GTC',
  reduceOnly: 'true',
});

Batch order management:

await usdm.submitMultipleOrders([
  {
    symbol: 'BTCUSDT',
    side: 'BUY',
    type: 'LIMIT',
    quantity: 0.001,
    price: 10000,
    timeInForce: 'GTC',
  },
  {
    symbol: 'BTCUSDT',
    side: 'SELL',
    type: 'LIMIT',
    quantity: 0.001,
    price: 13000,
    timeInForce: 'GTC',
  },
]);

See also:


Portfolio Margin REST API

Portfolio Margin has its own account model and a dedicated PortfolioClient.

Create a Portfolio Margin client

import { PortfolioClient } from 'binance';

const portfolio = new PortfolioClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

Common Portfolio Margin calls

const ping = await portfolio.testConnectivity();
const serverTime = await portfolio.getServerTime();
const balance = await portfolio.getBalance();
const account = await portfolio.getAccountInfo();
const umPositions = await portfolio.getUMPosition({ symbol: 'BTCUSDT' });
const cmPositions = await portfolio.getCMPosition({ pair: 'BTCUSD' });
const umOpenOrders = await portfolio.getAllUMOpenOrders({
  symbol: 'BTCUSDT',
});
const marginOpenOrders = await portfolio.getMarginOpenOrders({
  symbol: 'BTCUSDT',
});

Portfolio Margin order examples:

await portfolio.submitNewUMOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: '0.001',
  price: '10000',
  timeInForce: 'GTC',
});

await portfolio.submitNewCMOrder({
  symbol: 'BTCUSD_PERP',
  side: 'SELL',
  type: 'MARKET',
  quantity: '1',
});

await portfolio.submitNewMarginOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'MARKET',
  quantity: '0.001',
  sideEffectType: 'NO_SIDE_EFFECT',
});

See also:


WebSocket Streams

Use WebsocketClient when you want event-driven updates instead of polling the REST API. It is the shared client for public market streams and for the product areas where Binance still uses listen-key style user data streams.

The workflow is simple: create a client, add event handlers, provide API keys if you need private user data, and subscribe to the streams you want. The SDK opens the correct Binance endpoint, applies proxy settings if configured, fetches and refreshes listen keys where required, monitors heartbeats, reconnects stale sockets, and resubscribes cached topics after reconnect.

Common WebsocketClient events

EventMeaning
openConnection established
messageRaw streaming data received
formattedMessageBeautified public stream data when beautify: true
formattedUserDataMessageBeautified private user data stream event when beautify: true
responseSubscribe, unsubscribe, auth, or WebSocket API acknowledgement
reconnectingConnection dropped and retrying
reconnectedConnection restored and subscriptions resynced
closeSocket closed
authenticatedWebSocket API session authentication succeeded
exceptionErrors and unexpected conditions

Understanding WS_KEY_MAP

WS_KEY_MAP tells the SDK which Binance WebSocket endpoint family to use. This matters because Spot, USD-M Futures, COIN-M Futures, Options, Portfolio Margin, and WebSocket API traffic do not all live on the same endpoint.

Common WS_KEY_MAP entries:

KeyUse
mainSpot, margin, and isolated margin market data streams
main2Alternate Spot stream port
main3Spot market-data-only stream endpoint
mainWSAPISpot and margin WebSocket API
mainWSAPITestnetSpot WebSocket API testnet
marginUserDataMargin user data over WebSocket API listen-token flow
marginRiskUserDataCross-margin risk data stream
usdmPublicUSD-M high-frequency public market data, such as book and depth streams
usdmMarketUSD-M regular market data, such as trades, klines, tickers, mark price
usdmPrivateUSD-M private user data stream endpoint
usdmWSAPIUSD-M Futures WebSocket API
coinmCOIN-M market data and user data stream endpoint
coinmWSAPICOIN-M Futures WebSocket API
eoptionsEuropean Options WebSocket streams
portfolioMarginUserDataPortfolio Margin user data stream
portfolioMarginProUserDataPortfolio Margin Pro user data stream
alphaAlpha market data streams

These keys act like connection IDs. The SDK uses them to track connection state, cached subscriptions, reconnect behavior, and endpoint-specific routing.

Public Spot WebSocket topics

import { WebsocketClient, WS_KEY_MAP } from 'binance';

const ws = new WebsocketClient({ beautify: true });

ws.on('formattedMessage', (data) => console.log(data));
ws.on('exception', console.error);

ws.subscribe(
  [
    'btcusdt@trade',
    'btcusdt@aggTrade',
    'btcusdt@kline_1m',
    'btcusdt@bookTicker',
    'btcusdt@depth10@100ms',
  ],
  WS_KEY_MAP.main,
);

See also:

Public USD-M Futures WebSocket topics

USD-M Futures WebSockets have dedicated endpoint families for high-frequency public data and regular market data.

import { WebsocketClient, WS_KEY_MAP } from 'binance';

const ws = new WebsocketClient({ beautify: true });

ws.on('formattedMessage', (data) => console.log(data));
ws.on('exception', console.error);

// High-frequency public data: book ticker and order book depth.
ws.subscribe(
  ['btcusdt@bookTicker', 'btcusdt@depth10@100ms', 'btcusdt@depth@100ms'],
  WS_KEY_MAP.usdmPublic,
);

// Regular market data: trades, mark price, klines, mini tickers, liquidations.
ws.subscribe(['btcusdt@aggTrade', 'btcusdt@markPrice', 'btcusdt@kline_1m'], WS_KEY_MAP.usdmMarket);

See also:

Public COIN-M Futures WebSocket topics

import { WebsocketClient, WS_KEY_MAP } from 'binance';

const ws = new WebsocketClient({ beautify: true });

ws.on('message', (data) => console.log(JSON.stringify(data)));
ws.on('exception', console.error);

ws.subscribe(
  ['btcusd_perp@aggTrade', 'btcusd_perp@markPrice', 'btcusd_perp@kline_1m'],
  WS_KEY_MAP.coinm,
);

COIN-M symbols and stream names are not the same as Spot or USD-M symbols. Treat symbols as product-specific strings.


User Data Streams

User data streams are how Binance pushes private account events: order updates, execution updates, balance changes, position changes, margin events, and listen-key or subscription expiry events.

Binance uses two patterns for these streams: WebSocket API user data subscriptions and listen-key user data streams. The SDK supports both; the product group determines which path you should use.

For either pattern, listen for the WebSocket lifecycle events as well as account events. The event names are reconnecting and reconnected. reconnecting fires when the SDK starts replacing a dropped connection; reconnected fires after the replacement connection is open. Both include the wsKey, which tells you which connection was affected. For user data streams, reconnected is the right place to reconcile private state through the REST API in case account events were missed while the socket was down.

With WebsocketAPIClient, attach those handlers to wsApi.getWSClient(). With WebsocketClient, attach them directly to the client.

Preferred Spot user data stream with WebsocketAPIClient

import { WebsocketAPIClient, WS_KEY_MAP } from 'binance';

const wsApi = new WebsocketAPIClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  beautify: true,
});

const wsClient = wsApi.getWSClient();

// raw websocket event, unformatted
wsClient.on('message', (data) => {
  console.log('on message event: ', data.wsKey);
});

// formatted websocket event
wsClient.on('formattedMessage', (data) => {
  console.log('on formattedMessage: ', data);
});

// reconnection has started
wsClient.on('reconnecting', ({ wsKey }) => {
  console.log('spot user data reconnecting', wsKey);
});

// reconnection has completed
wsClient.on('reconnected', ({ wsKey }) => {
  console.log('spot user data reconnected', wsKey);
  // Fetch account state, open orders, or recent fills here if needed.
});

wsClient.on('exception', console.error);

await wsApi.subscribeUserDataStream(WS_KEY_MAP.mainWSAPI);

Binance announced deprecation of the old listenKey workflow for Spot and Margin user data streams on April 7, 2025. From February 20, 2026 at 07:00 UTC, the old Spot POST /api/v3/userDataStream path returns 410 Gone; use the WebSocket API user data stream instead. At the time of writing, Spot and Margin are the affected user data stream families. Futures and Portfolio Margin streams still use their existing listenKey-backed workflows. For the migration timeline and JavaScript fix, see Binance User Data Stream 410 Gone: Fix Spot listenKey in JavaScript.

Margin user data stream with WebsocketAPIClient

import { WebsocketAPIClient, WS_KEY_MAP } from 'binance';

const wsApi = new WebsocketAPIClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  beautify: true,
});

const wsClient = wsApi.getWSClient();

// raw websocket event, unformatted
wsClient.on('message', (data) => {
  console.log('on message event: ', data.wsKey);
});

// formatted websocket event
wsClient.on('formattedMessage', (data) => {
  console.log('on formattedMessage: ', data);
});

// reconnection has started
wsClient.on('reconnecting', ({ wsKey }) => {
  console.log('spot user data reconnecting', wsKey);
});

// reconnection has completed
wsClient.on('reconnected', ({ wsKey }) => {
  console.log('spot user data reconnected', wsKey);
  // Fetch account state, open orders, or recent fills here if needed.
});

await wsApi.subscribeUserDataStream(WS_KEY_MAP.marginUserData);

For margin, the SDK handles the listen-token workflow used by Binance's margin WebSocket API user data endpoint.

Futures user data streams with WebsocketClient

Futures user data streams are conveniently available through WebsocketClient in the Binance JavaScript SDK. Both USD-M and COIN-M Futures user data streams on Binance follow a listenKey mechanic. The SDK automates the life cycle and maintenance of this listenKey for you. Request the subscription and handle incoming events, as shown in the following example:

import { WebsocketClient } from 'binance';

const ws = new WebsocketClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  beautify: true,
});

ws.on('formattedUserDataMessage', (data) => {
  console.log('futures account event', data);
});

ws.on('reconnecting', ({ wsKey }) => {
  console.log('futures user data reconnecting', wsKey);
});

ws.on('reconnected', ({ wsKey }) => {
  console.log('futures user data reconnected', wsKey);
  // Fetch positions, balances, open orders, or fills here if needed.
});

ws.on('exception', console.error);

await ws.subscribeUsdFuturesUserDataStream();
// await ws.subscribeCoinFuturesUserDataStream();

The SDK will fetch the listen key, keep it alive, refresh it when needed, reconnect after network issues, and resubscribe where possible.

Portfolio Margin user data stream

import { WebsocketClient, WS_KEY_MAP } from 'binance';

const ws = new WebsocketClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  beautify: true,
});

ws.on('formattedUserDataMessage', (data) => {
  console.log('portfolio margin event', data);
});

ws.on('reconnecting', ({ wsKey }) => {
  console.log('portfolio margin user data reconnecting', wsKey);
});

ws.on('reconnected', ({ wsKey }) => {
  console.log('portfolio margin user data reconnected', wsKey);
});

ws.on('exception', console.error);

await ws.subscribePortfolioMarginUserDataStream(WS_KEY_MAP.portfolioMarginUserData);

See also:


WebSocket API

Binance's WebSocket API is a request/response API over a persistent WebSocket connection. It is useful when you want lower request overhead than REST API calls, or when a Binance feature is exposed through the WebSocket API flow.

WebsocketAPIClient wraps that in a promise-driven interface: call a method, await a promise, receive the response, and let the SDK manage the underlying WebSocket connection.

Authentication

The SDK supports HMAC, RSA, and Ed25519 keys:

  • HMAC: supported for REST API and WebSocket API, but WebSocket API private commands are signed individually.
  • RSA: supported for REST API and WebSocket API, but WebSocket API private commands are signed individually.
  • Ed25519: recommended for WebSocket API because the SDK can authenticate the WebSocket API session once and then send private commands without signing every command.

If your api_secret contains a PEM private key, the SDK automatically detects whether it should use RSA or Ed25519 signing.

See also:

Spot examples

import { WebsocketAPIClient } from 'binance';

const wsApi = new WebsocketAPIClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

const exchangeInfo = await wsApi.getSpotExchangeInfo({
  symbol: 'BTCUSDT',
});

const orderBook = await wsApi.getSpotOrderBook({
  symbol: 'BTCUSDT',
  limit: 10,
});

const account = await wsApi.getSpotAccountInformation({
  timestamp: Date.now(),
});

await wsApi.testSpotOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: '0.001',
  price: '10000',
  timeInForce: 'GTC',
  timestamp: Date.now(),
});

Submit a Spot order over the WebSocket API:

await wsApi.submitNewSpotOrder({
  symbol: 'BTCUSDT',
  side: 'BUY',
  type: 'LIMIT',
  quantity: '0.001',
  price: '10000',
  timeInForce: 'GTC',
});

Futures examples

import { WebsocketAPIClient } from 'binance';

const wsApi = new WebsocketAPIClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
});

const book = await wsApi.getFuturesOrderBook({
  symbol: 'BTCUSDT',
  limit: 10,
});

const balance = await wsApi.getFuturesAccountBalance('usdm', {
  timestamp: Date.now(),
});

await wsApi.submitNewFuturesOrder('usdm', {
  symbol: 'BTCUSDT',
  side: 'SELL',
  type: 'MARKET',
  quantity: '0.001',
  timestamp: Date.now(),
});

See also:


Environments and Special Endpoints

Demo trading

Demo trading uses real market data with simulated trading. For strategy testing, this is usually more useful than testnet.

const client = new USDMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  demoTrading: true,
});

Demo trading is supported by SDK options for REST API and WebSocket clients where Binance provides demo endpoints.

Testnet

Testnet uses separate credentials and simulated market conditions.

const client = new USDMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  testnet: true,
});

Use testnet for endpoint wiring and permission checks. Do not use testnet market behavior as evidence that a live strategy is profitable or safe.

Market maker endpoints

Binance provides market maker endpoints for eligible futures users. If you qualify and need those endpoints, enable them with useMMSubdomain: true.

const usdm = new USDMClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  useMMSubdomain: true,
});

const ws = new WebsocketClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  useMMSubdomain: true,
});

Market maker endpoints are for supported futures products. They are not a general Spot endpoint override and are not available on testnet.


Production Notes

Before a Binance integration trades unattended, these are the parts worth making explicit.

1. Roll out in layers

Move from public reads to private actions one layer at a time:

  1. Public REST APIs
  2. Public WebSockets
  3. Private REST API account reads
  4. Private account/user data streams
  5. Order validation
  6. Tiny demo or live trading tests

For Futures, prefer demo trading before live trading if it fits your setup.

2. Reconnect, then backfill

Listen for reconnecting and reconnected. A dropped WebSocket connection is a normal production condition, especially during volatility or scheduled exchange disconnects.

If your system uses WebSockets for account or market state, a reconnect should usually trigger a REST API backfill:

  1. Pause risky order actions when reconnecting fires.
  2. On reconnected, query the REST API for account state, orders, fills, positions, and any market state you depend on.
  3. Reconcile internal state.
  4. React to any discrepancies in internal vs exchange state, as needed.
  5. Resume normal processing.

3. Keep credentials scoped

Live, demo trading, Spot testnet, and Futures testnet credentials are different. Keep them separate in your secrets manager and deployment configuration.

Use the minimum permissions needed for each key. A market-data key should not be able to trade. A trading key should not have withdrawal permissions. Do not put live secrets in frontend code. Make use of IP whitelisting for any API keys. These must be protected, treat them like passwords.

4. Keep streams and commands separate

Use WebsocketClient for streams. Use WebsocketAPIClient for commands you want to await. They share WebSocket infrastructure, but they solve different problems.

5. Treat symbols and order IDs as product-specific state

Spot, USD-M Futures, COIN-M Futures, Options, and Portfolio Margin do not all use the same symbol conventions:

  • Spot: BTCUSDT
  • USD-M Futures: BTCUSDT
  • COIN-M Futures: BTCUSD_PERP
  • Stream names are usually lowercase, such as btcusdt@trade. Refer to the examples and/or exchange API docs for exact stream names.

Client order IDs deserve the same care. If you do not need a custom client order ID, omit it. If your strategy relies on idempotency, retries, or reconciliation, generate an ID before sending the order and persist it using the restClient.generateNewOrderId() method. If you build your own value, keep the SDK's product prefix in place (query it using restClient.getOrderIdPrefix()) and stay within Binance's length and character constraints.

6. Watch clocks and rate limits

Private Binance requests are timestamp-sensitive. Keep your system clock synced and set recvWindow intentionally:

const client = new MainClient({
  api_key: process.env.BINANCE_API_KEY!,
  api_secret: process.env.BINANCE_API_SECRET!,
  recvWindow: 5000,
});

await client.fetchLatencySummary();

// For WebSocket API clients:
wsApi.setTimeOffsetMs(-500);

The REST API client also tracks Binance rate-limit headers it sees:

const ticker = await client.getSymbolPriceTicker({ symbol: 'BTCUSDT' });
console.log(ticker);

console.log(client.getRateLimitStates());

If you see timestamp errors, fix system clock sync first. If you see rate-limit pressure, reduce polling, batch where the API allows it, and design around Binance's documented request weights.

For more guidance on resolving timestamp & recvWindow issues, refer to the following guidance: https://github.com/sieblyio/awesome-crypto-examples/wiki/Timestamp-for-this-request-is-outside-of-the-recvWindow

7. Logging and large integers

If you want SDK logs in your own monitoring stack, pass a logger:

import { DefaultLogger, WebsocketClient } from 'binance';

const customLogger: typeof DefaultLogger = {
  ...DefaultLogger,
  trace: () => {},
  info: (...params) => console.info(new Date(), ...params),
  error: (...params) => console.error(new Date(), ...params),
};

const ws = new WebsocketClient(
  {
    api_key: process.env.BINANCE_API_KEY!,
    api_secret: process.env.BINANCE_API_SECRET!,
    beautify: true,
  },
  customLogger,
);

JavaScript cannot precisely represent integers above Number.MAX_SAFE_INTEGER. If you need to preserve very large order IDs from WebSocket messages, provide a custom parser:

import { WebsocketClient } from 'binance';

const ws = new WebsocketClient({
  customParseJSONFn: (rawEvent) => {
    return JSON.parse(rawEvent.replace(/"orderId":\s*(\d+)/g, '"orderId":"$1"'));
  },
});

See also: custom parser example


FAQ

Which REST API client should I use?

Use MainClient for Spot, margin, wallet, Convert, Earn, sub-account, and many account APIs. Use USDMClient for USD-M Futures. Use CoinMClient for COIN-M Futures. Use PortfolioClient for Portfolio Margin.

Do I need API keys for public market data?

No. Public REST API market data and public WebSocket market data do not require API keys.

Can I use one Binance API key for every product group?

Sometimes, but only when the key belongs to the right environment and has the required product permissions enabled. Keep live, demo, and testnet credentials separate. Also keep high-risk permissions, especially withdrawals, separate from ordinary trading keys.

What is the difference between HMAC, RSA, and Ed25519?

HMAC is the standard API key + secret flow. RSA and Ed25519 use self-generated private keys. The SDK detects PEM private keys automatically when they are passed as api_secret. Ed25519 is recommended for latency-sensitive WebSocket API usage because it supports WebSocket API session authentication.

Why both WebsocketClient and WebsocketAPIClient?

  • WebsocketClient is for subscriptions and streaming topics.
  • WebsocketAPIClient is for commands over Binance's WebSocket API. Think "REST API" but over persistent WebSockets.

Should I use listen keys for Spot user data?

Use WebsocketAPIClient.subscribeUserDataStream(WS_KEY_MAP.mainWSAPI) for Spot user data. Binance retired the older Spot listen-key workflow, so JavaScript apps should not start new Spot user data streams with POST /api/v3/userDataStream.

What happens if a WebSocket connection drops?

The SDK supports reconnect and resubscribe flows. Listen for reconnecting and reconnected. Use reconnected as a trigger to reconcile state through the REST API before resuming risky trading actions.

Should I use demo trading or testnet?

Use demo trading when you want simulated trading with real market data. Use testnet for API wiring, endpoint behavior, and permission checks. Do not treat testnet market behavior as representative of live market behavior.

Can I use this Binance API SDK in TypeScript projects?

Yes. The package is TypeScript-first and publishes type declarations.

Do I need TypeScript to use this JavaScript Binance SDK?

No. Pure JavaScript projects can use this SDK too. Type declarations are included and will help your IDE, but TypeScript is not required.

Can I use this package in both ESM and CommonJS projects?

Yes. The package supports both ESM-style imports and CommonJS require().

Does this guide cover every SDK method?

No. This guide covers the common first steps and production concerns. For full method coverage, see:


Next steps

If you want to learn more about integrating with Binance APIs and WebSockets:

Subscribe on Substack

Complete the Substack form below to join our newsletter. Substack handles all subscriber data directly.