Get market data
Start with public Spot REST and public WebSocket streams for ticker, trade, candles, and order book workflows.
Open sectionBuild Kraken integrations without hand-rolling raw HTTP requests, Kraken JWTs/request signing, WebSocket authentication, heartbeats, reconnects, or exchange-specific payload plumbing.
Updated July 15, 2026
import { SpotClient } from '@siebly/kraken-api';
const client = new SpotClient();
async function main() {
const serverTime = await client.getServerTime();
const systemStatus = await client.getSystemStatus();
const ticker = await client.getTicker({ pair: 'XBTUSD' });
const orderBook = await client.getOrderBook({ pair: 'XBTUSD', count: 10 });
console.log({
serverTime,
systemStatus,
ticker,
orderBook,
});
}
// Since each of the above API calls is wrapped in an awaited promise, a high level catch will detect any exceptions:
main().catch(console.error);API surface map
The SDK keeps Kraken product boundaries explicit while giving JavaScript and TypeScript projects a single install, shared authentication patterns, and consistent async behavior.
Your app
Dashboard, worker, bot, tool
Any JavaScript-compatible runtime that needs Kraken data, orders, or account state.
npm package
npm install @siebly/kraken-apiSpotClient
Spot REST
DerivativesClient
Futures REST
WebsocketClient
Public and private streams
WebsocketAPIClient
Spot API commands
Kraken APIs
Spot REST and WebSockets
Futures REST and WebSockets
Spot WebSocket API commands
Public and private account flows
What this tutorial covers
The guide will introduce you to the key pieces of Kraken's API functionality, but presents the tutorial in surfaces you can explore one section at a time.
Understand what Kraken authenticated APIs expect while letting the SDK handle JWTs and authentication workflows for you.
Use typed clients for market data, account state, order entry, and product-specific request shapes.
Stream market data and account events with heartbeat, reconnect, and resubscribe handling.
Send Spot commands over Kraken's event-driven WebSocket API with awaitable SDK methods.
Start building
For more detail, refer to the full guide below, but if you want to jump straight to code that gets you making requests and receiving data,
import { SpotClient } from '@siebly/kraken-api'; const client = new SpotClient(); async function main() { const serverTime = await client.getServerTime(); const systemStatus = await client.getSystemStatus(); const ticker = await client.getTicker({ pair: 'XBTUSD' }); const orderBook = await client.getOrderBook({ pair: 'XBTUSD', count: 10 }); console.log({ serverTime, systemStatus, ticker, orderBook, });} // Since each of the above API calls is wrapped in an awaited promise, a high level catch will detect any exceptions:main().catch(console.error);import { WebsocketClient, WS_KEY_MAP } from '@siebly/kraken-api'; const ws = new WebsocketClient(); ws.on('open', (data) => console.log('connected', data?.wsKey));ws.on('response', (data) => console.log('response', JSON.stringify(data)));ws.on('message', (data) => console.log('message', JSON.stringify(data)));ws.on('reconnected', (data) => console.log('reconnected', data?.wsKey));ws.on('exception', console.error); ws.subscribe( { topic: 'ticker', payload: { symbol: ['BTC/USD', 'ETH/USD'], }, }, WS_KEY_MAP.spotPublicV2,);import { WebsocketClient, WS_KEY_MAP } from '@siebly/kraken-api'; const ws = new WebsocketClient({ apiKey: process.env.API_SPOT_KEY!, apiSecret: process.env.API_SPOT_SECRET!,}); ws.on('authenticated', (data) => console.log('authenticated', data?.wsKey));ws.on('response', (data) => console.log('response', JSON.stringify(data)));ws.on('message', (data) => console.log('message', JSON.stringify(data)));ws.on('reconnected', (data) => console.log('reconnected', data?.wsKey));ws.on('exception', console.error); ws.subscribe( { topic: 'executions', payload: { snap_trades: true, snap_orders: true, order_status: true, }, }, WS_KEY_MAP.spotPrivateV2,); ws.subscribe( { topic: 'balances', payload: {}, }, WS_KEY_MAP.spotPrivateV2,);import { SpotClient } from '@siebly/kraken-api'; const client = new SpotClient({ apiKey: process.env.API_SPOT_KEY!, apiSecret: process.env.API_SPOT_SECRET!,}); async function placeOrder() { const result = await client.submitOrder({ ordertype: 'limit', type: 'buy', pair: 'XBTUSD', volume: '0.0001', price: '10000', validate: true, cl_ord_id: client.generateNewOrderID(), }); console.log(result);} placeOrder().catch(console.error);import { DerivativesClient } from '@siebly/kraken-api'; const client = new DerivativesClient({ apiKey: process.env.API_FUTURES_KEY!, apiSecret: process.env.API_FUTURES_SECRET!, // testnet: true, // optional: route Derivatives REST calls to Kraken's demo environment}); async function placeFuturesOrder() { const result = await client.submitOrder({ orderType: 'lmt', symbol: 'PF_ETHUSD', side: 'buy', size: 0.01, limitPrice: 1000, cliOrdId: client.generateNewOrderID(), }); console.log(result);} placeFuturesOrder().catch(console.error);Workflow diagrams
Function-style stages keep the implementation order explicit, while the badges show which parts are automatic SDK behavior.
Use this pattern for public market data and private account streams that must survive normal network interruptions.
subscribe(topics)Your codeawait(connect)SDK automaticawait(authenticate)SDK automaticon(authenticated)Eventtrigger(backfill via REST)Your codeon(message)EventWhen a private connection reconnects, pause sensitive commands, backfill with REST, then resume from a known state.
on(reconnecting)Eventpause(private writes)Your codeawait(automatic reconnect)SDK automaticawait(automatic resubscribe)SDK automaticon(reconnected)Eventtrigger(backfill)Your coderesume(private writes)Your codeThe SDK wraps asynchronous WebSocket API commands in promises so private calls can be awaited like REST.
Call & await SDK methodYour codeawait(connect)SDK automaticawait(authenticate)SDK automaticon(authenticated)EventwrapInPromise(request)SDK automaticsend(WSCommand)SDK automaticon(response)Eventresolve(requestPromise)SDK automaticHandle resultYour codeProduction rollout
Explore the recommended patterns for production deployments, including how to handle reconnects, key separation, client-generated IDs, safe validation, logging, and post-reconnect best practices.
Use client-generated order IDs for safer retries and reconciliation.
Treat reconnects as a normal design path, not as an exceptional case.
Start with public data, validate private flows, then test live writes carefully.
Keep Spot & Futures API credentials & REST API clients separate.
Use minimum API key permissions and avoid withdrawal scopes for private API workflows.
Inject your own logger when SDK events need to feed monitoring or alerting.
Choose your path
Start with public Spot REST and public WebSocket streams for ticker, trade, candles, and order book workflows.
Open sectionAuthenticate private streams for balances, orders, executions, account events, and reconnect-aware state handling.
Open sectionUse typed REST clients for Spot and Futures order management, validation, and batch placement.
Open sectionUse promise-wrapped WebSocket API methods when a persistent authenticated command channel is the better fit.
Open sectionThis tutorial covers REST API and WebSocket usage for Spot and Futures, with examples for authentication, reconnects, order management, and rollout checks.
Build Kraken integrations in JavaScript or TypeScript without hand-rolling raw HTTP requests, Kraken JWTs/request signing for authenticated APIs, WebSocket authentication, heartbeats, reconnects, or exchange-specific payload handling.
This Kraken JavaScript tutorial uses @siebly/kraken-api, the Kraken JavaScript SDK by Siebly.io, to walk through the API surfaces most developers need:
Key Links
@siebly/kraken-apisieblyio/kraken-apiTopics covered in this guide
A stable Kraken API integration has to handle separate REST authentication models, private WebSocket authentication, reconnects, and asynchronous command responses.
The @siebly/kraken-api gives you one JavaScript and TypeScript SDK for Kraken API integration in any Node.js or JavaScript-capable environment:
WebsocketClient for public and private streaming across all Kraken products.WebsocketAPIClient for Spot commands over a persistent WebSocket connection, with the convenience of awaitable promise-wrapped WebSocket API requests. Each WebSocket API command can be awaited like a REST API request.The package also includes InstitutionalClient and PartnerClient, but this guide focuses on the flows most developers look for first: Spot, Futures, market data, account data, and order management.
This Kraken JavaScript SDK is relevant for any integration with Kraken's APIs and WebSockets, especially if you are building:
This guide is written for JavaScript developers (& LLMs) who:
Kraken exposes several API surfaces, and most integration mistakes start with choosing the wrong one for the job. Use this map before writing code.
| Developer task | Start with | SDK client or key | Why |
|---|---|---|---|
| Check connectivity or read public market data | Spot REST | SpotClient | Easiest request-response path. No API keys needed for public data. |
| Stream public market data | Spot WebSocket streams | WebsocketClient with WS_KEY_MAP.spotPublicV2 | Better fit when a dashboard, worker, or alerting service needs continuous updates. |
| Read balances, orders, fills, or account state | Private Spot REST plus private Spot WebSockets | SpotClient and WebsocketClient with WS_KEY_MAP.spotPrivateV2 | REST gives snapshots. WebSockets keep long-running processes updated after the initial snapshot. |
| Validate or submit Spot orders | Spot REST first | SpotClient.submitOrder with validate: true while testing | Simple to inspect, log, retry, and validate before live writes. |
| Send low-latency Spot commands over a persistent connection | Spot WebSocket API | WebsocketAPIClient | Useful after the integration already works over REST and a persistent command channel is the better fit. |
| Build against Kraken Futures | Futures REST and Futures WebSockets | DerivativesClient and derivatives WS_KEY_MAP entries | Futures uses separate credentials, symbols, endpoints, and request shapes. |
Rule of thumb: use REST when you need one clear answer to one clear request. Use WebSocket streams when you need live data or account events. Use the WebSocket API when you need a persistent authenticated command channel after the basic REST flow is already understood.
If you don't have Node.js installed yet, refer to the Node.js documentation on getting started with Node.js. The Kraken JavaScript SDK is published to both GitHub and npm.
Install the SDK with npm:
npm install @siebly/kraken-apiOr, if preferred, use your favourite npm-compatible package manager:
# or pnpm:
pnpm install @siebly/kraken-api
# or yarn:
yarn add @siebly/kraken-apiCreate API keys where Kraken documents them:
Use the minimum permissions needed for your scenario. Trading does not require withdrawal permissions. Analytics does not require trading permissions.
Important auth difference:
Typical environment variables:
export API_SPOT_KEY='your-spot-api-key'
export API_SPOT_SECRET='your-spot-api-secret'
export API_FUTURES_KEY='your-futures-api-key'
export API_FUTURES_SECRET='your-futures-api-secret'For local Node.js examples that use a .env file, make .env loading automatic before reading process.env. Prefer Node.js built-in --env-file or --env-file-if-exists in package scripts when supported; otherwise use process.loadEnvFile, dotenv/config, or the repo's existing loader. Real process environment variables should override .env.
If you are only testing public endpoints, you do not need any keys at all.
Use this checklist to avoid the common first-hour problems:
@siebly/kraken-api in the same project that will run the code.getServerTime() or getTicker() before adding credentials.validate: true for Spot order examples until you intentionally want to submit a live order.response, message, reconnecting, reconnected, and exception events before relying on a long-running WebSocket process.If you only want the fastest path to a working integration, this is the section to start from.
import { SpotClient } from '@siebly/kraken-api';
const client = new SpotClient();
async function main() {
const serverTime = await client.getServerTime();
const systemStatus = await client.getSystemStatus();
const ticker = await client.getTicker({ pair: 'XBTUSD' });
const orderBook = await client.getOrderBook({ pair: 'XBTUSD', count: 10 });
console.log({
serverTime,
systemStatus,
ticker,
orderBook,
});
}
// Since each of the above API calls is wrapped in an awaited promise, a high level catch will detect any exceptions:
main().catch(console.error);This is the quickest way to verify that your Kraken API JavaScript integration is wired correctly for public REST API calls.
See also: Kraken JavaScript Example - How to query spot market data
import { WebsocketClient, WS_KEY_MAP } from '@siebly/kraken-api';
const ws = new WebsocketClient();
ws.on('open', (data) => console.log('connected', data?.wsKey));
ws.on('response', (data) => console.log('response', JSON.stringify(data)));
ws.on('message', (data) => console.log('message', JSON.stringify(data)));
ws.on('reconnected', (data) => console.log('reconnected', data?.wsKey));
ws.on('exception', console.error);
ws.subscribe(
{
topic: 'ticker',
payload: {
symbol: ['BTC/USD', 'ETH/USD'],
},
},
WS_KEY_MAP.spotPublicV2,
);This gets a public Kraken Spot WebSocket stream running in JavaScript.
See also: Kraken JavaScript Example - How to subscribe to spot market data WebSocket stream
import { WebsocketClient, WS_KEY_MAP } from '@siebly/kraken-api';
const ws = new WebsocketClient({
apiKey: process.env.API_SPOT_KEY!,
apiSecret: process.env.API_SPOT_SECRET!,
});
ws.on('authenticated', (data) => console.log('authenticated', data?.wsKey));
ws.on('response', (data) => console.log('response', JSON.stringify(data)));
ws.on('message', (data) => console.log('message', JSON.stringify(data)));
ws.on('reconnected', (data) => console.log('reconnected', data?.wsKey));
ws.on('exception', console.error);
ws.subscribe(
{
topic: 'executions',
payload: {
snap_trades: true,
snap_orders: true,
order_status: true,
},
},
WS_KEY_MAP.spotPrivateV2,
);
ws.subscribe(
{
topic: 'balances',
payload: {},
},
WS_KEY_MAP.spotPrivateV2,
);For private Spot v2 topics, the SDK can fetch and refresh the token for you. You do not need to manually fetch a token and inject it into every subscribe payload.
See also: Kraken JavaScript Example - How to subscribe to spot account change WebSocket events
import { SpotClient } from '@siebly/kraken-api';
const client = new SpotClient({
apiKey: process.env.API_SPOT_KEY!,
apiSecret: process.env.API_SPOT_SECRET!,
});
async function placeOrder() {
const result = await client.submitOrder({
ordertype: 'limit',
type: 'buy',
pair: 'XBTUSD',
volume: '0.0001',
price: '10000',
validate: true,
cl_ord_id: client.generateNewOrderID(),
});
console.log(result);
}
placeOrder().catch(console.error);Use validate: true when you want to validate the request shape without sending the live order. Remove validate: true when you are ready to submit.
See also: Kraken JavaScript Example - How to submit spot orders
import { DerivativesClient } from '@siebly/kraken-api';
const client = new DerivativesClient({
apiKey: process.env.API_FUTURES_KEY!,
apiSecret: process.env.API_FUTURES_SECRET!,
// testnet: true, // optional: route Derivatives REST calls to Kraken's demo environment
});
async function placeFuturesOrder() {
const result = await client.submitOrder({
orderType: 'lmt',
symbol: 'PF_ETHUSD',
side: 'buy',
size: 0.01,
limitPrice: 1000,
cliOrdId: client.generateNewOrderID(),
});
console.log(result);
}
placeFuturesOrder().catch(console.error);See also: Kraken JavaScript Example - How to submit futures/derivatives orders
Most integrations start with Spot REST APIs because it is one of the simplest ways to test basic connectivity, such as querying account state and submitting orders.
import { SpotClient } from '@siebly/kraken-api';
const client = new SpotClient();Public calls do not require keys.
If you plan on making private API calls, include API keys when creating an instance of the SpotClient class:
import { SpotClient } from '@siebly/kraken-api';
const client = new SpotClient({
apiKey: process.env.API_SPOT_KEY!,
apiSecret: process.env.API_SPOT_SECRET!,
});const serverTime = await client.getServerTime();
const systemStatus = await client.getSystemStatus();
const assetInfo = await client.getAssetInfo({ asset: 'XBT,ETH' });
const assetPairs = await client.getAssetPairs({ pair: 'XBTUSD,ETHUSD' });
const ticker = await client.getTicker({ pair: 'XBTUSD' });
const orderBook = await client.getOrderBook({ pair: 'XBTUSD', count: 10 });
const candles = await client.getCandles({ pair: 'XBTUSD', interval: 60 });
const recentTrades = await client.getRecentTrades({
pair: 'XBTUSD',
count: 10,
});
const recentSpreads = await client.getRecentSpreads({ pair: 'XBTUSD' });const balance = await client.getAccountBalance();
const tradeBalance = await client.getTradeBalance();
const openOrders = await client.getOpenOrders();
const openOrdersWithTrades = await client.getOpenOrders({ trades: true });
const closedOrders = await client.getClosedOrders({
trades: true,
start: Math.floor(Date.now() / 1000) - 86400 * 7, // last 7 days
});See also:
Market order:
await client.submitOrder({
ordertype: 'market',
type: 'buy',
volume: '0.01',
pair: 'XBTUSD',
});Limit order:
await client.submitOrder({
ordertype: 'limit',
type: 'buy',
volume: '0.0001',
pair: 'XBTUSD',
price: '10000',
});Post-only limit order:
await client.submitOrder({
ordertype: 'limit',
type: 'buy',
volume: '0.001',
pair: 'XBTEUR',
price: '1000.00',
oflags: 'post',
timeinforce: 'GTC',
});If you want to stage multiple orders on one pair, batch APIs are a better fit than serially sending single orders.
await client.submitBatchOrders({
pair: 'XBTUSD',
orders: [
{
ordertype: 'limit',
type: 'buy',
volume: '0.0001',
price: '10000.00',
timeinforce: 'GTC',
// cl_ord_id: client.generateNewOrderID(), // optional: include a custom order ID before placing your order, for easier tracking
},
{
ordertype: 'limit',
type: 'sell',
volume: '0.0001',
price: '13000.00',
timeinforce: 'GTC',
// cl_ord_id: client.generateNewOrderID(), // optional: include a custom order ID before placing your order, for easier tracking
},
],
});Validate the batch without sending:
await client.submitBatchOrders({
pair: 'XBTUSD',
validate: true,
orders: [
{
ordertype: 'limit',
type: 'buy',
volume: '0.0001',
price: '45000.00',
},
{
ordertype: 'limit',
type: 'sell',
volume: '0.0001',
price: '55000.00',
},
],
});See also: Kraken JavaScript Example - How to submit spot orders via REST API
For long-running processes, WebSockets are key for staying in sync with market data & account state changes. Latency-sensitive systems should subscribe & react to event-driven market & account updates, rather than depending on REST API polling at regular intervals.
After subscribing to the topics needed by your system, persistent WebSocket connections will provide real-time updates on any changes to your subscribed topics. Stay informed on new market data as it becomes available. Immediately process and react to any account state changes, such as an order state change or fill. Integrating an event-driven design pattern with WebSockets will both reduce your latency and provide much higher capacity for making API calls within the available rate limits.
The Siebly Kraken JavaScript SDK's WebsocketClient handles most of the complexity of working with WebSockets for you. All you need to do is:
The SDK handles the connection work for you:
reconnecting event, informing you this process has started.
reconnected event, informing you this process has completed.
WebsocketClient events you will actually care about| Event | Meaning |
|---|---|
open | Connection established |
message | Streaming data received |
response | Subscribe, unsubscribe, and auth acknowledgements |
reconnecting | Connection dropped and retrying |
reconnected | Connection restored and subscriptions resynced |
close | Socket closed |
authenticated | Private auth succeeded |
exception | Errors and unexpected conditions |
WS_KEY_MAPWS_KEY_MAP tells the SDK which Kraken WebSocket endpoint family to use:
spotPublicV2spotPrivateV2spotL3V2derivativesPublicV1derivativesPrivateV1This matters because different product groups and topic families do not all live on the same connection endpoint. These keys act as primary keys, similar to a database, to uniquely identify a dedicated connection group.
ws.subscribe(
{
topic: 'ticker',
payload: { symbol: ['BTC/USD', 'ETH/USD'] },
},
WS_KEY_MAP.spotPublicV2,
);
ws.subscribe(
{
topic: 'trade',
payload: { symbol: ['BTC/USD'] },
},
WS_KEY_MAP.spotPublicV2,
);
ws.subscribe(
{
topic: 'ohlc',
payload: {
symbol: ['BTC/USD'],
interval: 1,
},
},
WS_KEY_MAP.spotPublicV2,
);You can also batch multiple subscriptions that share the same WsKey, by sending an array of WebSocket topics:
ws.subscribe(
[
{ topic: 'ticker', payload: { symbol: ['BTC/USD'] } },
{ topic: 'trade', payload: { symbol: ['BTC/USD'] } },
{
topic: 'instrument',
payload: {
symbol: ['BTC/USD'],
include_tokenized_assets: true,
},
},
],
WS_KEY_MAP.spotPublicV2,
);The SDK can authenticate and manage private Spot streams for you:
import { WebsocketClient, WS_KEY_MAP } from '@siebly/kraken-api';
const ws = new WebsocketClient({
apiKey: process.env.API_SPOT_KEY!,
apiSecret: process.env.API_SPOT_SECRET!,
});
ws.subscribe(
{
topic: 'executions',
payload: {
snap_trades: true,
snap_orders: true,
order_status: true,
ratecounter: true,
},
},
WS_KEY_MAP.spotPrivateV2,
);
ws.subscribe(
{
topic: 'balances',
payload: {},
},
WS_KEY_MAP.spotPrivateV2,
);
ws.subscribe(
{
topic: 'level3',
payload: {
symbol: ['BTC/USD'],
},
},
WS_KEY_MAP.spotL3V2,
);The Level 3 order book is a special case. It uses the dedicated L3 endpoint, so spotL3V2 matters.
See also:
WebsocketAPIClientKraken supports authenticated Spot command workflows, such as order management, over a persistent WebSocket connection. While each REST API call requires a new connection to be opened & signed per API call, the WebSocket API allows a persistent WebSocket connection to be opened & authenticated once, and then reused for any WS-API commands sent by your system. This can reduce latency for workflows where a persistent command channel is a better fit than REST alone.
If that model fits your system, WebsocketAPIClient gives you REST-like methods over the WebSocket API.
This utility class is wrapped around the Siebly Kraken JavaScript SDK's WebsocketClient. A persistent WebSocket API connection is automatically opened and managed as needed. Any API calls made via the WebsocketAPIClient are conveniently wrapped in JavaScript promises. This allows for much simpler asynchronous design patterns that feel very much like a REST API, with all the benefits of a persistent WebSocket API connection.
Make a WebSocket API request via a simple function call. Await the result. All of the speed with significantly less complexity.
import { WebsocketAPIClient } from '@siebly/kraken-api';
const wsApi = new WebsocketAPIClient({
apiKey: process.env.API_SPOT_KEY!,
apiSecret: process.env.API_SPOT_SECRET!,
});
wsApi.getWSClient().on('open', (data) => {
console.log('ws api open', data?.wsKey);
});
wsApi.getWSClient().on('exception', console.error);
const order = await wsApi.submitSpotOrder({
order_type: 'limit',
side: 'buy',
limit_price: 26500.4,
order_qty: 1.2,
symbol: 'BTC/USD',
});
await wsApi.amendSpotOrder({
order_id: 'TEST-ORDER-ID',
order_qty: 1.5,
limit_price: 27000,
});
await wsApi.cancelSpotOrder({
order_id: ['TEST-ORDER-ID'],
});
await wsApi.cancelAllSpotOrders();Other supported Spot WebSocket API flows include:
See also: Kraken JavaScript Example - How to send/manage low-latency spot orders via the WebSocket API
Refer to the Kraken API documentation for a detailed list of available WebSocket API capabilities.
While it looks & feels similar, Kraken's Derivatives use a different REST API surface and different request naming conventions than the Kraken Spot APIs. The @siebly/kraken-api JavaScript Kraken SDK manages this complexity for you, so you can focus on building & integrating your workflows.
Usage is similar to Spot. Create an instance of the utility class dedicated to the Kraken Derivatives API, the DerivativesClient. Provide your API keys if private API calls are desired. Call & await functions corresponding to the REST API endpoint you would like to use.
Detailed request building, routing & authentication are all handled under the hood by the SDK. Below are curated examples for common scenarios.
import { DerivativesClient } from '@siebly/kraken-api';
const client = new DerivativesClient();import { DerivativesClient } from '@siebly/kraken-api';
const client = new DerivativesClient({
apiKey: process.env.API_FUTURES_KEY!,
apiSecret: process.env.API_FUTURES_SECRET!,
// testnet: true, // optional: route Derivatives REST API calls to Kraken's demo environment
});const allTickers = await client.getTickers();
const ticker = await client.getTicker({ symbol: 'PF_ETHUSD' });
const orderBook = await client.getOrderbook({ symbol: 'PF_ETHUSD' });
const instruments = await client.getInstruments();
const feeSchedules = await client.getFeeSchedules();
const candles = await client.getCandles({
tickType: 'trade',
symbol: 'PF_ETHUSD',
resolution: '1h',
});You can also query recent public trade-style events:
const executions = await client.getPublicExecutionEvents({
tradeable: 'PF_ETHUSD',
});See also: Kraken JavaScript Example - How to query derivatives market data
Limit order:
await client.submitOrder({
orderType: 'lmt',
symbol: 'PF_ETHUSD',
side: 'buy',
size: 0.01,
limitPrice: 1000,
cliOrdId: client.generateNewOrderID(),
});Market order:
await client.submitOrder({
orderType: 'mkt',
symbol: 'PF_ETHUSD',
side: 'sell',
size: 0.01,
});Post-only and reduce-only:
await client.submitOrder({
orderType: 'post',
symbol: 'PF_ETHUSD',
side: 'buy',
size: 0.01,
limitPrice: 1000,
cliOrdId: client.generateNewOrderID(),
});
await client.submitOrder({
orderType: 'lmt',
symbol: 'PF_ETHUSD',
side: 'sell',
size: 1,
limitPrice: 1000,
reduceOnly: true,
});Batch order management:
await client.batchOrderManagement({
json: {
batchOrder: [
{
order: 'send',
order_tag: 'order-1',
orderType: 'lmt',
symbol: 'PF_ETHUSD',
side: 'buy',
size: 0.01,
limitPrice: 1000,
cliOrdId: client.generateNewOrderID(),
},
],
},
});See also: Kraken JavaScript Example - How to submit derivatives/futures orders
For subscribing to futures/derivatives market & account data in JavaScript (& Node.js), the SDK automatically handles this as well via the same WebsocketClient utility class.
import { WebsocketClient, WS_KEY_MAP } from '@siebly/kraken-api';
const ws = new WebsocketClient();
ws.on('open', (data) => console.log('connected', data?.wsKey));
ws.on('message', (data) => console.log('message', JSON.stringify(data)));
ws.on('reconnected', (data) => console.log('reconnected', data?.wsKey));
ws.on('exception', console.error);
ws.subscribe(
{
topic: 'trade',
payload: {
product_ids: ['PI_XBTUSD', 'PI_ETHUSD'],
},
},
WS_KEY_MAP.derivativesPublicV1,
);See also:
This is where SDKs usually earn their keep: not in the first successful request, but in the repeatable behavior around retries, reconnects, logging, and safe rollout.
For Spot, use cl_ord_id. For Futures, use cliOrdId. This makes retries and reconciliation safer.
const orderIdForEntry1 = client.generateNewOrderID();
const result = await client.submitOrder({
ordertype: 'limit',
type: 'buy',
pair: 'XBTUSD',
volume: '0.0001',
price: '10000',
validate: true,
cl_ord_id: orderIdForEntry1,
});
console.log(result);
// Detect entry 1 has filled, by looking for an order fill with cl_ord_id === orderIdForEntry1 either via REST API or async WebSocket updates.Listen for reconnecting and reconnected. A dropped connection is not the exceptional case in production. Recovery behavior is part of the design. WebSockets can be unstable, especially during volatility.
The important part is detecting issues early (handled by SDK), promptly reconnecting (handled by SDK), and ensuring your system remains in sync when the SDK emits a reconnected event (up to your implementation).
The lowest-friction rollout path is:
If using WebSockets for updates, integrate a backfill workflow after connecting:
This ensures your system has the full history it needs before it starts processing new market & account updates.
Do not blur product boundaries in your code or secrets management. Spot and Futures use different credentials and different request models.
Spot & Futures do not use the same symbol formatting. Treat symbols as product-specific inputs, not one universal string format. If needed, build your own solution to normalise outgoing & incoming symbols into a format your system can consistently work with.
If you want to integrate SDK logs into your own monitoring stack:
import { WebsocketClient, DefaultLogger, LogParams } from '@siebly/kraken-api';
const customLogger: DefaultLogger = {
trace: (..._params: LogParams) => {},
info: (...params: LogParams) => console.log(...params),
error: (...params: LogParams) => console.error(...params),
};
const ws = new WebsocketClient({}, customLogger);See also: Kraken JavaScript Example - How to subscribe to spot market data with WebSockets
Most early Kraken API issues are not SDK installation problems. They are usually auth, product boundary, symbol, or lifecycle issues. Start here when the first example works but the next workflow does not.
| Problem | Likely cause | Fix |
|---|---|---|
| Public REST works, private REST fails | API key is missing, loaded under the wrong environment variable, or belongs to the wrong Kraken product group | Log which key names are present, not the secret values. Confirm Spot keys are used with SpotClient and Futures keys are used with DerivativesClient. |
| Private WebSocket never authenticates | Private stream credentials are missing or the wrong WS_KEY_MAP entry is used | Use Spot credentials with WS_KEY_MAP.spotPrivateV2. Use derivatives credentials with derivatives WebSocket keys. |
| Market data request returns an unexpected pair or symbol error | Spot and Futures symbols use different formats | Treat symbols as product-specific inputs. Do not reuse one normalized symbol string across Spot REST, Futures REST, and WebSocket payloads without mapping it first. |
| WebSocket process reconnects and the app state looks stale | The connection recovered, but the app did not backfill missed state | Listen for reconnected, then query REST for the latest balances, orders, or market state before resuming normal processing. |
| Order request is rejected | Size, price, pair, permission, or order type is invalid for that market | Use validate: true for Spot orders while testing. Log sanitized request fields and compare them with the market's minimum size, precision, and permission requirements. |
| Retries create confusing order tracking | The integration does not assign client-generated IDs | Use cl_ord_id for Spot and cliOrdId for Futures so retries and reconciliation can be tied back to your own request IDs. |
| The code works locally but fails in deployment | Environment variables or secret loading differ between local and production | Make env loading explicit, fail fast when required private keys are absent, and keep public-only examples free of private client construction. |
If a public REST request fails, debug connectivity, package installation, or runtime configuration first. If public REST works and private calls fail, debug credentials and permissions next. If REST works but WebSockets fail, debug event handling, WS_KEY_MAP, reconnect behavior, and private stream authentication.
If you are evaluating SDKs rather than just copying a few snippets, these are the practical reasons this SDK tends to matter:
Do I need separate keys for Spot and Futures? Yes. Treat Spot and Futures as separate products with separate API credentials. These can be managed within your Kraken account.
Why both WebsocketClient and WebsocketAPIClient?
WebsocketClient is for subscriptions and streaming topics.WebsocketAPIClient is for Spot commands over Kraken's WebSocket API. Think "REST API" but via low-latency WebSockets.Does the SDK handle private authentication? Yes. All authentication for both REST APIs & WebSockets will be handled automatically using the underlying SDK architecture. Connectivity & authentication are both managed for you, so you can focus on integrating your system and making the API calls that you need.
What happens if the connection drops?
The SDK supports reconnect and resubscribe flows. Listen for reconnecting and reconnected.
The reconnecting event is a good trigger to pause any risky actions until the connection is restored & ready (cancel orders and prevent new orders).
The reconnected event is a good trigger to query the REST API for any out-of-sync account & market state before resuming normal private workflows (e.g. restore cancelled orders, resume paused order placement as desired).
Can I use this Kraken API SDK in TypeScript projects? Yes. The package is TypeScript-first and publishes type declarations.
Do I need TypeScript to use this JavaScript Kraken SDK? Pure JavaScript projects (including Node.js & Bun) can use this SDK too. TypeScript type declarations are included (and will help while working with the SDK in your IDE), but TypeScript is not required to use this JavaScript SDK for Kraken.
Can I use this package in both ESM and CommonJS projects? Yes. The package supports both. It is built & published to npm as a hybrid project. Your project will automatically import the correct bundle, due to the configuration in the SDK's package.json.
Does this guide cover every SDK method? Yes, complete API coverage is expected across all available product groups in Kraken's API offering, both for REST APIs & WebSockets. We regularly monitor the API for changes & regularly keep the Siebly JavaScript SDK for Kraken up to date. If any functionality happens to be missing or out of date, please get in touch by opening an issue on GitHub.
For full method coverage, see:
If you want to learn more about integrating with Kraken's APIs & WebSockets:
@siebly/kraken-apisieblyio/kraken-apiReturn to install snippets, direct examples, endpoint maps, and package links.
Map Kraken REST and WebSocket API methods to the current JavaScript SDK calls.
Review package release integrity, safe SDK usage, and key-handling guidance.
Compare Kraken with the other Siebly JavaScript and TypeScript exchange SDKs.
We use essential cookies and optional analytics. Read the Privacy Policy.
Essential cookies stay on. Toggle analytics if you want to share anonymous usage insights. You can revisit this anytime via Cookie Settings in the footer.