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.
The kucoin-api SDK ships with a DefaultLogger that writes info and error messages to the console while silencing trace-level output. For production systems — where you want structured logs, filtered noise, or integration with an existing logging framework — you can inject your own logger object into any WebsocketClient or WebsocketAPIClient constructor. The logger interface is intentionally minimal: any object that exposes trace, info, and error methods is accepted.
The DefaultLogger
The DefaultLogger is exported directly from the SDK. Its implementation is straightforward:
// src/lib/websocket/logger.ts
export type LogParams = null | any;
export const DefaultLogger = {
trace: (..._params: LogParams): void => {
// console.log(_params);
},
info: (...params: LogParams): void => {
console.info(params);
},
error: (...params: LogParams): void => {
console.error(params);
},
};
trace logging is disabled by default because it emits a very high volume of messages, including every WebSocket ping, pong, and heartbeat. Enable it selectively during debugging.
Log Levels
| Level | Default behaviour | What it covers |
|---|
trace | Silent | WebSocket pings, pongs, reconnection steps, message routing internals |
info | console.info | Connections opened, subscriptions confirmed, reconnection events |
error | console.error | Failed connections, authentication errors, unhandled exceptions |
Passing a Custom Logger
Supply a custom logger as the second argument to WebsocketClient or WebsocketAPIClient. Use the object-spread pattern to inherit the methods you don’t need to change and override only the ones you do:
const { WebsocketClient, DefaultLogger } = require('kucoin-api');
// E.g. customise logging for only the trace level:
const logger = {
// Inherit existing logger methods, using an object spread
...DefaultLogger,
// Define a custom trace function to override only that function
trace: (...params) => {
if (
[
// Selectively prevent some traces from logging
'Sending ping',
'Received pong',
].includes(params[0])
) {
return;
}
console.log('trace', JSON.stringify(params, null, 2));
},
};
const ws = new WebsocketClient(
{
apiKey: 'apiKeyHere',
apiSecret: 'apiSecretHere',
apiPassphrase: 'apiPassPhraseHere',
},
logger,
);
The same pattern applies to WebsocketAPIClient:
import { DefaultLogger, WebsocketAPIClient } from 'kucoin-api';
const customLogger = {
...DefaultLogger,
// Uncomment to enable verbose trace logging:
// trace: (...params) => console.log(new Date(), 'trace', ...params),
};
const wsClient = new WebsocketAPIClient(
{
apiKey: process.env.API_KEY || 'keyHere',
apiSecret: process.env.API_SECRET || 'secretHere',
apiPassphrase: process.env.API_PASSPHRASE || 'apiPassPhraseHere',
},
customLogger,
);
The WS_LOGGER_CATEGORY Constant
All internal log calls from the WebSocket client include a category field via the WS_LOGGER_CATEGORY constant, exported from the SDK:
export const WS_LOGGER_CATEGORY = { category: 'kucoin-ws' };
This constant is spread into every log call alongside the actual message. If you write a logger that accepts structured metadata (such as pino or winston with JSON transport), you can use the category field to filter or route kucoin-api WebSocket logs independently from the rest of your application’s logs.
Practical Patterns
Suppress Ping/Pong Noise
Integrate with winston
Integrate with pino
WebSocket heartbeat messages (Sending ping, Received pong) appear at the trace level and fire every few seconds. This pattern keeps trace logging enabled for meaningful events while dropping the heartbeat noise:import { DefaultLogger, WebsocketClient } from 'kucoin-api';
const SUPPRESS_TRACES = new Set(['Sending ping', 'Received pong']);
const logger = {
...DefaultLogger,
trace: (...params: any[]) => {
if (SUPPRESS_TRACES.has(params[0])) {
return;
}
console.log('trace', JSON.stringify(params, null, 2));
},
};
const client = new WebsocketClient(
{
apiKey: 'apiKeyHere',
apiSecret: 'apiSecretHere',
apiPassphrase: 'apiPassPhraseHere',
},
logger,
);
Map the SDK’s three log levels to a winston logger. Because winston uses different method names (verbose instead of trace), the mapping layer keeps your winston configuration unchanged:import winston from 'winston';
import { WebsocketClient } from 'kucoin-api';
const winstonLogger = winston.createLogger({
level: 'debug',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json(),
),
transports: [new winston.transports.Console()],
});
const sdkLogger = {
trace: (...params: any[]) => winstonLogger.verbose('[kucoin-ws]', { params }),
info: (...params: any[]) => winstonLogger.info('[kucoin-ws]', { params }),
error: (...params: any[]) => winstonLogger.error('[kucoin-ws]', { params }),
};
const client = new WebsocketClient(
{
apiKey: process.env.API_KEY!,
apiSecret: process.env.API_SECRET!,
apiPassphrase: process.env.API_PASSPHRASE!,
},
sdkLogger,
);
Pino’s structured JSON output pairs well with the SDK’s metadata objects. Pass the category through as a child logger to keep logs filterable:import pino from 'pino';
import { WebsocketClient } from 'kucoin-api';
const baseLogger = pino({ level: 'trace' });
const wsLogger = baseLogger.child({ module: 'kucoin-ws' });
const sdkLogger = {
trace: (...params: any[]) => wsLogger.trace({ params }, params[0]),
info: (...params: any[]) => wsLogger.info({ params }, params[0]),
error: (...params: any[]) => wsLogger.error({ params }, params[0]),
};
const client = new WebsocketClient(
{
apiKey: process.env.API_KEY!,
apiSecret: process.env.API_SECRET!,
apiPassphrase: process.env.API_PASSPHRASE!,
},
sdkLogger,
);
Enabling HTTP-level Tracing
For low-level REST debugging, the SDK also supports an environment variable that enables axios request/response interceptors. Set KUCOINTRACE=1 before starting your process to print every outgoing request URL and method along with the full response body:
KUCOINTRACE=1 node your-script.js
HTTP trace mode logs full request payloads and response bodies to stdout. Never enable it in production — it will expose order details and other sensitive trading data in your logs.