API Integration

How to Connect to Binance API with Node.js: crypto Signatures and node-binance-api

A complete practical guide to the Binance Node.js API: native crypto signatures, axios request encapsulation, official node-binance-api library, WebSocket ws subscriptions, exception handling, and TypeScript type definitions with runnable code.

The standard path for accessing the Binance Node.js API is using the native crypto module to generate HMAC-SHA256 signatures combined with axios or undici for sending requests, or directly using community libraries like node-binance-api or binance-api-node. This article provides complete code for native encapsulation, popular SDK comparisons, WebSocket subscriptions, and TypeScript types—all of which can be run immediately after an npm install. If you don't have a Binance account yet, you can register on the Binance Official Website; new users can open an account via Free Registration.

1. Node.js SDK Comparison Table

Library Author Weekly Downloads Features Recommended Use Case
node-binance-api jaggedsoft 30k+ Comprehensive, callback-based Quick script validation
binance-api-node Ashlar 50k+ Promise + TypeScript friendly Production TypeScript environments
@binance/connector Official 40k+ Lightweight thin wrapper Following API updates closely
ccxt Community 80k+ Unified multi-exchange API Cross-exchange quant trading
Custom axios + crypto Maximum control High-frequency market making

2. Native crypto Signature + axios Encapsulation

1. Project Initialization

mkdir binance-node && cd binance-node
npm init -y
npm install axios dotenv

.env file:

BINANCE_API_KEY=your_key_here
BINANCE_SECRET_KEY=your_secret_here

2. Core Signature Encapsulation

src/client.js:

const crypto = require('crypto');
const axios = require('axios');
require('dotenv').config();

const API_KEY = process.env.BINANCE_API_KEY;
const SECRET_KEY = process.env.BINANCE_SECRET_KEY;
const BASE_URL = 'https://api.binance.com';

function sign(params) {
  const query = new URLSearchParams(params).toString();
  return crypto
    .createHmac('sha256', SECRET_KEY)
    .update(query)
    .digest('hex');
}

async function request(method, path, params = {}, signed = false) {
  const headers = {};
  if (signed) {
    params.timestamp = Date.now();
    params.recvWindow = 5000;
    params.signature = sign(params);
    headers['X-MBX-APIKEY'] = API_KEY;
  }

  try {
    const config = {
      method,
      url: `${BASE_URL}${path}`,
      headers,
      timeout: 10000,
    };
    if (method === 'GET' || method === 'DELETE') {
      config.params = params;
    } else {
      config.data = new URLSearchParams(params).toString();
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
    }
    const r = await axios(config);
    return r.data;
  } catch (err) {
    if (err.response) {
      const { code, msg } = err.response.data;
      throw new Error(`Binance ${code}: ${msg}`);
    }
    throw err;
  }
}

module.exports = { request, sign };

3. Account and Ticker Calls

src/account.js:

const { request } = require('./client');

async function getAccount() {
  return request('GET', '/api/v3/account', {}, true);
}

async function getPrice(symbol) {
  const r = await request('GET', '/api/v3/ticker/price', { symbol });
  return parseFloat(r.price);
}

async function getDepth(symbol, limit = 20) {
  return request('GET', '/api/v3/depth', { symbol, limit });
}

async function placeLimitOrder(symbol, side, quantity, price) {
  return request('POST', '/api/v3/order', {
    symbol,
    side,
    type: 'LIMIT',
    timeInForce: 'GTC',
    quantity,
    price,
  }, true);
}

async function cancelOrder(symbol, orderId) {
  return request('DELETE', '/api/v3/order', { symbol, orderId }, true);
}

module.exports = { getAccount, getPrice, getDepth, placeLimitOrder, cancelOrder };

4. Running the Example

index.js:

const { getAccount, getPrice, placeLimitOrder } = require('./src/account');

(async () => {
  try {
    const account = await getAccount();
    const nonZero = account.balances.filter(b => parseFloat(b.free) > 0);
    console.log('Non-zero balances:');
    nonZero.forEach(b => console.log(`  ${b.asset}: ${b.free}`));

    const btc = await getPrice('BTCUSDT');
    console.log(`BTC Latest Price: $${btc}`);

    // Place a limit order (10% below current price to avoid immediate fill)
    const testPrice = (btc * 0.9).toFixed(2);
    const order = await placeLimitOrder('BTCUSDT', 'BUY', '0.001', testPrice);
    console.log(`Order ${order.orderId} created`);
  } catch (e) {
    console.error('Failed:', e.message);
  }
})();

Run:

node index.js

3. Quick Solution with node-binance-api

1. Installation

npm install node-binance-api

2. Usage Example

const Binance = require('node-binance-api');

const binance = new Binance().options({
  APIKEY: process.env.BINANCE_API_KEY,
  APISECRET: process.env.BINANCE_SECRET_KEY,
  useServerTime: true,  // Sync with server time automatically
  recvWindow: 10000,
  test: false,  // Set to true to use the testnet
});

// Check balances
binance.balance((error, balances) => {
  if (error) return console.error(error);
  Object.keys(balances).forEach(asset => {
    const available = parseFloat(balances[asset].available);
    if (available > 0) {
      console.log(`${asset}: ${available}`);
    }
  });
});

// Market Buy
binance.marketBuy('BTCUSDT', 0.001, (error, response) => {
  if (error) return console.error(error.body);
  console.log('Market buy successful:', response);
});

// Limit Order
binance.buy('BTCUSDT', 0.001, 60000, { type: 'LIMIT' }, (error, response) => {
  if (error) return console.error(error.body);
  console.log('Limit order placed:', response.orderId);
});

