Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tiagosiebler/kucoin-api/llms.txt

Use this file to discover all available pages before exploring further.

Private WebSocket streams deliver account-specific events such as order state changes, balance updates, and position changes. Unlike public streams, private connections require your API key, secret, and passphrase. The SDK handles authentication automatically when you subscribe to a private WsKey — no extra steps are needed beyond providing credentials in the constructor.

Authentication Flow

When you call subscribe() with a private WsKey (spotPrivateV1, futuresPrivateV1, or privateProV2), the SDK:
  1. Fetches a signed connection token from the KuCoin REST API using your credentials.
  2. Opens a WebSocket connection using that token in the URL (V1) or as a query parameter (V2).
  3. Completes any exchange-level authentication handshake automatically.
  4. Sends your subscription requests once the connection is ready.
The apiPassphrase is not your KuCoin account login password. It is the custom passphrase you set when creating the API key in the KuCoin dashboard.

Spot Private V1 Streams

Use the spotPrivateV1 WsKey for all private spot and margin topics.
1

Create the client with credentials

import { WebsocketClient } from 'kucoin-api';

const client = new WebsocketClient({
  apiKey: process.env.API_KEY || 'keyHere',
  apiSecret: process.env.API_SECRET || 'secretHere',
  apiPassphrase: process.env.API_PASSPHRASE || 'apiPassPhraseHere',
});
2

Register event handlers

client.on('open', (data) => {
  console.log('open: ', data?.wsKey);
});

client.on('update', (data) => {
  console.info('data received: ', JSON.stringify(data));
});

client.on('reconnect', (data) => {
  console.log('reconnect: ', data);
});

client.on('reconnected', (data) => {
  console.log('reconnected: ', data);
});

client.on('close', (data) => {
  console.error('close: ', data);
});

client.on('response', (data) => {
  console.info('response: ', data);
});

client.on('exception', (data) => {
  console.error('exception: ', {
    msg: data.msg,
    errno: data.errno,
    code: data.code,
    syscall: data.syscall,
    hostname: data.hostname,
  });
});
3

Subscribe to private spot topics

client.subscribe(
  [
    '/market/match:BTC-USDT',            // Private trade match (your fills)
    '/spotMarket/tradeOrders',            // Spot order lifecycle updates (V1)
    '/spotMarket/tradeOrdersV2',          // Spot order lifecycle updates (V2)
    '/account/balance',                   // Account balance changes
    '/spotMarket/advancedOrders',         // Stop orders triggered/cancelled
  ],
  'spotPrivateV1',
);

Margin Private Topics

Margin topics also use the spotPrivateV1 WsKey:
client.subscribe(
  [
    '/margin/position',                        // Cross margin position changes
    '/margin/isolatedPosition:BTC-USDT',       // Isolated margin position changes
    '/spotMarket/advancedOrders',              // Advanced stop orders
  ],
  'spotPrivateV1',
);

Futures Private V1 Streams

Use the futuresPrivateV1 WsKey for futures-specific private events.
import { WebsocketClient } from 'kucoin-api';

const client = new WebsocketClient({
  apiKey: process.env.API_KEY || 'keyHere',
  apiSecret: process.env.API_SECRET || 'secretHere',
  apiPassphrase: process.env.API_PASSPHRASE || 'apiPassPhraseHere',
});

client.on('open', (data) => console.log('open: ', data?.wsKey));
client.on('update', (data) => console.info('data received: ', JSON.stringify(data)));
client.on('reconnect', (data) => console.log('reconnect: ', data));
client.on('reconnected', (data) => console.log('reconnected: ', data));
client.on('close', (data) => console.error('close: ', data));
client.on('response', (data) => console.info('response: ', data));
client.on('exception', (data) => {
  console.error('exception: ', {
    msg: data.msg,
    errno: data.errno,
    code: data.code,
    syscall: data.syscall,
    hostname: data.hostname,
  });
});

