---
title: "HTX Futures API Node.js SDK: 2026 Implementation Guide"
description: "A 2026 guide to the HTX Futures API Node.js SDK. Build clean, type-safe trading systems and manage awaitable WebSocket orders with the htx-api package."
canonical: "https://siebly.io/blog/htx-futures-api-nodejs-sdk-2026-implementation-guide"
---

# HTX Futures API Node.js SDK: 2026 Implementation Guide

A 2026 guide to the HTX Futures API Node.js SDK. Build clean, type-safe trading systems and manage awaitable WebSocket orders with the htx-api package.

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

Building a production trading system on HTX should not mean reconstructing every request signature or babysitting WebSocket heartbeats yourself. Official docs remain the source of truth, but a raw DIY wrapper gets brittle fast. Signing, clock format, and the split between Linear Swap, Coin Swap, and Delivery endpoints eat time that should go into your own architecture.

This guide shows how [@siebly/htx-api](/sdk/htx/javascript) from Siebly.io is meant to be used in Node.js. You get typed REST clients, a unified subscription client, and an awaitable WebSocket API for order commands. The SDK signs requests and keeps sockets alive. You still own rate limiting, risk checks, and what happens when an order is rejected. By the end you should have a working pattern for HTX market data, positions, and order flow.

## Key Takeaways {#key-takeaways}

- Use [@siebly/htx-api](/sdk/htx/javascript) so REST and WebSocket traffic share one package instead of a pile of one-off wrappers.
- Create API keys with Trade and Read only. Leave withdrawal off for any automated process.
- Drive Linear Swap (and Coin Swap / Delivery) through `FuturesClient`. Cross and isolated are separate method families, not one toggle.
- Place orders over REST or over `WebsocketAPIClient` if you want a promise back on a persistent socket.
- Throttle yourself. HTX private futures traffic is generally 144 requests every 3 seconds per UID, split 72 trade and 72 read. Some endpoints are tighter.



## Simplifying HTX Futures Integration with Siebly.io {#simplifying-htx-futures-integration-with-sieblyio}

