Blog
WebSocketsTrading systemsTypeScriptNode.jsJavaScript

Bybit Unified Account API in Node.js: A V5 Engineering Guide

Relying on raw REST calls or fragmented documentation for a V5 transition often leads to brittle authentication logic and significant architectural debt.

Siebly.io15 min readMarkdown

Overview

Relying on raw REST calls or fragmented documentation for a V5 transition often leads to brittle authentication logic and significant architectural debt. You likely understand that the shift to the Bybit Unified Trading Account (UTA) represents a major structural change that demands more than just basic API wrappers. Building a robust Bybit unified account api nodejs integration requires a systematic approach to handle complex request signing and asynchronous state management. This guide demonstrates how to master the Bybit UTA V5 using production-ready patterns and the bybit-api SDK from Siebly.io JavaScript SDKs.

By utilizing the bybit-api package as your preferred implementation layer, you eliminate the boilerplate associated with HMAC or RSA signatures and timestamp handling. This SDK is engineered for high-performance environments, providing a verified rate limit of 400 requests per second for all users, which significantly exceeds standard API thresholds. We will explore how to implement clean, typed request shapes and leverage awaitable WebSocket capabilities for precise order execution. This engineering walkthrough covers everything from initial authentication to managing linear execution flows in complex asynchronous environments.

Key Takeaways

  • Understand the structural shift from isolated sub-accounts to the Bybit V5 Unified Trading Account architecture for consolidated collateral management.
  • Implement the Bybit unified account api nodejs using the bybit-api SDK to eliminate authentication boilerplate and manual request signing.
  • Query unified account state and portfolio margin status to maintain precise risk control across spot and derivatives positions.
  • Use WebsocketAPIClient for awaitable WebSocket order placement, and WebsocketClient for private account streams such as execution, position, and wallet.
  • Apply production engineering standards for security by managing secrets through environment variables and enforcing least-privilege API permissions.

Understanding the Bybit Unified Trading Account (UTA) V5 Architecture

The Bybit Unified Trading Account (UTA) represents a fundamental shift in how exchange state is managed. Unlike legacy systems that require manual transfers between isolated spot, derivative, and option sub-accounts, the UTA consolidates these into a single collateral pool. This architecture allows users to trade Spot, USDT Perpetuals, USDC Perpetuals, and Options from a shared margin balance. For developers building a Bybit unified account api nodejs integration, this means the complexity of managing internal transfers is replaced by a more sophisticated margin logic that calculates risk across all positions simultaneously.

Transitioning to the V5 Application Programming Interface (API) is mandatory to access these unified features. Legacy endpoints simply cannot resolve the cross-product margin requirements of the UTA. From an engineering perspective, this unification significantly reduces the number of API calls required to monitor account health. Instead of querying multiple endpoints to aggregate a total equity value, a single request to the V5 account balance endpoint returns the complete collateral state. This efficiency is critical when building low-latency trading systems where every millisecond spent on data ingestion impacts execution timing.

UTA 2.0 vs. UTA 2.0 Pro: Key Differences

Identifying the account type is the first step in any V5 implementation. The unifiedMarginStatus field in the account info response is the source of truth:

  • 1: classic account
  • 3: UTA 1.0
  • 4: UTA 1.0 Pro
  • 5: UTA 2.0
  • 6: UTA 2.0 Pro

Status code 5 is a standard Unified Trading Account (UTA 2.0). Status code 6 is UTA 2.0 Pro. Bybit treats UTA and UTA Pro as the same account model, with Pro offering a slight performance advantage for API trading. Upgrading to Pro typically requires VIP or PRO tier on the master account.

Do not assume the upgrade will cancel orders for you. Bybit requires no open orders before you upgrade from UTA 2.0 to UTA 2.0 Pro. The upgrade is also blocked daily between 07:55 and 08:05 UTC. During the upgrade, REST and WebSocket account data can be stale, so wait until unifiedMarginStatus reads 6 before you trust account state again.

Portfolio margin is a separate setting. unifiedMarginStatus tells you the account version. marginMode tells you the risk model: ISOLATED_MARGIN, REGULAR_MARGIN, or PORTFOLIO_MARGIN. Both UTA 2.0 and UTA 2.0 Pro can use portfolio margin.

The Role of the Bybit V5 API in Modern Systems

