
Security News
OpenClaw Skill Marketplace Emerges as Active Malware Vector
Security researchers report widespread abuse of OpenClaw skills to deliver info-stealing malware, exposing a new supply chain risk as agent ecosystems scale.
Complete Node.js SDK for OKX's REST APIs and WebSockets, with TypeScript & end-to-end tests
Complete, updated & performant Node.js SDK for the OKX(OKEX) APIs and WebSockets:
market: 'EEA'.market: 'US'.sendWSAPIRequest() method, or;npm install okx-api
Check out my related JavaScript/TypeScript/Node.js projects:
Most methods accept JS objects. These can be populated using parameters specified by okx's API documentation, or check the type definition in the rest-client class methods.
Support my efforts to make algo trading accessible to all - register with my referral links:
For more ways to give thanks & support my efforts, visit Contributions & Thanks!
This project uses typescript. Resources are stored in 3 key structures:
Create API credentials at okx
data property is directly (without the code, data & msg properties).code and msg properties). See the interface for APIResponse.import { RestClient } from 'okx-api';
const client = new RestClient({
apiKey: 'apiKeyHere',
apiSecret: 'apiSecretHere',
apiPass: 'apiPassHere',
// For Global users (www.okx.com), you don't need to set the market.
// It will use global by default.
// Not needed: market: 'GLOBAL',
// For EEA users (my.okx.com), set market to "EEA":
// market: 'EEA',
// For US users (app.okx.com), set market to "US":
// market: 'US',
});
// Submit a buy and sell market order
(async () => {
try {
const allBalances = await client.getBalance();
console.log('All balances: ', allBalances);
const buyResult = await client.submitOrder({
instId: 'BTC-USDT',
ordType: 'market',
side: 'buy',
sz: '0.1',
tdMode: 'cash',
tgtCcy: 'base_ccy',
});
console.log('buy order result: ', buyResult);
const sellResult = await client.submitOrder({
instId: 'BTC-USDT',
ordType: 'market',
side: 'sell',
sz: '0.1',
tdMode: 'cash',
tgtCcy: 'base_ccy',
});
console.log('Sell order result: ', sellResult);
} catch (e) {
console.error('request failed: ', e);
}
})();
This connector includes a high-performance Node.js, TypeScript & JavaScript WebSocket client for the OKX public & private WebSocket, including the OKX WebSocket API for order placement. API credentials are optional unless private streams will be used (such as account order updates).

