Blog
AIWebSocketsTrading systemsTypeScriptNode.js

Bitget API SDK for TypeScript: Node.js Guide (2026)

Master the Bitget api sdk TypeScript for Node.js. This guide shows how to build production-ready integrations with typed requests and awaitable WebSockets.

Siebly.io9 min readMarkdown

Overview

Raw HTTP against Bitget is a pain. You have to sign every private request, keep timestamps inside a 30 second window, and keep WebSocket connections alive yourself. The bitget-api package from Siebly.io does that work for you, in TypeScript and plain Node.js.

This guide walks through the real clients in the SDK: REST for V2 and V3, market data streams, and awaitable WebSocket orders on the V3 Unified Trading Account. The SDK signs requests and keeps sockets connected. It does not rate-limit for you. That part is still yours.

Key Takeaways

  • bitget-api signs private REST calls with HMAC SHA256 (or RSA) and sets the ACCESS-KEY, ACCESS-SIGN, ACCESS-TIMESTAMP, and ACCESS-PASSPHRASE headers.
  • New work on a Unified Trading Account should use RestClientV3, WebsocketClientV3, and WebsocketAPIClient. Stay on RestClientV2 / WebsocketClientV2 if you have not upgraded.
  • Awaitable WebSocket orders exist on V3 only, through WebsocketAPIClient. V2 sockets are subscriptions, not request-response order placement.
  • Bitget has no separate testnet URL in this SDK. Use demoTrading: true for demo trading.
  • Default private REST limits sit around 10 requests per second per UID. The SDK does not throttle. You handle 429s and backoff.

Overcoming Fragmentation in Bitget API Integrations

Bitget currently ships two generations of API. V3 is the Unified Trading Account (UTA). V2 is the older classic account. Endpoint shapes differ. Auth does not. A dedicated Bitget TypeScript SDK gives you one client per generation instead of a pile of signed fetch wrappers.

bitget-api is listed in Bitget's own API docs. It covers V2 REST and WebSockets, V3/UTA REST and WebSockets, and V3 WebSocket API order placement. Official docs stay the source of truth for what an endpoint does. The SDK is the typed client you actually call.

Install it with:

Imported example

Shell
npm install bitget-api

The Problem with Raw REST and WebSocket Implementations

Bitget signs private REST with HMAC SHA256, then Base64. The payload is timestamp + method + path + query or body. One extra character and the request dies. Private WebSockets need the same credentials, plus heartbeats, reconnect, and resubscribe.

The SDK builds those headers and keeps the socket alive. Response types still differ between V2 and V3, so pick the matching client. Rate limits are still on you. Hit them and Bitget returns HTTP 429.

Why a TypeScript-First SDK is Essential

Request params and responses are typed. Autocomplete is useful. Compile-time checks catch missing fields before you send a live order. The package is written in TypeScript and ships JavaScript, so either language works.

If you use coding agents, the package also ships an llms.txt file. Point the agent at that file and it will call the right client methods instead of inventing them. Same family of clients as the other Siebly.io SDKs.

Authentication and Request Signing with Siebly bitget-api

Private Bitget calls need three values: API key, secret, and passphrase. HMAC is the usual path. RSA works too if you created the key with your own public key and pass the PEM private key as apiSecret.

The SDK concatenates timestamp, uppercase HTTP method, request path, and body (or ?query for GET), hashes with HMAC SHA256, and Base64-encodes the result. It then sets:

  • ACCESS-KEY
  • ACCESS-SIGN
  • ACCESS-TIMESTAMP
  • ACCESS-PASSPHRASE

Bitget rejects a timestamp more than 30 seconds away from server time. REST signing in this SDK uses local Date.now(). It does not rewrite timestamps for you. If your clock is wrong, fix NTP, or call fetchLatencySummary() to measure drift. That helper is diagnostic. It does not attach an offset to later REST calls.

The SDK also does not rate-limit. Many private endpoints sit at 10 requests per second per UID. Plan for 429s.

Implementing Secure Secret Management

Keep keys out of git. Environment variables are enough for most Node services. Disable withdrawals on automation keys. If you only need market data and orders, grant only those permissions. IP whitelist the box that signs requests.