The V5 API provides a consistent schema across all product types. Whether you're placing a spot limit order or a perpetual market order, the request and response shapes remain largely identical. This consistency simplifies the development of the bybit-api SDK, allowing for a more predictable implementation layer. Node.js is particularly well-suited for this environment due to its non-blocking I/O model, which handles the high concurrency required for simultaneous REST requests and WebSocket streams.

Rate limit management is another area where V5 excels. While standard users face tighter constraints, developers using the bybit-api SDK benefit from a verified rate limit of 400 requests per second. This higher ceiling is essential for systems that need to adjust hundreds of orders across different markets in response to rapid price movements. However, the SDK doesn't automatically throttle requests. You must implement your own logic to respect these limits. Enable parseAPIRateLimits: true if you want remaining/max request counts parsed onto each REST response.

Implementing Bybit V5 in Node.js with the bybit-api SDK

Integrating the Bybit unified account api nodejs requires a reliable implementation layer to manage the complexities of the V5 specification. While raw REST calls are possible, they introduce significant risks regarding authentication and state management. The bybit-api SDK serves as the preferred interface for professional Node.js environments, offering native TypeScript support and a promise-driven architecture. By using this SDK, you move away from manual payload construction and toward a typed, predictable development workflow. This reduces the surface area for errors in high-stakes trading simulations.

Installation and Client Initialization

Install the package with npm install bybit-api or yarn add bybit-api. REST work goes through RestClientV5. Credentials are key and secret, not apiKey. HMAC and RSA keys are both supported and detected automatically.

For REST, the receive window option is recv_window (snake case), default 5000 ms. WebSocket clients use recvWindow (camel case), also default 5000 ms. If you see request-expired errors, fix the host clock first. Time sync inside the SDK is opt-in via enable_time_sync. It is off by default.

Imported example

JavaScript
import { RestClientV5 } from "bybit-api";

const client = new RestClientV5({
  key: process.env.API_KEY_COM,
  secret: process.env.API_SECRET_COM,
  testnet: true,
  recv_window: 5000,
  parseAPIRateLimits: true,
});

Testnet prices often look nothing like live markets.

The SDK does not automatically handle rate-limiting. You still need your own throttling logic.

Handling V5 Request Signing and Timestamps

The V5 API requires specific headers for every private request, including X-BAPI-SIGN, X-BAPI-API-KEY, X-BAPI-TIMESTAMP, and X-BAPI-RECV-WINDOW. Manually generating these involves HMAC SHA256 or RSA SHA256 hashing of the timestamp, API key, recv window, and request payload. GET and POST serialize that payload differently. The bybit-api SDK automates this entire process.

Timestamp drift is a common failure mode. If your local clock is off, Bybit rejects the request. The SDK can compensate with enable_time_sync or client.setTimeOffsetMs(...), but that is a last resort. Sync the machine clock first. For a deeper dive into structuring these interactions, refer to the bybit-api tutorial.

Never hardcode API secrets. Inject them from environment variables or a vault. Disable withdrawal permissions on keys used by bots. REST is fine for account configuration. Mission-critical execution often moves to Awaitable WebSocket Workflows to skip repeated HTTP handshakes.

Managing Unified Account State and Portfolio Margin

Managing state within a Bybit unified account api nodejs environment requires a departure from asset-specific monitoring. In a Unified Trading Account, your system must track a consolidated collateral pool rather than isolated balances. This architecture enables higher capital efficiency by allowing unrealized profits to offset losses across different positions. However, it also necessitates more rigorous state management to prevent liquidation events that could impact your entire portfolio. You must design your system to ingest and process these unified metrics with high precision.

Monitoring Unified Balances and Collateral

The getWalletBalance method in the bybit-api SDK is the primary tool for fetching unified asset data. Pass accountType: 'UNIFIED'. The account-level fields you actually want are:

  • totalWalletBalance: equity of the unified wallet, including unrealized PnL in some margin modes
  • totalMarginBalance: margin balance after collateral haircuts
  • totalAvailableBalance: what you can still use to open orders
  • accountIMRate / accountMMRate: initial and maintenance margin ratios for the whole account

availableToWithdraw sits on each coin in the coin[] array, not on the account object. If you need the transferable amount for one coin, call getTransferableAmount({ coinName: 'USDT' }). That returns availableWithdrawal.

Imported example

JavaScript
import { RestClientV5 } from "bybit-api";