HTX derivatives still mix older v1 REST paths with newer V5 private streams and order commands. REST and WebSocket shapes do not match. That is annoying if you are building an [algorithmic trading](https://en.wikipedia.org/wiki/Algorithmic_trading) stack. The HTX SDK from Siebly.io covers Linear Swaps, Coin Swaps, and Delivery Futures in one package, with a separate `SpotClient` if you also need spot.

### The Problem with DIY Exchange API Wrappers {#the-problem-with-diy-exchange-api-wrappers}

A custom wrapper is a maintenance job. HTX has moved parts of derivatives onto V5 sockets while a lot of REST still lives under `/linear-swap-api/v1/`. Signing is picky: HTTP method, host, path, then a sorted query string. Untyped JavaScript will let a bad payload through until live trading rejects it. That is a painful class of bug when you are already racing the clock.

### Siebly.io as the Preferred Implementation Layer {#siebly-io-as-the-preferred-implementation-layer}

[@siebly/htx-api](https://www.npmjs.com/package/@siebly/htx-api) takes the signing and request construction off your plate. You call typed methods and get promises back. TypeScript definitions catch a lot of bad request shapes at compile time.

It does not magically unify every HTX product into one client. You pick `FuturesClient` for derivatives and `SpotClient` for spot. WebSockets go through `WebsocketClient` for streams and `WebsocketAPIClient` for command/response trading. The SDK also does not throttle you. That is intentional. You decide how hard to hit the exchange.

Install it, then import the futures client:

```js title="Imported example"
// npm install @siebly/htx-api
// yarn add @siebly/htx-api
// Node.js 22.13.0 or newer

import { FuturesClient } from "@siebly/htx-api";
```

## Secure Authentication and Request Signing in Node.js {#secure-authentication-and-request-signing-in-nodejs}

Private HTX REST calls use HMAC SHA256 by default (Signature Version 2). The base string is the HTTP method, the host, the path, then a lexicographically sorted list of query parameters. POST JSON bodies are not part of that signature. If you pass an Ed25519 secret, the SDK switches `SignatureMethod` to Ed25519 on its own.

You do not build that string yourself. `FuturesClient` and `SpotClient` do it when you construct them with `apiKey` and `apiSecret`. Linear Swap and Coin Swap use the same signing rules. What changes is the endpoint and the request fields, not the crypto.

One thing the SDK does not do: it does not fetch HTX server time and apply an offset on REST. It signs with your local clock, formatted as `YYYY-MM-DDThh:mm:ss` in UTC. Keep the machine on NTP. If you need a custom clock, pass `customTimestampFn`. There is also `client.getTimestamp()` if you want to measure drift yourself. For WebSocket API auth you can call `setTimeOffsetMs()` on the WS client.

### Configuring the HTX REST Client {#configuring-the-htx-rest-client}

Store keys in environment variables. Do not hard-code them. The constructor also accepts `baseUrl` or `baseUrlKey` if you need a non-default host, and the second argument is a normal axios config (timeouts, proxies, and so on).

That is the right default. Override it only if you know you need `api.hbdm.com` or `api.btcgateway.pro`.

```js title="Imported example"
import { FuturesClient } from "@siebly/htx-api";

// Public market data: no keys needed
const publicClient = new FuturesClient();

const ticker = await publicClient.getLinearSwapTicker({
  contract_code: "BTC-USDT",
});
console.log("Futures ticker:", ticker);

const orderBook = await publicClient.getLinearSwapMarketDepth({
  contract_code: "BTC-USDT",
  type: "step0",
});
console.log("Futures order book:", orderBook);

// Private calls: keys from the environment
const client = new FuturesClient({
  apiKey: process.env.API_FUTURES_KEY,
  apiSecret: process.env.API_FUTURES_SECRET,
});

const accounts = await client.getLinearSwapCrossAccountInfo();
console.log("Cross account info:", accounts);
```

Full option lists live in the [Siebly.io SDK documentation](/sdk/htx/javascript).

### Handling API Timestamps and Replay Attacks {#handling-api-timestamps-and-replay-attacks}

HTX checks the `Timestamp` on private requests. If your clock is too far off, you get a signature or expiry error, not a friendly "sync me" message. Sync the host. Use `getTimestamp()` during bring-up if you want a number to compare.

Least privilege still matters more than clock math. Futures automation needs Trade and Read. Withdrawal should stay off. The same credentials are reused when the SDK signs the private WebSocket handshake. One key policy, both transports.

## Executing Orders and Managing Futures Positions {#executing-orders-and-managing-futures-positions}

Order params are typed objects, not hand-built query strings. HTX futures size is `volume` (contracts), not a coin quantity. Price type is `order_price_type` (`limit`, `market`, `opponent`, and so on). Cross and isolated are different methods: `submitLinearSwapCrossOrder` vs `submitLinearSwapIsolatedOrder`.

The SDK will send what you give it. It will not size the order, check margin, or refuse a stupid price. That logic is yours.

### Order Lifecycle Management {#order-lifecycle-management}

Submit, then track by `order_id` or `client_order_id`. Query open orders, history, and fills. Cancel one or cancel all for a contract.

Batch limits from HTX: isolated batch place is up to 10, cross batch place is up to 25, cancel-by-id is up to 25 per call. Isolated and cross each have their own cancel-all method.

```js title="Imported example"
import { FuturesClient } from "@siebly/htx-api";

const client = new FuturesClient({
  apiKey: process.env.API_FUTURES_KEY,
  apiSecret: process.env.API_FUTURES_SECRET,
});

const contractCode = "BTC-USDT";

// Cross-margin limit order (Linear Swap)
const order = await client.submitLinearSwapCrossOrder({
  contract_code: contractCode,
  direction: "buy",
  offset: "open",
  volume: 1,
  lever_rate: 5,
  order_price_type: "limit",
  price: 10000,
});
console.log("Limit order result:", order);

const openOrders = await client.getLinearSwapCrossOpenOrders({
  contract_code: contractCode,
});
console.log("Open orders:", openOrders);

const orderInfo = await client.getLinearSwapCrossOrderInfo({
  contract_code: contractCode,
  order_id: "1234567890123456",
});
console.log("Order info:", orderInfo);

await client.cancelLinearSwapCrossOrder({
  contract_code: contractCode,
  order_id: "1234567890123456",
});

await client.cancelLinearSwapCrossAllOrders({
  contract_code: contractCode,
});
```

Handle HTX error codes yourself (margin, price band, permission). Do not retry an uncertain write blindly. Generate a client order id, then query by it before you send the same order again.

### Position and Risk Monitoring {#position-and-risk-monitoring}

Fetch positions and accounts with the matching margin family. Cross example:

```js title="Imported example"
const positions = await client.getLinearSwapCrossPositions({
  contract_code: "BTC-USDT",
});
console.log("Cross positions:", positions);

const fills = await client.getLinearSwapCrossFills({
  contract: "BTC-USDT",
  trade_type: 0,
});
console.log("Cross fills:", fills);
```

Leverage is per contract, and HTX requires no open orders on that contract when you change it. Rate limit on leverage switch is 1 request per 3 seconds, not the general 144 window.

```js title="Imported example"
await client.updateLinearSwapCrossLeverage({
  contract_code: "BTC-USDT",
  lever_rate: 5,
});
```

Cross vs isolated is not a single "set margin mode" switch. You call the cross methods or the isolated methods. What you can switch is position mode (one-way `single_side` vs hedge `dual_side`) via `updateLinearSwapCrossPositionMode` / `updateLinearSwapIsolatedPositionMode`, and account type via `updateLinearSwapAccountType` if you are moving onto the unified account.

Trade history is not auto-paginated. Pass `from_id`, page size, and direction yourself and loop until you are done. For more integration patterns see [Siebly AI patterns](/ai/patterns).



## Building Reliable Real-Time Workflows with WebSockets {#building-reliable-real-time-workflows-with-websockets}

REST polling is fine for setup. Live books and fills should go over sockets. [@siebly/htx-api](/sdk/htx/javascript) splits that into:

1. `WebsocketClient` for public market data and private account/order streams
2. `WebsocketAPIClient` for REST-like order commands on a persistent socket

Public streams need no keys. Private streams and the WebSocket API do. The SDK authenticates, heartbeats the connection (`pingInterval`, `pongTimeout`), reconnects (`reconnectTimeout`), and resubscribes topics after a drop. You still have to process messages without blocking the event loop, and you should reload balances, positions, and open orders after a private gap.

### Market Data Ingestion via WebSockets {#market-data-ingestion-via-websockets}

Pass a `WS_KEY_MAP` value so the client opens the right HTX URL. Linear Swap public is `WS_KEY_MAP.linearSwapPublic`. Coin delivery, coin swap, index, and system heartbeats each have their own key.

```js title="Imported example"
import { WebsocketClient, WS_KEY_MAP } from "@siebly/htx-api";

const wsClient = new WebsocketClient();

wsClient.on("open", (data) => {
  console.log("WebSocket connected:", data?.wsKey);
});

wsClient.on("message", (data) => {
  console.log("Data received:", JSON.stringify(data));
});

wsClient.on("reconnected", (data) => {
  console.log("WebSocket reconnected:", data);
});

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

wsClient.subscribe(
  [
"market.BTC-USDT.kline.1min",
"market.BTC-USDT.detail",
"market.BTC-USDT.trade.detail",
"market.BTC-USDT.bbo",
  ],
  WS_KEY_MAP.linearSwapPublic,
);

wsClient.subscribe(
  ["market.BTC-USDT.index.1min", "market.BTC-USDT.mark_price.1min"],
  WS_KEY_MAP.derivativesIndex,
);
```

Subscribe only to what you need. HTX caps topics per connection. `subscribe` / `unsubscribe` are dynamic, so you can drop a symbol when a strategy is idle. More detail is in the [Siebly.io SDK documentation](/sdk/htx/javascript).

Private Linear Swap on accounts that already moved to V5 should use `WS_KEY_MAP.derivativesPrivateV5`, not the legacy `linearSwapPrivate` topics:

```js title="Imported example"
import { WebsocketClient, WS_KEY_MAP } from "@siebly/htx-api";

const wsClient = new WebsocketClient({
  apiKey: process.env.API_FUTURES_KEY,
  apiSecret: process.env.API_FUTURES_SECRET,
});

wsClient.on("authenticated", (data) => {
  console.log("WebSocket authenticated:", data);
});

wsClient.on("message", (data) => {
  console.log("Private data:", JSON.stringify(data));
});

wsClient.subscribe(
  [
"account",
{ topic: "trade", payload: { contract_code: "BTC-USDT" } },
{ topic: "positions", payload: { contract_code: "BTC-USDT" } },
  ],
  WS_KEY_MAP.derivativesPrivateV5,
);
```

Use `contract_code: '*'` on trade/positions if you want every contract. Legacy `orders.BTC-USDT` / `linearSwapPrivate` only still applies if that account has not migrated.

### The Awaitable WebSocket API Pattern {#the-awaitable-websocket-api-pattern}

`WebsocketAPIClient` maps each command to a promise. First request connects and authenticates lazily. You can pre-connect with `client.getWSClient().connectWSAPI(WS_KEY_MAP.linearSwapTrade)` if you want the handshake done before the first order.

V5-style Linear Swap order:

```js title="Imported example"
import { WebsocketAPIClient } from "@siebly/htx-api";

const client = new WebsocketAPIClient({
  apiKey: process.env.API_FUTURES_KEY,
  apiSecret: process.env.API_FUTURES_SECRET,
});

const linearOrder = await client.placeLinearSwapOrder({
  contract_code: "BTC-USDT",
  margin_mode: "cross",
  position_side: "long",
  side: "buy",
  type: "limit",
  time_in_force: "gtc",
  price: "20000",
  volume: "1",
  reduce_only: 0,
});
console.log("placeLinearSwapOrder:", linearOrder);
```

Older Linear Swap WS order shape is still there as `submitLinearSwapOrder` (direction/offset/lever_rate). Delivery and coin swap have `submitCoinDeliveryOrder` and `submitCoinSwapOrder`. Cancels exist too (`cancelLinearSwapOrder`, `cancelAllLinearSwapCrossOrders`, plus V5 cancel helpers).

After a reconnect, subscriptions come back on their own. WS API sessions can re-auth if you leave `reauthWSAPIOnReconnect` enabled. Confirm final order state with REST or a private fill stream. A command reply is not a fill.

To start from the package page, [get the HTX Node.js SDK](/sdk/htx/javascript).

## Production Best Practices for HTX Trading Systems {#production-best-practices-for-htx-trading-systems}

Connectivity is the easy part. Production pain is rate limits, clock drift, and not treating a dropped private socket as "state is still true". Keep market data, execution, and risk on separate paths so a stuck book updater does not freeze cancels.

### Rate Limiting and Resilience {#rate-limiting-and-resilience}

Siebly SDKs do not throttle for you. HTX's usual private futures budget is 144 requests every 3 seconds per UID, split 72 trade / 72 read, shared across API keys on that UID. Public market data is a different budget (often 240/3s per IP, some depth/ticker calls much higher). Leverage switch is 1 per 3 seconds. Master/sub transfers are in the 10/min range.

The SDK returns response bodies. Successful calls currently drop HTTP headers, including `X-HB-RateLimit-Requests-Remain` and `X-HB-RateLimit-Requests-Expire`. Those headers exist on HTX. If you need them, add an axios interceptor via the second constructor argument. Otherwise count your own calls.

Do not auto-retry order placement. WebSocket reconnect is already built in. REST writes are not, on purpose.

### Architectural Safety and Simulations {#architectural-safety-and-simulations}

HTX does not offer a public futures testnet anymore. The old Huobi testnet was shut down. [@siebly/htx-api](/sdk/htx/javascript) has no `testnet: true` flag. Validate against public endpoints first, then use tiny size on live keys with withdrawals disabled. Build your own dry-run layer if you need to fake fills.

Kill-switches still belong in your process: cancel-all, flatten, and a hard stop if latency or error rate blows up. HTX also has a cancel-all-after style call (`setLinearSwapCancelAfter`) if you want the exchange to dump open orders when your heartbeats stop.

For prompt-level integration notes see the [Siebly AI Prompt Framework](/ai). For keeping local state honest after a disconnect, see [exchange state documentation](/ai/exchange-state).

## Advancing Your HTX Engineering Infrastructure {#advancing-your-htx-engineering-infrastructure}

You do not need a homegrown signer for HTX derivatives. [@siebly/htx-api](/sdk/htx/javascript) covers REST, public/private streams, and awaitable WS orders with TypeScript types. Your job is product routing (spot vs futures, cross vs isolated, V5 vs legacy private WS), throttling, and not trusting a socket gap.

Walk the path in this order: public REST, private REST reads, a single small order you immediately cancel, then public WS, then private WS, then WS API if you actually need the latency. Official HTX docs still win when an endpoint changes.

Siebly.io keeps these clients current. Start here: [Explore the Siebly.io HTX SDK documentation](/sdk/htx/javascript).

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

### How do I install the HTX Futures SDK for Node.js? {#how-do-i-install-the-htx-futures-sdk-for-node-js}

Run `npm install @siebly/htx-api` or `yarn add @siebly/htx-api`. The npm name is [@siebly/htx-api](/sdk/htx/javascript), not `htx-api`. Import `FuturesClient` for derivatives, `SpotClient` for spot, `WebsocketClient` for streams, and `WebsocketAPIClient` for awaitable order commands. Node.js 22.13.0 or newer is required.

### Does the Siebly HTX SDK support TypeScript? {#does-the-siebly-htx-sdk-support-typescript}

Yes. The package is written in TypeScript and ships declarations for request and response shapes. That is the main reason to use it instead of an untyped fetch wrapper. Types follow HTX's field names (`contract_code`, `volume`, `lever_rate`), so you still need to read the exchange docs for enums and units.

### How are WebSocket reconnections handled in the `@siebly/htx-api` package? {#how-are-websocket-reconnections-handled-in-the-siebly-htx-api-package}

`WebsocketClient` heartbeats the socket, reconnects after `reconnectTimeout`, and resubscribes the topics it already had. You get `reconnecting` and `reconnected` events. Tune `pingInterval`, `pongTimeout`, and `reconnectTimeout` on the client options. After a private disconnect, refetch account, positions, and open orders. Resubscribe restores the stream, not the messages you missed.

### Can I use this SDK for both HTX Spot and Futures trading? {#can-i-use-this-sdk-for-both-htx-spot-and-futures-trading}

Yes. One package, two REST clients: `SpotClient` and `FuturesClient`. Streams share `WebsocketClient` with a `WS_KEY_MAP` entry per product. `WebsocketAPIClient` covers both spot (`submitSpotOrder`) and derivatives (`placeLinearSwapOrder`, plus coin swap/delivery helpers). Auth options are the same shape on all of them.

### Does the SDK automatically handle HTX API rate limits? {#does-the-sdk-automatically-handle-htx-api-rate-limits}

No. You throttle. Private futures is generally 144/3s per UID (72 trade, 72 read). That is not a 2026-only rule, it is what HTX documents today, and individual endpoints can be stricter. The SDK does not queue or sleep for you.

### How do I sign private requests for HTX Futures? {#how-do-i-sign-private-requests-for-htx-futures}

Pass `apiKey` and `apiSecret` into the client. The library builds Signature Version 2 (HMAC SHA256, or Ed25519 if that is the key type), sorts query params, and attaches `Timestamp`. You do not sign v1 vs V5 paths differently. V5 in HTX usually means the newer private WS and some order commands, not a second signing scheme.

### Is it possible to place orders via WebSockets with this library? {#is-it-possible-to-place-orders-via-websockets-with-this-library}

Yes. Use `WebsocketAPIClient`. `placeLinearSwapOrder` is the V5 Linear Swap command. `submitLinearSwapOrder` is the older Linear Swap WS order. Both return promises. The socket is created on first use unless you call `connectWSAPI` yourself.

### Where can I find examples for HTX Linear Swap integration? {#where-can-i-find-examples-for-htx-linear-swap-integration}

In the [GitHub examples](https://github.com/sieblyio/htx-api/tree/main/examples) under `examples/Derivatives/` (REST, public WS, private WS, WS API) and in the [Siebly HTX JavaScript tutorial](/sdk/htx/javascript/tutorial). Those snippets are engineering samples. They are not trading advice. HTX has no public testnet, so treat every private example as live unless you stub it.

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

- [HTX - new addition to Siebly SDKs](/blog/htx-new-addition-to-siebly-sdks)
- [KuCoin Futures API Node.js SDK: 2026 Integration Guide](/blog/kucoin-futures-api-nodejs-sdk-2026-integration-guide)
- [Binance Futures API Node.js SDK: A Production-Ready Engineering Guide](/blog/binance-futures-api-nodejs-sdk-a-production-ready-engineering-guide)


## Related Siebly Resources

- [Siebly SDK directory](/sdk)
- [Siebly AI Prompt Framework & Skills](/ai)
- [Exchange State Management](/ai/exchange-state)
- [Runnable exchange API examples](/examples)
- [SDK security and release integrity](/security)