Imported example

JavaScript
import { RestClientV3 } from "bitget-api";
// or: const { RestClientV3 } = require('bitget-api');

const client = new RestClientV3({
  apiKey: process.env.API_KEY_COM,
  apiSecret: process.env.API_SECRET_COM,
  apiPass: process.env.API_PASS_COM,
});

(async () => {
  try {
console.log(await client.getBalances());

const newOrder = await client.submitNewOrder({
category: "USDT-FUTURES",
orderType: "market",
side: "buy",
qty: "0.001",
symbol: "BTCUSDT",
});

console.log("Order submitted: ", newOrder);
  } catch (e) {
console.error("request failed: ", e);
  }
})();

Public calls do not need keys:

Imported example

JavaScript
import { RestClientV3 } from "bitget-api";

const restClient = new RestClientV3();

const response = await restClient.getCandles({
  symbol: "BTCUSDT",
  category: "SPOT",
  interval: "1m",
});

If you have not upgraded to UTA, use RestClientV2 the same way (apiKey, apiSecret, apiPass). Methods follow the V2 docs, for example getSpotAccount() and getSpotCandles().

Handling Nonces and Replay Attack Protection

ACCESS-TIMESTAMP is milliseconds since epoch. Bitget treats anything older than 30 seconds as expired. That is Bitget's rule, not a Binance-style recvWindow query param on REST.

fetchLatencySummary() on both REST clients hits getServerTime(), estimates one-way latency, and warns if local clock is more than 500ms off. Use it when signed calls start failing. Keep the machine on NTP. WebSocket clients expose setTimeOffsetMs() if you need to nudge WS auth timestamps yourself.

For config patterns, see the bitget-api quickstart.

Reliable WebSockets: Implementing Awaitable Patterns and Streams

There are three WebSocket clients. Do not mix them up.

  • WebsocketClientV3: V3/UTA market data and private account streams.
  • WebsocketAPIClient: V3 order placement over a persisted socket. Looks like REST, returns promises.
  • WebsocketClientV2: V2 streams if you are still on a classic account.

Awaitable orders are V3 only. V2 subscribeTopic() is event-driven. You cannot await a V2 order over WebSocket through this SDK.

All three reconnect, resubscribe, and send application-level ping frames (default every 10 seconds). Bitget does not use native WebSocket ping/pong frames here. You still have to respect Bitget's subscribe and message limits, or the exchange will drop the connection.

Awaitable WebSocket Mechanics Explained

WebsocketAPIClient wraps WebsocketClientV3.sendWSAPIRequest(). Each call is routed over the open private socket and resolved when the matching response arrives. You need V3/UTA keys.

Imported example

JavaScript
import { WebsocketAPIClient } from "bitget-api";
// or: const { WebsocketAPIClient } = require('bitget-api');

const wsClient = new WebsocketAPIClient({
  apiKey: process.env.API_KEY_COM,
  apiSecret: process.env.API_SECRET_COM,
  apiPass: process.env.API_PASS_COM,
  // demoTrading: true,
});

async function start() {
  // Optional: warm the socket so the first order is not a cold start
  await wsClient.getWSClient().connectWSAPI();

  try {
const res = await wsClient.submitNewOrder("spot", {
orderType: "limit",
price: "100",
qty: "0.1",
side: "buy",
symbol: "BTCUSDT",
timeInForce: "gtc",
});

console.log(new Date(), 'WS API "submitNewOrder()" result: ', res);
  } catch (e) {
console.error(new Date(), 'Exception with WS API "submitNewOrder()": ', e);
  }
}

start().catch((e) => console.error("Exception in example: ", e));

Same client also has placeBatchOrders, cancelOrder, and cancelBatchOrders. Batch place can return code: "0" at the top level even when individual orders failed. Check each item's code and msg.

Managing Real-Time Market Data Streams

WebsocketClientV3 multiplexes public and private topics. Subscribe to several tickers on one public connection, and account/order/fill/position on the private one.

Imported example

JavaScript
import { WebsocketClientV3, WS_KEY_MAP } from "bitget-api";

const wsClient = new WebsocketClientV3();

wsClient.on("update", (data) => {
  console.log("WS raw message received ", data);
});