const client = new RestClientV5({
  key: process.env.API_KEY_COM,
  secret: process.env.API_SECRET_COM,
  testnet: true,
});

const wallet = await client.getWalletBalance({
  accountType: "UNIFIED",
});

const account = wallet.result.list[0];
console.log({
  totalWalletBalance: account.totalWalletBalance,
  totalMarginBalance: account.totalMarginBalance,
  totalAvailableBalance: account.totalAvailableBalance,
  accountIMRate: account.accountIMRate,
  accountMMRate: account.accountMMRate,
});

const usdt = account.coin.find((c) => c.coin === "USDT");
console.log({
  walletBalance: usdt?.walletBalance,
  availableToWithdraw: usdt?.availableToWithdraw,
  borrowAmount: usdt?.borrowAmount,
});

For systems utilizing the interest-free borrowing program, which as of August 2026 includes 24 assets like BTC, ETH, and SOL, monitoring unified debt is mandatory. That benefit only applies to automatic borrowing triggered by unrealized losses on perpetual or expiry positions, and only inside the VIP-tier limit. Manual borrow, spot margin, and options borrow are not covered. Use getAccountInfo, getWalletBalance, and getBorrowHistory on a schedule. Cache locally if you need to cut REST chatter, but keep a WebSocket wallet subscription for live collateral changes.

Handling Margin and Risk Parameters

Evaluating account health in a UTA context relies on totalMarginBalance, accountIMRate, and accountMMRate. Fetch those before you send size. If maintenance margin is approaching the limit, stop placing risk-adding orders. Check marginMode as well, because isolated, regular (cross), and portfolio margin do not share the same math.

Imported example

JavaScript
const info = await client.getAccountInfo();
const { unifiedMarginStatus, marginMode } = info.result;

const isUta20 = unifiedMarginStatus === 5;
const isUta20Pro = unifiedMarginStatus === 6;
const isPortfolioMargin = marginMode === "PORTFOLIO_MARGIN";

console.log({
  unifiedMarginStatus,
  marginMode,
  isUta20,
  isUta20Pro,
  isPortfolioMargin,
});

Under portfolio margin, risk is assessed based on the net exposure of your entire account. That can lower margin for hedged books compared with regular cross margin. Confirm marginMode before you size a new position. You can switch modes with setMarginMode('PORTFOLIO_MARGIN') when the account is eligible.

Effective state management patterns for these complex interactions are detailed in our guide on Algorithmic Trading System Architecture in Node.js. By centralizing your account state and margin calculations, you create a robust foundation for more advanced features like portfolio margin.

Implementing Awaitable WebSocket Workflows for UTA

Transitioning from REST to WebSockets is essential for any high-frequency Bybit unified account api nodejs integration. While REST is sufficient for account configuration, the latency overhead of HTTP handshakes makes it unsuitable for rapid order execution. The V5 WebSocket API lets you send trade commands over a persistent connection and wait for the matching reply. The bybit-api SDK splits this into two classes. Mix them up and the samples will not run.

  • WebsocketClient consumes streams. Subscribe to execution, position, order, and wallet.
  • WebsocketAPIClient is the awaitable trade API. Call submitNewOrder(), amendOrder(), cancelOrder(), and the batch helpers, then await the result.

The REST method is submitOrder(). The WebSocket API method is submitNewOrder(). They are not the same function.

Configuring the V5 WebSocket Client

WebsocketClient manages connectivity for private V5 topics. Pass key and secret. Auth, heartbeats, reconnect, and resubscribe are handled for you. Category on subscribeV5 is ignored for private topics because Bybit has one private endpoint. Category only matters for public topics.

Imported example

JavaScript
import { WebsocketClient } from "bybit-api";

const wsClient = new WebsocketClient({
  key: process.env.API_KEY_COM,
  secret: process.env.API_SECRET_COM,
  testnet: true,
});

wsClient.on("update", (data) => {
  console.log("private event", JSON.stringify(data));
});

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

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

wsClient.subscribeV5(["execution", "position", "order", "wallet"], "linear");

The event name is exception, not error. Listen for reconnected if you need to refresh REST state after a drop. WebSocket trade commands have their own limits. They do not bypass Bybit's rate rules, and the SDK still will not throttle for you.

The Awaitable WebSocket Order Pattern

