---
title: "KuCoin Node.js SDK: A Guide to Modern Exchange Integration"
description: "Build a production-ready KuCoin integration with a modern Kucoin node sdk. Eliminate auth boilerplate and leverage awaitable WebSockets in your Node.js app."
canonical: "https://siebly.io/blog/kucoin-nodejs-sdk-a-guide-to-modern-exchange-integration"
---

# KuCoin Node.js SDK: A Guide to Modern Exchange Integration

Build a production-ready KuCoin integration with a modern Kucoin node sdk. Eliminate auth boilerplate and leverage awaitable WebSockets in your Node.js app.

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

If you have integrated KuCoin the hard way, you already know the pain: HMAC-SHA256 request signing, a passphrase that is easy to get wrong, and official Node.js wrappers that no longer move. Building a custom Kucoin node sdk from scratch means you own timestamps, headers, reconnects, and every API change after that.

This guide shows how to use [kucoin-api](/sdk/kucoin/javascript), a TypeScript-first Node.js SDK, as the implementation layer. You will wire REST clients, subscribe to public and private WebSockets, and place orders over the WebSocket API with async/await. Official KuCoin docs stay the source of truth for endpoints. Rate limits and throttling stay in your application. We will also cover Classic REST plus the Unified Trading Account (UTA / Pro) API surface.

## Key Takeaways {#key-takeaways}

- The official KuCoin Node.js and Futures SDKs were archived on March 4, 2025. A maintained Kucoin node sdk avoids sitting on a read-only repo.
- Pass your API key, secret, and passphrase into the client. The SDK signs REST and WebSocket requests with HMAC-SHA256. You do not hand-roll the pre-hash string.
- Use `WebsocketAPIClient` when you want awaitable order calls over a persistent WebSocket, instead of matching request IDs yourself.
- The SDK does not throttle for you. Rate limits depend on VIP level and whether you hit UTA or Classic endpoints.
- Heartbeats, reconnect, and topic resubscribe are built in. After a drop, still reconcile your local order and balance state.



## The Current State of KuCoin Node.js SDKs {#the-current-state-of-kucoin-nodejs-sdks}