wsClient.on("open", (data) => {
  console.log("WS connection opened:", data.wsKey);
});

wsClient.on("reconnect", ({ wsKey }) => {
  console.log("WS automatically reconnecting.... ", wsKey);
});

wsClient.on("reconnected", (data) => {
  console.log("WS reconnected ", data?.wsKey);
});

wsClient.on("exception", (data) => {
  console.log("WS error", data);
});

wsClient.subscribe(
  {
topic: "ticker",
payload: {
instType: "spot",
symbol: "BTCUSDT",
},
  },
  WS_KEY_MAP.v3Public,
);

wsClient.subscribe(
  [
{
topic: "ticker",
payload: { instType: "spot", symbol: "ETHUSDT" },
},
{
topic: "ticker",
payload: { instType: "usdt-futures", symbol: "BTCUSDT" },
},
  ],
  WS_KEY_MAP.v3Public,
);

Private UTA account events use instType: 'UTA' and WS_KEY_MAP.v3Private. That is true for account, position, fill, and order topics.

On V2:

Imported example

JavaScript
import { WebsocketClientV2 } from "bitget-api";

const wsClient = new WebsocketClientV2({
  apiKey: process.env.API_KEY_COM,
  apiSecret: process.env.API_SECRET_COM,
  apiPass: process.env.API_PASS_COM,
  // demoTrading: true,
});

wsClient.on("update", (data) => {
  console.log("WS update received: ", data);
});

wsClient.subscribeTopic("SPOT", "ticker", "BTCUSDT");
wsClient.subscribeTopic("SPOT", "account");

Keep heavy work off the event loop. The bitget-api tutorial has more stream examples.

Engineering Best Practices: Safety Boundaries and Demo Trading

The SDK sends valid requests. Your app still needs limits, retries, and key hygiene.

Bitget's default for many authenticated endpoints is 10 requests per second per UID. After 3 September 2026 (17:00 UTC+8), top-tier MM and PRO UTA accounts can raise the per-UID cap as high as 600 requests per second. That is not the default, and it is not every institutional account. Unconfigured sub-accounts still land on 10/s. The SDK will not slow you down. If you ignore 429s, you will have a bad time.

Disable withdrawals on bot keys. Whitelist IPs. Rotate keys. Keep the integration layer thin so an exchange change does not rewrite your strategy code.

Demo Trading Before Live Keys