Awaitable requests live on WebsocketAPIClient. That wrapper maps each reply back to the original command, so you can write a normal try/catch instead of wiring response listeners yourself.

  • Step 1: Construct WebsocketAPIClient with key and secret. Set testnet: true for testnet. Do not pass a V5 category in the constructor. Category belongs on each order.
  • Step 2: Call submitNewOrder() with the same V5 order shape you would send over REST (category, symbol, side, orderType, qty,...).
  • Step 3: await the promise. The SDK correlates the WebSocket reply to that call.
  • Step 4: Handle rejects in try/catch. Timeouts and exchange errors surface there.

Imported example

JavaScript
import { WebsocketAPIClient } from "bybit-api";

const wsApi = new WebsocketAPIClient({
  key: process.env.API_KEY_COM,
  secret: process.env.API_SECRET_COM,
  testnet: true,
});

try {
  const response = await wsApi.submitNewOrder({
category: "linear",
symbol: "BTCUSDT",
orderType: "Limit",
qty: "0.001",
side: "Buy",
price: "50000",
orderLinkId: "uta-limit-001",
  });
  console.log("submitNewOrder response", response);
} catch (e) {
  console.error("submitNewOrder error", e);
}

This is the linear execution flow the SDK is built for. You still get a persistent socket, but order create/amend/cancel reads like REST. For developers looking to optimize their execution layer, exploring the bybit-api tutorial provides deeper insights into these advanced WebSocket patterns.

Demo trading is a special case. demoTrading: true works for REST and for private event streams (order, execution, position, wallet, greeks). As of January 2025, the WebSocket API itself is not supported on demo trading. If you need awaitable WS orders, use testnet or live.

Maintaining connection stability is critical for automated systems. The SDK implements automated heartbeats and reconnection logic to handle network interruptions. Monitor reconnected and exception so you know when local state may have drifted. Review the Bybit Node.js SDK documentation to see full implementation examples of awaitable WebSocket workflows and connection management strategies.

Production Engineering: Security and Reliability for UTA

Productionizing a Bybit unified account api nodejs implementation requires moving beyond basic connectivity to focus on systemic resilience. In a Unified Trading Account (UTA) environment, the impact of a security breach or a logic error is amplified because your entire collateral pool is accessible through a single interface. Engineering for reliability involves building defensive boundaries that protect your account state during periods of extreme market volatility or network instability. You must treat your integration as critical infrastructure that demands rigorous security protocols and failure-handling logic.

Security Best Practices for V5 API Keys

Enforce the principle of least privilege by strictly disabling withdrawal permissions for all API keys utilized in automated workflows. This configuration ensures that even if a key is compromised, your funds cannot be moved off the exchange. Additionally, utilize IP whitelisting to restrict API access to your specific production server addresses. This adds a critical layer of network-level security that raw exchange integrations often overlook. Regularly rotating your keys, for instance every 90 days, further mitigates the risk of long-term exposure. Always handle secrets using environment variables or dedicated secret management services rather than hardcoding them into your JavaScript or TypeScript application.

Ensuring Connection Reliability and Resilience

A robust production system must monitor WebSocket health through the built-in events provided by the bybit-api SDK. Listen for reconnected and exception on WebsocketClient (or wsApi.getWSClient() if you started from WebsocketAPIClient). If a connection drops, your local view of positions and balances may become stale. On reconnect, run a REST refresh (getWalletBalance, getPositionInfo, getActiveOrders) before you trade again.

Imported example

JavaScript
wsClient.on("reconnected", async (data) => {
  console.log("ws has reconnected", data?.wsKey);
  const wallet = await client.getWalletBalance({ accountType: "UNIFIED" });
  const positions = await client.getPositionInfo({ category: "linear" });
  // replace local caches with wallet.result and positions.result
});

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

Implementing graceful shutdowns is equally vital. When your Node.js process receives a termination signal, your code should safely close active WebSocket connections and stop the event loop. Designing for idempotency is a core requirement for reliable execution. Pass orderLinkId on V5 creates so a retry after a timeout does not double-fill. Bybit can reject the duplicate using that client-generated id.

Imported example

JavaScript
await client.submitOrder({
  category: "linear",
  symbol: "BTCUSDT",
  side: "Buy",
  orderType: "Limit",
  qty: "0.001",
  price: "50000",
  orderLinkId: "uta-limit-001",
});