On March 4, 2025, KuCoin archived [kucoin-node-sdk](https://github.com/Kucoin/kucoin-node-sdk) and [kucoin-futures-node-sdk](https://github.com/Kucoin/kucoin-futures-node-sdk). Both repos are read-only. KuCoin pointed people at a multi-language Universal SDK. That is a real shift, and it is also a red flag if your production stack still imports those archived packages: no security patches, no dependency updates, no coverage for newer API families.

You can keep a raw REST client in-house, or you can use a maintained Kucoin node sdk. The first option means you own every signing bug and every endpoint rename.

### Why Official SDK Deprecation Matters {#why-official-sdk-deprecation-matters}

Archived code and a live exchange drift apart. As of August 2026, KuCoin still ships Classic REST (spot on `api.kucoin.com`, futures on `api-futures.kucoin.com`) and a Unified Trading Account API under `/api/ua/v1`. In June 2026 they moved the Pro API onto that UTA surface and said UTA would be the focus going forward. Archived Node wrappers do not track that split.

When the official tool is frozen, HMAC-SHA256, passphrase headers, and VIP rate-limit changes all land on your team. That is a bad place to be during a volatility spike.

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

[kucoin-api](/sdk/kucoin/javascript) is a TypeScript-first SDK. Most request and response shapes are typed. Official docs remain the source of truth for what an endpoint accepts.

It is not one mega-client. REST is split on purpose:

- `SpotClient` - spot and margin
- `FuturesClient` - futures
- `BrokerClient` - broker and sub-accounts
- `UnifiedAPIClient` - UTA / Pro endpoints across spot, futures, and margin (`tradeType` selects the market)

WebSockets go through `WebsocketClient` (streams) and `WebsocketAPIClient` (awaitable trading over WS).

The SDK handles networking and signing. It does not auto-throttle. You implement rate-limit logic for your VIP level and endpoint family.

## Authentication and Request Signing for KuCoin {#authentication-and-request-signing-for-kucoin}

KuCoin private calls need three credentials: API key, API secret, and API passphrase. That passphrase is not your account password. It is the string you set when you created the key.

Signing is HMAC-SHA256. The pre-hash string is:

`timestamp + HTTP method + /endpoint + body-or-query`

The passphrase is not part of that pre-hash. For API key version 2 (the SDK default), the passphrase is HMAC-SHA256 signed on its own and sent as `KC-API-PASSPHRASE`. The request signature goes in `KC-API-SIGN`. Manual implementations usually fail on JSON body serialisation, query string encoding, or clock skew.

Pass the three values into the constructor. The client signs REST and private WebSocket traffic from there.

```js title="Imported example"
const { SpotClient } = require("kucoin-api");

const client = new SpotClient({
  apiKey: process.env.KUCOIN_API_KEY,
  apiSecret: process.env.KUCOIN_API_SECRET,
  apiPassphrase: process.env.KUCOIN_API_PASSPHRASE,
});
```

Same shape for `FuturesClient` and `UnifiedAPIClient`. Public market data does not need keys. Create an empty client if you only read tickers and books.

The SDK does not rate-limit you. Keep that in your app.

### Managing API Credentials Safely {#managing-api-credentials-safely}

Keep keys in environment variables. Never commit them. Use least privilege: trading automation should not have withdrawal permission. That lines up with broader industry talk, including SEC Proposed Crypto Regulations, on how digital assets and access credentials should be safeguarded. A dedicated [KuCoin JavaScript SDK](/sdk/kucoin/javascript) at least keeps signing in one place instead of copy-pasted header code.

### Handling Timestamps and Clock Skew {#handling-timestamps-and-clock-skew}

KuCoin rejects signed requests when your `KC-API-TIMESTAMP` is more than 5 seconds off server time (error 400002). The SDK uses `Date.now()` unless you pass `customTimestampFn`. It does not generate nonces. There is no nonce in this auth scheme.

Sync the host with NTP. If you still see skew, call `getServerTime()` (`GET /api/v1/timestamp`) and feed a corrected clock into `customTimestampFn`. `SpotClient` also exposes `fetchLatencySummary()` if you want a quick local-vs-server check. Do not assume the client silently rewrites every timestamp for you.

## Transitioning to Awaitable WebSockets for KuCoin {#transitioning-to-awaitable-websockets-for-kucoin}

Market data is fine as event listeners (`update`, `reconnect`, `reconnected`). Order placement over WebSocket is not. Matching request IDs across the process is busywork.

[kucoin-api](/sdk/kucoin/javascript) exposes two WS API styles:

- `WebsocketClient.sendWSAPIRequest()` - promise-wrapped, still close to the raw command
- `WebsocketAPIClient` - one method per endpoint, REST-like, connection kept alive for you

That is the awaitable pattern. Same linear `await` as REST, without opening a new HTTP session per order.

A persistent socket also matters if you care about operational traceability. Guidance such as the [FinCEN Virtual Currency Guidance](https://www.fincen.gov/resources/statutes-regulations/guidance/application-of-fincens-regulations-persons-administering) is about the businesses around the exchange, not about this npm package, but the engineering point stands: keep connectivity boring and logs complete. Heartbeats and reconnect are in the client. Rate limits are still yours.

### Awaitable Order Placement via WebSocket {#awaitable-order-placement-via-websocket}

`WebsocketAPIClient` is the straightforward path. This matches the SDK example in `examples/WebSockets/WS-API/ws-api-client.ts`:

```js title="Imported example"
const { WebsocketAPIClient } = require("kucoin-api");

const wsClient = new WebsocketAPIClient({
  apiKey: process.env.KUCOIN_API_KEY,
  apiSecret: process.env.KUCOIN_API_SECRET,
  apiPassphrase: process.env.KUCOIN_API_PASSPHRASE,
});

async function placeSpotLimit() {
  const response = await wsClient.submitNewSpotOrder({
side: "buy",
symbol: "BTC-USDT",
type: "limit",
price: "20000",
size: "0.0001",
  });
  console.log(response);
}

async function placeFuturesLimit() {
  const response = await wsClient.submitFuturesOrder({
clientOid: "futures-test-" + Date.now(),
side: "buy",
symbol: "XBTUSDTM",
marginMode: "CROSS",
type: "limit",
price: "1000",
qty: "0.01",
leverage: 10,
positionSide: "LONG",
  });
  console.log(response);
}
```

Use prices and sizes that cannot fill if you are only testing the round trip. `submitSyncSpotOrder` waits for the matching-engine ack. Futures batch helpers exist too (`submitMultipleFuturesOrders`, `cancelMultipleFuturesOrders`).

### Managing WebSocket Subscriptions {#managing-websocket-subscriptions}

Public streams do not need keys. Private account streams do. The client authenticates when you pass credentials.

V1 topics still work (`spotPublicV1`, `futuresPublicV1`, `spotPrivateV1`). V2 / Pro / UTA topics use keys such as `spotPublicProV2`, `futuresPublicProV2`, and `privateProV2`. Private V2 topics share one connection.

Public ticker example from `examples/WebSockets/ws-public-spot-v1.ts`:

```js title="Imported example"
const { WebsocketClient } = require("kucoin-api");

const ws = new WebsocketClient();

ws.on("update", (data) => {
  console.log("data received:", JSON.stringify(data));
});

ws.on("reconnect", (data) => {
  console.log("reconnect:", data);
});

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

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

ws.subscribe("/market/ticker:BTC-USDT,ETH-USDT", "spotPublicV1");
```

Private UTA / Pro orders, from `examples/WebSockets/ws-private-pro-v2.ts`:

```js title="Imported example"
const { WebsocketClient, WS_KEY_MAP } = require("kucoin-api");

const ws = new WebsocketClient({
  apiKey: process.env.KUCOIN_API_KEY,
  apiSecret: process.env.KUCOIN_API_SECRET,
  apiPassphrase: process.env.KUCOIN_API_PASSPHRASE,
});

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

ws.subscribe(
  {
topic: "orderAll",
payload: { tradeType: "UNIFIED" },
  },
  WS_KEY_MAP.privateProV2,
);

ws.subscribe(
  {
topic: "positionAll",
payload: { tradeType: "FUTURES" },
  },
  WS_KEY_MAP.privateProV2,
);
```

Reconnect resubscribes stored topics automatically. After `reconnected`, refresh orders and balances with REST so your cache is not stale. More stream detail is in the [KuCoin JavaScript SDK tutorial](/sdk/kucoin/javascript/tutorial).



## Engineering Reliable Market Data Pipelines {#engineering-reliable-market-data-pipelines}

Keep ingestion off the hot path of your strategy code. Typed responses help, especially on order book deltas. The SDK types most payloads. It does not magically protect you from KuCoin changing a field.

Respect rate limits in your process. [kucoin-api](/sdk/kucoin/javascript) will not queue or back off for you. UTA limits are per second and scale with VIP. Classic spot, futures, and public pools use a 30-second window. 429s and IP bans are on you if you ignore that.

### Building a Data Collector in Node.js {#building-a-data-collector-in-node-js}

Separate the socket reader from analysis. Use REST for snapshots and history, WebSockets for the live tape.

Spot public REST, from `examples/Rest/rest-spot-public.ts`:

```js title="Imported example"
const { SpotClient } = require("kucoin-api");

const client = new SpotClient();

async function collectSpot() {
  const symbols = await client.getSymbols();
  const ticker = await client.getTicker({ symbol: "BTC-USDT" });
  const klines = await client.getKlines({
symbol: "BTC-USDT",
type: "1day",
  });
  console.log({ symbols, ticker, klines });
}

collectSpot().catch(console.error);
```

UTA market data, from `examples/kucoin-UNIFIED-examples-nodejs.md`:

```js title="Imported example"
const { UnifiedAPIClient } = require("kucoin-api");

const unifiedClient = new UnifiedAPIClient();

async function collectUnified() {
  const spotTickers = await unifiedClient.getTickers({ tradeType: "SPOT" });
  const futuresTicker = await unifiedClient.getTickers({
tradeType: "FUTURES",
symbol: "XBTUSDTM",
  });
  const klines = await unifiedClient.getKlines({
tradeType: "SPOT",
symbol: "BTC-USDT",
interval: "1hour",
startAt: Date.now() - 24 * 60 * 60 * 1000,
endAt: Date.now(),
  });
  console.log({ spotTickers, futuresTicker, klines });
}

collectUnified().catch(console.error);
```

On 429, back off. A token bucket or a small queue across workers is enough. [Install kucoin-api](/sdk/kucoin/javascript) and point your collector at the public methods first.

### Managing Order and Account State {#managing-order-and-account-state}

Do not poll REST for every fill. Snapshot with REST, then apply private WS updates.

```js title="Imported example"
const { UnifiedAPIClient } = require("kucoin-api");

const unifiedClient = new UnifiedAPIClient({
  apiKey: process.env.KUCOIN_API_KEY,
  apiSecret: process.env.KUCOIN_API_SECRET,
  apiPassphrase: process.env.KUCOIN_API_PASSPHRASE,
});

async function snapshot() {
  const account = await unifiedClient.getAccount();
  const open = await unifiedClient.getOpenOrderList(
{ tradeType: "SPOT", symbol: "BTC-USDT", pageSize: 50 },
"unified",
  );
  return { account, open };
}
```

Patterns for that hybrid cache are in [Siebly research on order flow](/research/crypto-order-flow-trading-system). Pair them with the [KuCoin JavaScript SDK](/sdk/kucoin/javascript/tutorial).

## Implementing KuCoin Integrations with Siebly kucoin-api {#implementing-kucoin-integrations-with-siebly-kucoin-api}

Install the package:

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

Yarn is `yarn add kucoin-api`. The library targets Node.js and TypeScript. ESM and CommonJS both work.

Pick the client that matches the API family you actually call. Classic spot orders go through `SpotClient` (HF helpers such as `submitHFOrder`). Futures go through `FuturesClient`. UTA / Pro trading goes through `UnifiedAPIClient`, with `accountMode` `'unified'` or `'classic'`. Do not assume one constructor covers every KuCoin URL.

### Quickstart with Siebly kucoin-api {#quickstart-with-siebly-kucoin-api}

Public ticker plus a UTA limit order (from the unified examples). The second argument to `placeOrder` is the account mode. Default is `'unified'`.

```js title="Imported example"
const { UnifiedAPIClient } = require("kucoin-api");

const unifiedClient = new UnifiedAPIClient({
  apiKey: process.env.KUCOIN_API_KEY,
  apiSecret: process.env.KUCOIN_API_SECRET,
  apiPassphrase: process.env.KUCOIN_API_PASSPHRASE,
});

async function main() {
  const ticker = await unifiedClient.getTickers({
tradeType: "SPOT",
symbol: "BTC-USDT",
  });
  console.log(ticker);

  const order = await unifiedClient.placeOrder(
{
tradeType: "SPOT",
clientOid: "my-client-oid-" + Date.now(),
symbol: "BTC-USDT",
side: "BUY",
orderType: "LIMIT",
size: "0.001",
sizeUnit: "BASECCY",
price: "40000",
timeInForce: "GTC",
},
"unified",
  );
  console.log(order);
}

main().catch(console.error);
```

Classic spot HF order, from `examples/Rest/rest-spot-private-trade.ts`:

```js title="Imported example"
const { SpotClient } = require("kucoin-api");

const client = new SpotClient({
  apiKey: process.env.KUCOIN_API_KEY,
  apiSecret: process.env.KUCOIN_API_SECRET,
  apiPassphrase: process.env.KUCOIN_API_PASSPHRASE,
});

async function placeHfMarket() {
  const result = await client.submitHFOrder({
clientOid: client.generateNewOrderID(),
side: "buy",
type: "market",
symbol: "BTC-USDT",
size: "0.00001",
  });
  console.log(result);
}

placeHfMarket().catch(console.error);
```

`generateNewOrderID()` returns a nanoid. Use it for `clientOid` instead of rolling your own uniqueness. Method lists live in the [Siebly KuCoin SDK guide](/sdk/kucoin/javascript).

### Testing and Safety Boundaries {#testing-and-safety-boundaries}

KuCoin's old sandbox (`openapi-sandbox.kucoin.com`) is offline. Official docs say the independent sandbox stopped maintenance. `kucoin-api` has no working testnet base URL, so do not look for a `testnet: true` switch that points at a real KuCoin sandbox.

What you can do:

- Spot HF mock: `submitHFOrderTest` (`POST /api/v1/hf/orders/test`)
- Older mock: `submitOrderTest` (deprecated; prefer the HF test method)
- Trade tiny size on live
- Use [paper trading workflows](/blog) for architecture checks

Cap order size in your own code. Disable withdrawals on bot keys. Validate signing and WS subscribe on public data before you send a live order.

## Advancing Your KuCoin Integration Architecture {#advancing-your-kucoin-integration-architecture}

Archived official wrappers and homemade signing are the two usual failure modes. A maintained Kucoin node sdk gets you typed REST clients, a unified WebSocket consumer, and awaitable WS API calls.

[kucoin-api](/sdk/kucoin/javascript) is TypeScript-first and ships ESM plus CommonJS. Signing and socket frame handling are in the library. Rate limits, order-size caps, and state reconciliation after reconnect stay in your process.

Ready to wire it up? [Explore the Siebly KuCoin JavaScript SDK](/sdk/kucoin/javascript). Start with public REST, then private WS, then one guarded order call.

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

### Is the official KuCoin Node.js SDK still supported? {#is-the-official-kucoin-node-js-sdk-still-supported}

No. `kucoin-node-sdk` and `kucoin-futures-node-sdk` were archived on March 4, 2025. The repos are read-only. KuCoin recommends their Universal SDK. If you want a maintained TypeScript Node client with dedicated spot, futures, broker, UTA, and WebSocket classes, use kucoin-api from Siebly.io.

### How do I handle KuCoin API rate limits in Node.js? {#how-do-i-handle-kucoin-api-rate-limits-in-node-js}

Limits depend on product and VIP level. On the Unified Account pool, VIP0 is 300 requests per second. Classic spot (including margin) for VIP0 is 4000 per 30 seconds. Futures, public, and other Classic pools have their own 30-second quotas. UTA quota can be split across master and sub-accounts. [kucoin-api](/sdk/kucoin/javascript) does not throttle. Put a token bucket or a queue in front of the client and back off on 429.

### Can I use the Siebly KuCoin SDK with TypeScript? {#can-i-use-the-siebly-kucoin-sdk-with-typescript}

Yes. The package is written in TypeScript. Request objects and most responses have declarations, so the editor can complete method names and flag bad params before runtime.

### Does the KuCoin API require a passphrase for authentication? {#does-the-kucoin-api-require-a-passphrase-for-authentication}

Yes. Key, secret, and passphrase are all required for private calls. The passphrase is signed and sent as `KC-API-PASSPHRASE`. It is not concatenated into the request pre-hash. The pre-hash is timestamp, method, path, and body. Pass all three constructor fields: `apiKey`, `apiSecret`, `apiPassphrase`.

### What is the difference between KuCoin Spot and Futures APIs? {#what-is-the-difference-between-kucoin-spot-and-futures-apis}

Auth is the same three credentials. In this SDK, use `SpotClient` and `FuturesClient` for those Classic APIs. `UnifiedAPIClient` talks to `/api/ua/v1` and selects the market with `tradeType: 'SPOT' | 'FUTURES'`. `WebsocketClient` covers both markets; you pass a `wsKey` so the right socket is used.

### How do I manage WebSocket reconnections for KuCoin? {#how-do-i-manage-websocket-reconnections-for-kucoin}

The client heartbeats, reconnects, re-auths private sockets, and resubscribes topics it already stored. Listen for `reconnect` and `reconnected`. After `reconnected`, do a REST snapshot of orders and balances. You do not need to call `subscribe` again for topics that were still in the store. Call `unsubscribe` if you want a topic gone after the next drop.

### Is there a testnet or sandbox for KuCoin API development? {#is-there-a-testnet-or-sandbox-for-kucoin-api-development}

Not a live one you should rely on. KuCoin took the independent sandbox offline. This SDK does not point at a working testnet URL. Use `submitHFOrderTest` for spot HF dry-runs, tiny live orders, or paper-trading flows. Never assume a sandbox flag will save you from hitting production.

### How do I sign KuCoin API requests correctly? {#how-do-i-sign-kucoin-api-requests-correctly}

Build `timestamp + method + /endpoint + body` (query string with `?` for GET/DELETE). HMAC-SHA256 with the secret, Base64-encode, send as `KC-API-SIGN`. Send the key, version, timestamp, and signed passphrase in the other `KC-API-*` headers. `kucoin-api` does this on every private REST call. You should not reimplement it unless you are debugging a signature mismatch.

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

- [KuCoin Node.js SDK: Building Reliable Exchange Integrations in 2026](/blog/kucoin-nodejs-sdk-building-reliable-exchange-integrations-in-2026)
- [Crypto Exchange Integration Patterns: Architecting Reliable Node.js Systems in 2026](/blog/crypto-exchange-integration-patterns-architecting-reliable-nodejs-systems-in-2026)
- [Algorithmic Trading Architecture: Node.js Production Guide](/blog/algorithmic-trading-architecture-nodejs-production-guide)


## Related Siebly Resources

- [KuCoin JavaScript SDK](/sdk/kucoin/javascript)
- [Siebly SDK directory](/sdk)
- [Exchange State Management](/ai/exchange-state)
- [Runnable exchange API examples](/examples)
- [SDK security and release integrity](/security)