Bitget demo trading is not a separate testnet host in this SDK. WebSockets switch to the demo hosts (wss://wspap.bitget.com/...). You need demo-trading API keys from Bitget's demo environment.

Imported example

JavaScript
const client = new RestClientV3({
  apiKey: process.env.API_KEY_COM,
  apiSecret: process.env.API_SECRET_COM,
  apiPass: process.env.API_PASS_COM,
  demoTrading: true,
});

const wsClient = new WebsocketClientV3({
  apiKey: process.env.API_KEY_COM,
  apiSecret: process.env.API_SECRET_COM,
  apiPass: process.env.API_PASS_COM,
  demoTrading: true,
});

Same flag on WebsocketAPIClient and WebsocketClientV2. Do not pass a fake testnet baseUrl. That option exists for proxies and custom domains, not for Bitget demo trading.

Building for AI-Assisted Engineering

Types help Copilot and similar tools. The bundled llms.txt helps more, because it lists actual methods and params. You can also use Siebly AI frameworks when you want pre-checked integration patterns. Still read the official Bitget docs before you ship.

Scaling Bitget Integrations with Siebly SDKs

A homemade Bitget wrapper ages badly. V2 vs V3, HMAC vs RSA, demo vs live, WS reconnect. The Siebly client already has those paths. The same layout shows up in the binance package (binance on npm) and bybit-api. One style of REST client plus WebSocket client, per exchange.

Watch REST latency and WebSocket reconnect / reconnected / exception events. Stay on Bitget's current V2 or V3 docs, and on the institutional rate-limit notice if you are in that program. The SDK will not absorb a 429 for you.

Migration Guidance for Legacy Wrappers

Replace hand-rolled HMAC with RestClientV3 or RestClientV2. Credentials are apiKey, apiSecret, apiPass. If you place orders over WebSocket, move that to WebsocketAPIClient on UTA. Leave WebsocketClientV3 (or V2) for streams. Linear await on WS API calls is easier to debug than a global message handler that matches order IDs by hand.

The Role of Siebly in Professional Infrastructure

Release notes live at siebly.io/releases. For a wider Node.js trading layout, see Algorithmic Trading System Architecture in Node.js. For this exchange, start with bitget-api.

Deploying Stable Bitget Integration Infrastructure

Use V3 clients if you are on UTA. Use V2 if you are not. Let the SDK sign REST and keep WebSockets up. Put demo trading, key scopes, and your own rate limiter in front of live orders.

Siebly.io ships these Node.js clients with TypeScript types and an llms.txt for agents. Explore the Bitget TypeScript SDK on Siebly.io, run against demo trading first, then point the same code at live keys.

Frequently Asked Questions

Does the Siebly Bitget SDK automatically handle rate limiting?

No. bitget-api does not queue, throttle, or retry on 429. Many private endpoints default to 10 requests per second per UID. Higher caps exist for some MM/PRO UTA accounts after the 3 September 2026 update, up to 600/s per UID at the top tier. Your process still has to stay under whatever Bitget assigned you.

Can I use the bitget-api package with both JavaScript and TypeScript?

Yes. It is written in TypeScript and published as JavaScript. import or require both work.

How do I connect to Bitget demo trading using this SDK?

Set demoTrading: true on the client. Use demo API keys from Bitget's demo trading pages. REST stays on the live host and sends paptrading: 1. WebSockets use the demo WSS URLs. There is no testnet: true flag and no testnet base URL in this SDK.

Is the WebSocket client awaitable for private order placement?

On V3/UTA, yes, via WebsocketAPIClient (submitNewOrder, batch place, cancel). That is not how WebsocketClientV2 or WebsocketClientV3 subscriptions work. Those emit update events for streams.

What is the most secure way to handle my Bitget API secrets in Node.js?

Environment variables or a vault. Never commit key, secret, or passphrase. Least privilege, withdrawals off, IP whitelist on.

Does this SDK support Bitget V2 and V3?

Yes. RestClientV2 and WebsocketClientV2 cover V2. RestClientV3, WebsocketClientV3, and WebsocketAPIClient cover V3/UTA, including spot, futures, and account modules on that generation. New UTA projects should start on V3.

How do heartbeats and reconnections work in the WebSocket client?

The client sends ping on an interval (10 seconds by default) and expects a pong. If the socket dies, it reconnects and resubscribes to the topics it already had. You get reconnect then reconnected events. Native WebSocket ping frames are not used for Bitget.

Can I use this SDK with AI coding agents like GitHub Copilot?

Yes. Types help, and llms.txt in the package is the file to feed an agent so it uses the real method names.

Disclaimer

*Technical and legal disclaimer: Siebly.io provides software development tools, SDKs, documentation, and educational engineering content for crypto exchange API integrations. This content is for software engineering education only and is not financial, investment, legal, tax, accounting, compliance, or trading advice.

Nothing in this article is a recommendation, invitation, or inducement to buy, sell, hold, trade, long, short, or allocate to any cryptoasset, exchange product, strategy, bot, or automated workflow. Examples, code patterns, simulations, backtests, and architecture diagrams are illustrative only and must not be treated as trading signals, investment recommendations, or evidence of future performance.

Cryptoasset markets are high risk and volatile. If you choose to build or operate exchange-connected software, you are responsible for your own legal, regulatory, tax, security, exchange-account, API-key, and risk-management obligations. Use public data, testnet, demo, dry-run, or paper-trading workflows before any live execution. Keep API keys server-side, use least-privilege permissions, and never enable withdrawals for automation keys unless you fully understand and accept the risks.

Siebly.io is not an exchange, custodian, investment adviser, trading-signal provider, or managed trading service. Official exchange documentation remains the source of truth for exchange-specific rules, API behavior, and terms of use. Use of Siebly.io content and software is also subject to the Siebly.io terms and conditions.*

Related articles

Continue from here

Related Siebly resources

All articles

Subscribe on Substack

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