Bitget API SDK TypeScript: Building Production-Ready Node.js Integrations in 2026
Build production-ready Node.js integrations with our Bitget API SDK TypeScript guide. Automate HMAC signing and use type-safe interfaces for REST & WebSocket.
Overview
Manual Bitget API integration often burns more time on auth and signing than on the trading logic itself. V2 and V3 docs live in different places, and HMAC SHA256 request signing needs exact string formatting. The bitget-api package handles signing, request shapes, and TypeScript types so you can focus on what your app actually does.
Unreliable WebSocket reconnects and untyped API responses are a real problem in production. This guide walks through a type-safe Bitget setup for REST and WebSocket workflows in Node.js, including awaitable WebSocket commands for order placement. The SDK signs requests and parses responses, but rate limiting and throttling stay on your side. By the end you should have a solid base for a JavaScript or TypeScript app without a pile of exchange-specific glue code.
Key Takeaways
- Bitget runs V2 (classic accounts) and V3 (Unified Trading Account / UTA) in parallel. The SDK exposes separate clients for each generation.
- HMAC SHA256 signing, headers, and auth for REST and WebSocket are handled inside the client.
- Full TypeScript types cover REST and WebSocket request and response shapes.
WebsocketAPIClientexposes promise-based order placement over a persistent WebSocket connection.- Use Bitget's demo trading environment and your own rate-limit logic before going live.
Integrating Bitget V2 and V3 APIs with TypeScript
Bitget maintains two API generations. V2 covers classic spot, margin, and futures account layouts. V3 is built around the Unified Trading Account (UTA), which is what Bitget positions as the current standard for capital efficiency and cross-product trading in 2026.
If you run algorithmic trading workflows across both, rolling your own wrappers tends to split your codebase and make response parsing fragile. The bitget-api SDK gives you typed clients for both generations:
| Client | Use when |
|---|---|
RestClientV3 | UTA accounts, latest REST endpoints |
WebsocketClientV3 | UTA public and private WebSocket streams |
WebsocketAPIClient | UTA order placement via WebSocket API |
RestClientV2 | Classic account types not yet on UTA |
WebsocketClientV2 | V2 WebSocket streams |
TypeScript matters here. Exchange JSON is messy. Typed responses catch missing fields at compile time instead of mid-trade at runtime.
The Role of bitget-api in Modern Trading Systems
A home-grown Bitget wrapper means maintaining signing, error parsing, endpoint drift, and WebSocket lifecycle code yourself. bitget-api wraps Spot, Futures, and UTA endpoints behind consistent client classes. Types ship for requests and responses across REST and WebSocket.
The SDK does not throttle outbound traffic. Bitget rate limits vary by endpoint (often 1 to 20 requests per second per UID on V3, not a single global cap). Read response headers and queue work in your app if you burst calls.
Environment Setup and Package Installation
Install from npm:
Imported example
npm install bitget-api
Or with yarn:
Imported example
yarn add bitget-api
Turn on strict mode in tsconfig.json so the compiler catches bad parameters early.
For UTA accounts, start with RestClientV3:
Imported example
import { RestClientV3 } from "bitget-api";
const client = new RestClientV3({
apiKey: process.env.API_KEY_COM!,
apiSecret: process.env.API_SECRET_COM!,
apiPass: process.env.API_PASS_COM!, // passphrase from API key setup, not your login password
});
(async () => {
try {
const balances = await client.getBalances();
console.log(balances);
const order = await client.submitNewOrder({
category: "USDT-FUTURES",
orderType: "market",
side: "buy",
qty: "0.001",
symbol: "BTCUSDT",
});
console.log("Order submitted:", order);
} catch (e) {
console.error("request failed:", e);
}
})();
Public endpoints work without credentials:
Imported example
import { RestClientV3 } from "bitget-api";
const client = new RestClientV3();
const tickers = await client.getTickers({ category: "SPOT" });
If you are still on a classic account, use RestClientV2 instead. Same credential shape:
Imported example
import { RestClientV2 } from "bitget-api";
const client = new RestClientV2({
apiKey: process.env.API_KEY_COM!,
apiSecret: process.env.API_SECRET_COM!,
apiPass: process.env.API_PASS_COM!,
});
const account = await client.getSpotAccount();
REST and WebSocket use different client classes. That mirrors how Bitget splits protocols and keeps each connection lifecycle clear.
Mastering Bitget Authentication and Request Signing
Bitget private endpoints need three values: API key, secret, and passphrase (the one you set when creating the key). The SDK reads them as apiKey, apiSecret, and apiPass.
V3 enforces signature checks on private REST and WebSocket traffic. Each signed request builds a string from timestamp, HTTP method, request path, and body (or query string for GET), then signs it with HMAC SHA256. The result goes in the ACCESS-SIGN header alongside ACCESS-KEY, ACCESS-PASSPHRASE, and ACCESS-TIMESTAMP.
Secure API Key Management
Use least privilege on every key:
- Market data only: read permissions.
- Trading bots: enable spot or futures trading, keep withdrawals off.
- Never commit keys. Use environment variables or a secrets manager locally via
dotenv, with.envexcluded from git.
Bitget does not offer a separate testnet URL in this SDK. For safe development, use demo trading: create demo API keys in the demo trading environment and pass demoTrading: true. That adds the paptrading: 1 header on REST and routes WebSockets to demo endpoints.
Imported example
import { RestClientV3 } from "bitget-api";
const client = new RestClientV3({
apiKey: process.env.API_KEY_COM!,
apiSecret: process.env.API_SECRET_COM!,
apiPass: process.env.API_PASS_COM!,
demoTrading: true,
});
Multiple accounts? Instantiate one client per credential set.
Automated Request Signing Mechanics
You should not hand-build signing strings in production. One wrong character or body encoding fails auth immediately.
The REST client signs every private call internally. For latency-sensitive Node.js backends, you can inject Node's native createHmac instead of the default Web Crypto signer:
Imported example
import { createHmac } from "crypto";
import { RestClientV3 } from "bitget-api";
const client = new RestClientV3({
apiKey: process.env.API_KEY_COM!,
apiSecret: process.env.API_SECRET_COM!,
apiPass: process.env.API_PASS_COM!,
customSignMessageFn: async (message, secret) => {
return createHmac("sha256", secret).update(message).digest("base64");
},
});
The SDK also supports RSA key signing. See examples/auth/rest-private-rsa.ts in the repo.
Clock sync: REST signing uses Date.now() on your machine. The SDK does not auto-sync your clock on startup. If you see timestamp or recvWindow errors, fix system time or call fetchLatencySummary() on RestClientV3 to measure drift against Bitget's server time:
Imported example
const latency = await client.fetchLatencySummary();
console.log(latency.timeDifference); // ms between local clock and server
For WebSockets, setTimeOffsetMs() exists on WebsocketClientV3 and WebsocketAPIClient if you compute an offset yourself.
More patterns: Bitget TypeScript tutorial.
Why Engineers Choose Siebly over DIY Bitget Wrappers
A quick Axios wrapper feels fine until Bitget ships endpoint changes and your signing helper breaks across dozens of routes. Teams often end up maintaining hundreds of lines that never touch trading logic.
Generic multi-exchange libraries like CCXT cover many venues but flatten exchange-specific behavior. A Bitget-focused SDK keeps UTA types, V3 WebSocket order channels, and Bitget error codes aligned with the official docs without waiting on upstream releases.
Boilerplate Reduction and Engineering Velocity
Compare a raw integration (manual headers, timestamp, signature string, response typing) with the SDK client above. The difference in code volume is large. IntelliSense on typed responses catches wrong property names during development instead of in production.
Reliability and Error Handling
Failed exchange calls need structured errors, not a generic 500 string. With parseExceptions enabled (default), the REST client throws an object containing HTTP status, Bitget code / msg in body, and response headers so you can branch on insufficient margin, invalid size, or permission errors.
WebSocket clients emit open, reconnect, reconnected, authenticated, update, and exception events. Reconnection and resubscription run inside the client after drops.
Again: no built-in rate limiting. Track headers and shape your own backoff.
Building Reliable WebSocket Workflows for Real-Time Data
REST is fine for balances and history. Live execution and market feeds need WebSockets.
The SDK separates two WebSocket patterns:
- Subscriptions - passive streams (ticker, order book, fills, account updates).
- Commands - active requests on the V3 WebSocket API (place or cancel orders).
WebsocketAPIClient wraps command channels in Promises, so await wsClient.submitNewOrder(...) feels like REST but rides a warm connection.
Awaitable WebSocket Commands for Execution
Imported example
import { WebsocketAPIClient } from "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,
});
// Optional: warm the WS API connection before first order
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("place-order response:", res);
} catch (e) {
console.error("submitNewOrder failed:", e);
}
// Cancel by client order id
await wsClient.cancelOrder("spot", { clientOid: "my-order-id" });
Requires V3 / UTA API keys. V2 WebSockets do not expose this order channel; use RestClientV2 or RestClientV3 REST methods there.
Handling Real-Time Market Data Streams
For public market data on UTA, use WebsocketClientV3:
Imported example
import { WebsocketClientV3, WS_KEY_MAP } from "bitget-api";
const wsClient = new WebsocketClientV3();
wsClient.on("update", (data) => {
console.log("market update:", data);
});
wsClient.on("reconnected", (data) => {
console.log("reconnected:", data?.wsKey);
});
wsClient.subscribe(
{
topic: "ticker",
payload: { instType: "spot", symbol: "BTCUSDT" },
},
WS_KEY_MAP.v3Public,
);
// Multiple symbols in one call
wsClient.subscribe(
[
{ topic: "ticker", payload: { instType: "spot", symbol: "BTCUSDT" } },
{ topic: "ticker", payload: { instType: "spot", symbol: "ETHUSDT" } },
],
WS_KEY_MAP.v3Public,
);
The client handles heartbeats, reconnect, and resubscribe after disconnects. It delivers parsed events; it does not maintain a local order book state machine for you. For merged depth snapshots and incremental book maintenance, pair the stream with your own logic or a library like orderbooks.
Private account streams (balances, orders, positions) use WebsocketClientV3 with API credentials on WS_KEY_MAP.v3Private. See examples/V3 - UTA/Websocket/ws-private.ts.
Full walkthrough: Bitget JavaScript Quickstart.
Production Deployment Best Practices with bitget-api
Going live means operational discipline, not just working code. The SDK handles protocol details; you own queues, monitoring, and key hygiene.
Testing and Verification in Simulation
Start on demo trading with demoTrading: true and demo keys. Exercise auth, orders, and error paths without real capital.
Mock REST responses in unit tests for edge cases (insufficient balance, bad tick size, expired keys). For architecture patterns around long-running bots, see our Algorithmic Trading System Architecture guide.
WebSocket demo mode:
Imported example
import { WebsocketClientV2 } from "bitget-api";
const wsClient = new WebsocketClientV2({
demoTrading: true,
apiKey: process.env.API_KEY_COM!,
apiSecret: process.env.API_SECRET_COM!,
apiPass: process.env.API_PASS_COM!,
});
Scaling for Performance
Large ingest workloads may need several WebSocket connections across symbols or account partitions. If multiple Node.js processes share order state, centralize state in Redis or similar rather than assuming one process owns the truth.
The SDK targets high-volume WebSocket use: persistent connections, reconnect, and typed events. Your app decides how to consume and act on them.
The package ships llms.txt and consistent method names, which helps AI coding agents generate correct calls. For prompt templates, see Siebly.io AI.
Before production: no withdrawal permission on bot keys, secrets out of source control, and rate limits enforced in your layer.
Standardizing Your Bitget Integration for 2026
A maintainable Bitget integration needs typed clients, correct signing, and stable WebSocket behavior. bitget-api covers V2 and V3, REST and WebSocket, and promise-based WS order placement without a custom signing layer in your repo.
Move from demo trading to live keys when tests pass. Keep throttling and monitoring in your application; the SDK stays intentionally thin on traffic shaping.
Explore the Bitget JavaScript SDK on Siebly.io for REST and WebSocket clients with full TypeScript support.
Frequently Asked Questions
Does the Bitget API SDK handle rate-limiting automatically?
No. The bitget-api SDK does not throttle or queue requests. Limits depend on the endpoint (check Bitget docs and inline comments in RestClientV3 / RestClientV2). Watch response headers and implement your own queue or leaky bucket if you burst traffic.
How do I use the Bitget V3 API with TypeScript?
Install bitget-api, use RestClientV3 and WebsocketClientV3 (or WebsocketAPIClient for WS orders), and pass UTA API credentials. Types for UTA request and response shapes are exported from the package.
What is the difference between Bitget V2 and V3 APIs?
V3 targets the Unified Trading Account: shared margin across products and the latest endpoint set. V2 remains for classic account layouts. New UTA projects should default to V3 clients; use V2 clients only if your account has not migrated.
Can I place orders via WebSockets using the bitget-api package?
Yes, on V3 / UTA. Use WebsocketAPIClient methods like submitNewOrder, placeBatchOrders, cancelOrder, and cancelBatchOrders. Each returns a Promise resolved when the matching WS API response arrives.
How do I handle WebSocket reconnections in the Bitget SDK?
WebsocketClientV2 and WebsocketClientV3 reconnect automatically, send heartbeats, and resubscribe prior topics after a drop. Listen for reconnect and reconnected if you need to log or meter connection health.
Is there a Bitget testnet available for development?
Bitget's paper environment is demo trading, not a separate testnet hostname in this SDK. Create demo API keys, set demoTrading: true on REST and WebSocket clients, and route traffic there before using live keys.
What are the security best practices for Bitget API keys?
Least privilege (no withdrawals on automation keys), environment-based secret storage, regular key rotation, and demo trading for initial development.
How do I synchronise my system clock with Bitget servers?
REST signing uses your local Date.now(). Call fetchLatencySummary() on RestClientV3 to check drift, keep OS time accurate (NTP), or set a manual offset on WebSocket clients via setTimeOffsetMs() after you compute one. There is no automatic clock sync on client construction.
Related articles
Continue from here