ts-node examples/ws-private.tsimport { ... } from 'okx-api' to const { ... } = require('okx-api');ws-private.jsnode examples/ws-private.jsOKX supports some order management capabilities via a persisted WebSocket connection. This SDK supports this with two convenient approaches.
The recommended route is to use the dedicated WebsocketAPIClient class, included with this SDK:
It looks & feels like a REST API client, but uses WebSockets, via the WebsocketClient's sendWSAPIRequest method (which you can use directly if you prefer).
A simple example is below but for a more thorough example, check the example here: ./examples/ws-api-client.ts.
import { WebsocketAPIClient } from 'okx-api';
// or if you prefer require:
// const { WebsocketAPIClient } = require("okx-api");
// For private events, all 3 of the following are required (per account):
const API_KEY = process.env.API_KEY_COM;
const API_SECRET = process.env.API_SECRET_COM;
const API_PASSPHRASE = process.env.API_PASSPHRASE_COM;
// If running from CLI in unix, you can pass env vars as such:
// API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/ws-private.ts
const wsClient = new WebsocketAPIClient({
// For Global users (www.okx.com), you don't need to set the market.
// It will use global by default.
// Not needed: market: 'GLOBAL',
// For EEA users (my.okx.com), set market to "EEA":
// market: 'EEA',
// For US users (app.okx.com), set market to "US":
// market: 'US',
accounts: [
{
apiKey: API_KEY,
apiSecret: API_SECRET,
apiPass: API_PASSPHRASE,
},
],
});
async function start() {
// Optional: prepare the WebSocket API connection in advance.
// This happens automatically but you can do this early before making any API calls, to prevent delays from a cold start.
// await wsClient.connectWSAPI();
/**
* OKX's WebSocket API be used like a REST API, through this SDK's WebsocketAPIClient. The WebsocketAPIClient is a utility class wrapped around WebsocketClient's sendWSAPIRequest() capabilities.
*
* Each request sent via the WebsocketAPIClient will automatically:
* - route via the active WS API connection
* - return a Promise, which automatically resolves/rejects when a matching response is received
*/
/**
* Place Order
* https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-order
*/
try {
const res = await wsClient.submitNewOrder({
instId: 'BTC-USDT',
tdMode: 'cash',
side: 'buy',
ordType: 'market',
sz: '100',
});
/**
const res = {
id: '2',
op: 'order',
code: '1',
msg: '',
data: [
{
tag: '159881cb7207BCDE',
ts: '1753714603721',
ordId: '',
clOrdId: '',
sCode: '51008',
sMsg: 'Order failed. Insufficient USDT balance in account.'
}
],
inTime: '1753714603720755',
outTime: '1753714603721942',
wsKey: 'prodPrivate',
isWSAPIResponse: false
}
const res = {
id: '2',
op: 'order',
code: '1',
msg: '',
data: [
{
tag: '159881cb7207BCDE',
ts: '1753714567149',
ordId: '',
clOrdId: '',
sCode: '51010',
sMsg: "You can't complete this request under your current account mode."
}
],
inTime: '1753714567149196',
outTime: '1753714567149913',
wsKey: 'prodPrivate',
isWSAPIResponse: false
}
*/
console.log(new Date(), 'WS API "submitNewOrder()" result: ', res);
} catch (e) {
console.error(new Date(), 'Exception with WS API "submitNewOrder()": ', e);
}
/**
* Submit multiple orders in a batch
* https://www.okx.com/docs-v5/en/#order-book-trading-trade-ws-place-multiple-orders
*/
try {
const res = await wsClient.submitMultipleOrders([
{
instId: 'BTC-USDT',
tdMode: 'cash',
side: 'buy',
ordType: 'market',
sz: '100',
},
{
instId: 'BTC-USDT',
tdMode: 'cash',
side: 'buy',
ordType: 'market',
sz: '50',
},
]);
console.log(new Date(), 'WS API "submitMultipleOrders()" result: ', res);
} catch (e) {
console.error(
new Date(),
'Exception with WS API "submitMultipleOrders()": ',
e,
);
}
}
start();
The below example demonstrates connecting as a consumer, to receive WebSocket events from OKX, using the included WebsocketClient:
import { WebsocketClient } from 'okx-api';
// or if you prefer require:
// const { WebsocketClient } = require("okx-api");
// For private events, all 3 of the following are required (per account):
const API_KEY = process.env.API_KEY_COM;
const API_SECRET = process.env.API_SECRET_COM;
const API_PASSPHRASE = process.env.API_PASSPHRASE_COM;
// If running from CLI in unix, you can pass env vars as such:
// API_KEY_COM='lkm12n3-2ba3-1mxf-fn13-lkm12n3a' API_SECRET_COM='035B2B9637E1BDFFEE2646BFBDDB8CE4' API_PASSPHRASE_COM='ComplexPa$$!23$5^' ts-node examples/ws-private.ts
// Note the single quotes, preventing special characters such as $ from being incorrectly passed
const wsClient = new WebsocketClient({
// For Global users (www.okx.com), you don't need to set the market.
// It will use global by default.
// Not needed: market: 'GLOBAL',
// For EEA users (my.okx.com), set market to "EEA":
// market: 'EEA',
// For US users (app.okx.com), set market to "US":
// market: 'US',
accounts: [
// For private topics, include one or more accounts in an array. Otherwise only public topics will work
{
apiKey: API_KEY,
apiSecret: API_SECRET,
apiPass: API_PASSPHRASE,
},
// {
// apiKey: 'yourApiKeyHere',
// apiSecret: 'yourApiSecretHere',
// apiPass: 'yourApiPassHere',
// },
// {
// apiKey: 'anotherAccountKey',
// apiSecret: 'anotherAccountSecret',
// apiPass: 'anotherAccountPass',
// },
],
});
// Raw data will arrive on the 'update' event
wsClient.on('update', (data) => {
console.log('ws update (raw data received)', JSON.stringify(data));
});
wsClient.on('open', (data) => {
console.log('connection opened open:', data.wsKey);
});
// Replies (e.g. authenticating or subscribing to channels) will arrive on the 'response' event
wsClient.on('response', (data) => {
// console.log('ws response: ', JSON.stringify(data, null, 2));
console.log('ws response: ', JSON.stringify(data));
});
wsClient.on('reconnect', ({ wsKey }) => {
console.log('ws automatically reconnecting.... ', wsKey);
});
wsClient.on('reconnected', (data) => {
console.log('ws has reconnected ', data?.wsKey);
});
wsClient.on('exception', (data) => {
console.error('ws exception: ', data);
});
/**
* Simply call subscribe to request the channels that you're interested in.
*
* If authentication is required, the WSClient will automatically authenticate with the available credentials.
*/
// Subscribe one event at a time:
wsClient.subscribe({
channel: 'account',
});
// OR, combine multiple subscription events into one request using an array instead of an object:
wsClient.subscribe([
{
channel: 'account',
},
{
channel: 'positions',
instType: 'ANY',
},
]);
// Public topics, for comparison. These do not require authentication / api keys:
wsClient.subscribe([
{
channel: 'instruments',
instType: 'SPOT',
},
{
channel: 'instruments',
instType: 'FUTURES',
},
{
channel: 'tickers',
instId: 'LTC-BTC',
},
]);
See examples/ws-public.ts for a full example:

