---
title: "Bitget API SDK for TypeScript: Node.js Guide (2026)"
description: "Master the Bitget api sdk TypeScript for Node.js. This guide shows how to build production-ready integrations with typed requests and awaitable WebSockets."
canonical: "https://siebly.io/blog/bitget-api-sdk-for-typescript-nodejs-guide-2026"
---

# 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.

## Technical Disclaimer

These articles are software engineering references for exchange API integrations. They are not financial, investment, legal, tax, compliance, or trading advice. Use public data, demo, testnet, or paper workflows first. Keep API credentials out of frontend code and disable withdrawal permissions for automation keys.

## Overview {#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](/sdk/bitget/javascript) 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 {#key-takeaways}

- [bitget-api](/sdk/bitget/javascript) 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 {#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](/sdk/bitget/javascript) 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:

```bash title="Imported example"
npm install bitget-api
```

### The Problem with Raw REST and WebSocket Implementations {#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 {#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](/sdk).

## Authentication and Request Signing with Siebly bitget-api {#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 {#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.

```js title="Imported example"
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:

```js title="Imported example"
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 {#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](/sdk/bitget/javascript).

## Reliable WebSockets: Implementing Awaitable Patterns and Streams {#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 {#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.

```js title="Imported example"
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 {#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.

```js title="Imported example"
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:

```js title="Imported example"
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](/sdk/bitget/javascript) has more stream examples.



## Engineering Best Practices: Safety Boundaries and Demo Trading {#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 {#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.

```js title="Imported example"
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 {#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](/ai) when you want pre-checked integration patterns. Still read the official Bitget docs before you ship.

## Scaling Bitget Integrations with Siebly SDKs {#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](/sdk/binance/javascript) package (`binance` on npm) and [bybit-api](/sdk/bybit/javascript). 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 {#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 {#the-role-of-siebly-in-professional-infrastructure}

Release notes live at [siebly.io/releases](/releases). For a wider Node.js trading layout, see [Algorithmic Trading System Architecture in Node.js](/blog/algorithmic-trading-system-architecture-in-nodejs-a-2026-engineering-guide). For this exchange, start with [bitget-api](/sdk/bitget/javascript).

## Deploying Stable Bitget Integration Infrastructure {#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](/sdk/bitget/javascript), run against demo trading first, then point the same code at live keys.

## Frequently Asked Questions {#frequently-asked-questions}

### Does the Siebly Bitget SDK automatically handle rate limiting? {#does-the-siebly-bitget-sdk-automatically-handle-rate-limiting}

No. [bitget-api](/sdk/bitget/javascript) 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? {#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? {#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? {#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? {#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? {#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? {#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? {#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

- [Bitget API SDK TypeScript: Building Production-Ready Node.js Integrations in 2026](/blog/bitget-api-sdk-typescript-building-production-ready-nodejs-integrations-in-2026)
- [Real-Time Crypto Market Data API: Node.js Guide 2026](/blog/real-time-crypto-market-data-api-nodejs-guide-2026)
- [Crypto Exchange SDK for Coding Agents: Building Reliable Agentic Trading Systems](/blog/crypto-exchange-sdk-for-coding-agents-building-reliable-agentic-trading-systems)


## Related Siebly Resources

- [Binance JavaScript SDK](/sdk/binance/javascript)
- [Bybit JavaScript SDK](/sdk/bybit/javascript)
- [Bitget JavaScript SDK](/sdk/bitget/javascript)
- [Siebly SDK directory](/sdk)
- [Siebly AI Prompt Framework & Skills](/ai)