client.subscribe(
  [
    '/contractMarket/tradeOrders:XBTUSDM', // Order updates for a specific contract
    '/contractMarket/tradeOrders',          // Order updates for all contracts
    '/contractMarket/advancedOrders',       // Advanced stop orders
    '/contractAccount/wallet',              // Futures wallet balance changes
    '/contract/position:XBTUSDM',          // Position changes for a specific contract
    '/contract/positionAll',               // Position changes for all contracts
  ],
  'futuresPrivateV1',
);
TopicWsKeyDescription
/spotMarket/tradeOrdersspotPrivateV1Spot HF order updates
/spotMarket/tradeOrdersV2spotPrivateV1Spot order updates (V2 format)
/account/balancespotPrivateV1Account balance changes
/spotMarket/advancedOrdersspotPrivateV1Stop order triggers
/market/match:SYMBOLspotPrivateV1Your private trade fills
/margin/positionspotPrivateV1Cross margin position changes
/margin/isolatedPosition:SYMBOLspotPrivateV1Isolated margin changes
/contractMarket/tradeOrdersfuturesPrivateV1Futures order updates (all)
/contractMarket/tradeOrders:SYMBOLfuturesPrivateV1Futures order updates (single)
/contractMarket/advancedOrdersfuturesPrivateV1Futures stop orders
/contractAccount/walletfuturesPrivateV1Futures wallet balance
/contract/position:SYMBOLfuturesPrivateV1Futures position (single)
/contract/positionAllfuturesPrivateV1Futures positions (all)

Unified Private Pro V2 Streams

The privateProV2 WsKey provides a single connection covering both spot and futures private events. Use structured WsTopicRequest objects and set the appropriate tradeType in the payload.
import { WebsocketClient, WS_KEY_MAP, WsTopicRequest } from 'kucoin-api';

const client = new WebsocketClient({
  apiKey: process.env.API_KEY || 'keyHere',
  apiSecret: process.env.API_SECRET || 'secretHere',
  apiPassphrase: process.env.API_PASSPHRASE || 'apiPassPhraseHere',
});

client.on('open', (data) => console.log('open: ', data?.wsKey));
client.on('update', (data) => console.info('data received: ', JSON.stringify(data)));
client.on('reconnect', (data) => console.log('reconnect: ', data));
client.on('reconnected', (data) => console.log('reconnected: ', data));
client.on('close', (data) => console.error('close: ', data));
client.on('response', (data) => console.info('response: ', data));
client.on('exception', (data) => {
  console.error('exception: ', {
    msg: data.msg,
    errno: data.errno,
    code: data.code,
    syscall: data.syscall,
    hostname: data.hostname,
  });
});

// Subscribe to a single topic
const orderAllSpotRequest: WsTopicRequest = {
  topic: 'orderAll',
  payload: {
    tradeType: 'SPOT', // SPOT / FUTURES / ISOLATED / CROSS / UNIFIED
  },
};
client.subscribe(orderAllSpotRequest, WS_KEY_MAP.privateProV2);

// Subscribe to multiple topics in one call
client.subscribe(
  [
    // All orders across trade types
    {
      topic: 'orderAll',
      payload: { tradeType: 'UNIFIED' },
    },
    // Orders for a specific symbol
    {
      topic: 'order',
      payload: {
        tradeType: 'SPOT',
        symbol: 'BTC-USDT',
      },
    },
    // All futures positions
    {
      topic: 'positionAll',
      payload: { tradeType: 'FUTURES' },
    },
    // Position for a specific futures contract
    {
      topic: 'position',
      payload: {
        tradeType: 'FUTURES',
        symbol: 'XBTUSDTM',
      },
    },
    // Account balance updates
    {
      topic: 'balance',
      payload: { accountType: 'SPOT' }, // SPOT / ISOLATED / CROSS / FUTURES / UNIFIED
    },
    // Trade/execution updates
    {
      topic: 'execution',
      payload: { tradeType: 'SPOT' },
    },
    // Liquidation warnings (Unified only)
    {
      topic: 'lw',
      payload: { tradeType: 'UNIFIED' },
    },
    // Leverage updates (Unified only)
    {
      topic: 'leverage',
      payload: { tradeType: 'UNIFIED' },
    },
  ],
  WS_KEY_MAP.privateProV2,
);
With privateProV2, a single authenticated WebSocket connection replaces the two separate V1 private connections (spotPrivateV1 and futuresPrivateV1). This reduces overhead and simplifies connection management.

Reconnection and Re-authentication

Private connections reconnect with the same automatic behaviour as public ones, with one addition: authentication is re-executed automatically after reconnect because a fresh token is fetched via the REST API. Your subscriptions are cached internally and replayed in full after every successful reconnection. The reconnected event fires once the connection is live and topics are active again. No manual intervention is needed.
To be notified when the private connection is authenticated (useful for debugging), listen to the authenticated event emitted by the internal WebsocketClient:
client.on('authenticated', (data) => {
  console.info('ws has authenticated', data?.wsKey);
});

Build docs developers (and LLMs) love