See examples/ws-private.ts for a full example:

This is the "modern" way, allowing the package to be directly imported into frontend projects with full typescript support.
npm install crypto-browserify stream-browserify
tsconfig.json
{
"compilerOptions": {
"paths": {
"crypto": [
"./node_modules/crypto-browserify"
],
"stream": [
"./node_modules/stream-browserify"
]
}
(window as any).global = window;
This is the "old" way of using this package on webpages. This will build a minified js bundle that can be pulled in using a script tag on a website.
Build a bundle using webpack:
npm installnpm buildnpm packThe bundle can be found in dist/. Altough usage should be largely consistent, smaller differences will exist. Documentation is still TODO.
This SDK includes a bundled llms.txt file in the root of the repository. If you're developing with LLMs, use the included llms.txt with your LLM - it will significantly improve the LLMs understanding of how to correctly use this SDK.
This file contains AI optimised structure of all the functions in this package, and their parameters for easier use with any learning models or artificial intelligence.
Have my projects helped you? Share the love, there are many ways you can show your thanks:
0xA3Bda8BecaB4DCdA539Dc16F9C54a592553Be06C Contributions are encouraged, I will review any incoming pull requests. See the issues tab for todo items.
The following represents some of the known public projects that use this SDK on GitHub:
FAQs
Complete Node.js SDK for OKX's REST APIs and WebSockets, with TypeScript & end-to-end tests
The npm package okx-api receives a total of 1,584 weekly downloads. As such, okx-api popularity was classified as popular.
We found that okx-api demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Security researchers report widespread abuse of OpenClaw skills to deliver info-stealing malware, exposing a new supply chain risk as agent ecosystems scale.

Security News
Claude Opus 4.6 has uncovered more than 500 open source vulnerabilities, raising new considerations for disclosure, triage, and patching at scale.

Research
/Security News
Malicious dYdX client packages were published to npm and PyPI after a maintainer compromise, enabling wallet credential theft and remote code execution.