// Promise Style
(async () => {
  const ticker = await binance.prices('BTCUSDT');
  console.log('Current price:', ticker.BTCUSDT);

  const candles = await binance.candlesticks('BTCUSDT', '1h', false, { limit: 100 });
  console.log('Recent K-lines:', candles.length);
})();

4. binance-api-node (Promise / TypeScript)

1. Installation

npm install binance-api-node
npm install -D typescript @types/node

2. TypeScript Example

import Binance, { Binance as BinanceClient, OrderType, OrderSide } from 'binance-api-node';

const client: BinanceClient = Binance({
  apiKey: process.env.BINANCE_API_KEY!,
  apiSecret: process.env.BINANCE_SECRET_KEY!,
});

async function main() {
  // Automatic type inference
  const time = await client.time();
  console.log('Server time:', new Date(time));

  const account = await client.accountInfo();
  const nonZero = account.balances.filter(b => parseFloat(b.free) > 0);
  console.log(`Holding ${nonZero.length} assets`);

  const depth = await client.book({ symbol: 'BTCUSDT', limit: 20 });
  console.log(`Bid 1: ${depth.bids[0].price}, Ask 1: ${depth.asks[0].price}`);

  // Order with type checking
  const order = await client.order({
    symbol: 'BTCUSDT',
    side: OrderSide.BUY,
    type: OrderType.LIMIT,
    timeInForce: 'GTC',
    quantity: '0.001',
    price: '60000.00',
  });
  console.log('Order ID:', order.orderId);
}

main().catch(console.error);

5. Real-time WebSocket Subscriptions (ws library)

const WebSocket = require('ws');

function subscribeTickers(symbols) {
  const streams = symbols.map(s => `${s.toLowerCase()}@ticker`).join('/');
  const url = `wss://stream.binance.com:9443/stream?streams=${streams}`;

  function connect() {
    const ws = new WebSocket(url);

    ws.on('open', () => console.log(`Subscribed to ${symbols.length} pairs`));

    ws.on('message', (raw) => {
      const { stream, data } = JSON.parse(raw);
      console.log(`${data.s}: Latest Price ${data.c}, 24h Change ${data.P}%`);
    });

    ws.on('pong', () => console.log('Received pong'));

    ws.on('close', () => {
      console.log('Connection closed, reconnecting in 5s');
      setTimeout(connect, 5000);
    });

    ws.on('error', (err) => console.error('WS Error:', err.message));

    // Send ping every 3 minutes to keep alive
    setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) ws.ping();
    }, 180000);
  }

  connect();
}

subscribeTickers(['BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT']);

6. Futures API Node.js Example

const crypto = require('crypto');
const axios = require('axios');

const FAPI = 'https://fapi.binance.com';

function signFutures(params, secret) {
  const query = new URLSearchParams(params).toString();
  return crypto.createHmac('sha256', secret).update(query).digest('hex');
}

async function futuresPlaceOrder(apiKey, secret, symbol, side, quantity, price) {
  const params = {
    symbol,
    side,
    type: 'LIMIT',
    timeInForce: 'GTC',
    quantity: quantity.toString(),
    price: price.toString(),
    timestamp: Date.now(),
  };
  params.signature = signFutures(params, secret);

  const r = await axios.post(
    `${FAPI}/fapi/v1/order`,
    new URLSearchParams(params).toString(),
    {
      headers: {
        'X-MBX-APIKEY': apiKey,
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    }
  );
  return r.data;
}

async function futuresSetLeverage(apiKey, secret, symbol, leverage) {
  const params = { symbol, leverage, timestamp: Date.now() };
  params.signature = signFutures(params, secret);

  const r = await axios.post(
    `${FAPI}/fapi/v1/leverage`,
    new URLSearchParams(params).toString(),
    { headers: { 'X-MBX-APIKEY': apiKey } }
  );
  return r.data;
}

7. FAQ

Q1: Is Date.now() accurate enough in Node.js?

A: Yes. Date.now() returns a millisecond-precision timestamp (13 digits), which is exactly what the Binance API requires. Ensure your system clock is accurate in container environments (using chronyd or systemd-timesyncd).

Q2: Which is better for the Binance API, axios or node-fetch?

A: axios is well-suited for REST by default (automatic JSON parsing, error retries, connection pooling). node-fetch (native in Node 18+) is lighter but requires manual error handling. For high-frequency scenarios, undici or native http.Agent is recommended, offering up to 30% higher performance than axios.

Q3: How do I avoid as any in TypeScript?

A: Use binance-api-node, which comes with full type definitions, or generate types from official OpenAPI specs using openapi-typescript. Avoid generic request<any> wrappers.

Q4: What should I watch for with pm2?

A: If a WebSocket connection is lost, the Node event loop won't exit, so pm2 won't auto-restart. Implement reconnection logic (see section 5) and set max_memory_restart: '500M' to prevent memory leaks.

Q5: How do I implement rate limiting in Node.js?

A: Use the bottleneck library:

const Bottleneck = require('bottleneck');
const limiter = new Bottleneck({
  minTime: 10,        // Minimum 10ms interval
  maxConcurrent: 20,  // Maximum 20 concurrent requests
});
const wrappedGet = limiter.wrap(axios.get);

After reviewing the Node.js solutions, return to the Category Navigation to check other SDK tutorials in the "API Integration" category.

Keep reading

Still have Binance questions? Head back to the category page for more tutorials on the same topic.

Categories

Related tutorials

How to Apply for Binance API? Common Guide for Key Generation and Signatures 2026-04-14 How to Use Binance Spot API? Executable Code from Zero to Your First Order 2026-04-14 What are the Differences Between Binance Futures and Spot APIs? Endpoint, Parameter, and Weight Comparison 2026-04-14 Will My IP Get Banned? Detailed Explanation of Binance API Rate Limits and Weights 2026-04-14