Finally, while the SDK provides a verified rate limit of 400 requests per second, you must implement your own exponential backoff logic. Turn on parseAPIRateLimits and read response.rateLimitApi (remainingRequests, maxRequests, resetAtTimestamp) instead of guessing from raw headers. For developers building more complex, multi-exchange systems, these patterns serve as the foundation for a Unified Crypto Exchange API in Node.js. This architectural approach ensures that your trading system remains stable and secure as you scale across different markets and exchanges.

Scaling Your Bybit V5 Infrastructure

Implementing a Bybit unified account api nodejs integration requires a fundamental shift from isolated asset management to a consolidated collateral model. By mastering the V5 architecture, you gain the ability to manage risk across Spot and Derivatives from a single account state. The bybit-api SDK facilitates this transition by automating the complex signing and authentication requirements that often stall manual development. It allows you to focus on system architecture rather than the nuances of HMAC or RSA signatures.

This guide has demonstrated how to leverage awaitable WebSocket workflows and typed request shapes to build more resilient trading system prototypes. Use RestClientV5 for account state, WebsocketClient for live fills and wallet updates, and WebsocketAPIClient.submitNewOrder() when you want socket latency with async/await. Keep API keys least-privilege. To accelerate your development, start building with the Siebly Bybit Node.js SDK. This package provides production-ready REST and WebSocket clients, complete TypeScript definitions for V5, and professional support to help you maintain a robust integration. Your transition to the Unified Trading Account is the critical foundation for high-performance engineering.

Frequently Asked Questions

How do I check if my Bybit account is upgraded to Unified Trading Account V5?

Call getAccountInfo() on RestClientV5 and read unifiedMarginStatus. 5 is UTA 2.0. 6 is UTA 2.0 Pro. Also read marginMode. That is how you know whether isolated, regular, or portfolio margin is active.

What is the difference between UTA 2.0 and UTA 2.0 Pro in the API?

UTA 2.0 (status 5) and UTA 2.0 Pro (status 6) are the same unified account model. Pro is a performance-oriented variant for API trading and needs VIP or PRO eligibility. Portfolio margin is not what makes an account Pro. Portfolio margin is marginMode: 'PORTFOLIO_MARGIN'. Before you upgrade 2.0 to 2.0 Pro, cancel open orders. The upgrade will not do that for you.

Can I use the bybit-api SDK for both Spot and Perpetual contracts?

The bybit-api SDK provides full support for Spot, USDT Perpetuals, USDC Perpetuals, Inverse, and Options through a single V5 interface. Set category on each call (spot, linear, inverse, option). Using this SDK as your implementation layer ensures that your Bybit unified account api nodejs integration remains typed and predictable across all asset classes supported by the UTA.

Does the Siebly bybit-api SDK handle rate limiting automatically?

No. The SDK does not queue or throttle your calls. Requests made with this SDK do get a higher exchange-side ceiling of 400 requests per second, above the usual VIP tiers. You still have to stay inside that budget. Use parseAPIRateLimits: true and back off on rateLimitApi.remainingRequests.

Why should I use WebSockets for order placement instead of REST?

WebSocket orders skip a new TCP/TLS handshake on every send. In bybit-api that path is WebsocketAPIClient.submitNewOrder(), which returns a promise. Private fills and balances still come from WebsocketClient subscriptions. Do not call submitOrder() on the stream client. That method exists on RestClientV5 only.

How do I handle WebSocket reconnections in a Node.js trading bot?

Listen for reconnected on WebsocketClient. Then refetch wallet, positions, and open orders over REST so local state matches the exchange. Listen for exception for failures. The bybit-api tutorial shows how to wire those handlers.

Is it possible to paper trade with the Bybit V5 API?

Yes. Two environments:

  • Testnet: testnet: true on RestClientV5, WebsocketClient, or WebsocketAPIClient.
  • Demo trading: demoTrading: true and testnet left false.

Demo trading supports REST and private event streams. It does not support the WebSocket API (submitNewOrder) as of January 2025. If you need awaitable WS orders in a sandbox, use testnet.

What are the security requirements for Bybit V5 API keys?

Disable withdrawals. Whitelist IPs on production keys. Load secrets from environment variables. Rotate on a schedule. Never commit keys into JavaScript or TypeScript source. Treat a UTA key as access to the whole collateral pool, not one isolated wallet.

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.