Hyperliquid JavaScript SDK
Build with the Hyperliquid REST API & WebSockets with our JavaScript SDK, TypeScript-first package declarations, and Node.js-compatible runtime patterns. Discover installation, common examples, a detailed endpoint-to-function map, and the REST API/WebSocket patterns shared across our Siebly SDK family.
Use the same TypeScript-first REST API and WebSocket clients from plain JavaScript or TypeScript in Node.js-compatible runtimes.
Package surfaces
Explore the following API capabilities are covered by our Hyperliquid SDK:
- Perpetuals
- Spot
- Account State
- WebSockets
- WebSocket API
- Testnet
- WebSocket clients with:
- Built-in heartbeats.
- Automatic reconnection.
- Automatic reauthentication and resubscribe where the exchange supports it.
- Promise-wrapped WebSocket API commands you can await like a REST API.
- Typed requests and responses for Node.js, JavaScript, and TypeScript IDEs.
- Framework-neutral JavaScript snippets that stay approachable in Node.js-compatible runtimes.
- TypeScript-first package declarations for stricter services, shared libraries, and editor-assisted integrations.
Install Hyperliquid SDK
# Via your favourite package manager, e.g. npm:
npm install @siebly/hyperliquid-api
# or pnpm:
pnpm install @siebly/hyperliquid-api
# or yarn:
yarn add @siebly/hyperliquid-apiQuickstart Examples with the Hyperliquid JavaScript SDK
Get started with just a few lines of JavaScript. TypeScript, while not required, is absolutely recommended. TypeScript declarations are included with all our SDKs and provide convenient definitions on request & response fields, WebSocket payloads, and generally safer integrations.
import { RestClient } from '@siebly/hyperliquid-api'; const client = new RestClient(); async function main() { try { const status = await client.getExchangeStatus(); console.log('Exchange status:', status); } catch (error) { console.error('Exchange-status request failed:', error); } try { const mids = await client.getAllMids(); console.log('BTC midpoint:', mids.BTC); } catch (error) { console.error('Midpoint request failed:', error); } try { const metadata = await client.getPerpMetadata(); const btc = metadata.universe.find((asset) => asset.name === 'BTC'); console.log('BTC perpetual metadata:', btc); } catch (error) { console.error('Perpetual metadata request failed:', error); } try { const orderBook = await client.getOrderBook({ coin: 'BTC', }); console.log('Best bid:', orderBook?.levels[0][0]); console.log('Best ask:', orderBook?.levels[1][0]); } catch (error) { console.error('Order-book request failed:', error); } try { const candles = await client.getCandles({ coin: 'BTC', interval: '1h', startTime: Date.now() - 24 * 60 * 60 * 1000, }); console.log('Latest hourly candle:', candles.at(-1)); } catch (error) { console.error('Candle request failed:', error); } try { const trades = await client.getRecentTrades({ coin: 'BTC', }); console.log('Most recent trade:', trades[0]); } catch (error) { console.error('Recent-trade request failed:', error); }} main();import { WebsocketClient } from '@siebly/hyperliquid-api'; const client = new WebsocketClient(); async function main() { client .on('open', ({ wsKey }) => { console.log('WebSocket opened:', wsKey); }) .on('reconnecting', ({ wsKey, event }) => { console.log('WebSocket reconnecting:', wsKey, event); }) .on('reconnected', ({ wsKey }) => { console.log('WebSocket reconnected:', wsKey); }) .on('close', ({ wsKey }) => { console.log('WebSocket closed:', wsKey); }) .on('exception', ({ wsKey, event }) => { console.error('WebSocket exception:', wsKey, event); }); try { await client.subscribe({ type: 'allMids' }, (update) => { console.log('BTC midpoint:', update.mids.BTC); }); } catch (error) { console.error('Midpoint subscription failed:', error); } try { await client.subscribe({ type: 'l2Book', coin: 'BTC' }, (book) => { console.log('Best bid:', book.levels[0][0]); console.log('Best ask:', book.levels[1][0]); }); } catch (error) { console.error('Order-book subscription failed:', error); } try { await client.subscribe({ type: 'trades', coin: 'BTC' }, (trades) => { console.log('Trades:', trades); }); } catch (error) { console.error('Trade subscription failed:', error); } try { await client.subscribe( { type: 'candle', coin: 'BTC', interval: '1m' }, (candle) => { console.log('One-minute candle:', candle); }, ); } catch (error) { console.error('Candle subscription failed:', error); }} main();import { randomBytes } from 'node:crypto';import { WebsocketAPIClient } from '@siebly/hyperliquid-api'; const privateKey = process.env.HYPERLIQUID_TESTNET_API_WALLET_KEY;const accountAddress = process.env.HYPERLIQUID_TESTNET_ACCOUNT_ADDRESS; if (!privateKey || !accountAddress) { throw new Error( 'Set HYPERLIQUID_TESTNET_API_WALLET_KEY and HYPERLIQUID_TESTNET_ACCOUNT_ADDRESS before starting.', );} const client = new WebsocketAPIClient({ privateKey, accountAddress, testnet: true,}); function trimDecimal(value) { if (!value.includes('.')) { return value; } return value.replace(/0+$/, '').replace(/\.$/, '');} function sizeForNotional(price, szDecimals, targetNotional) { const factor = 10 ** szDecimals; const size = Math.ceil((targetNotional / Number(price)) * factor) / factor; return trimDecimal(size.toFixed(szDecimals));} async function main() { client .on('open', ({ wsKey }) => { console.log('WebSocket API opened:', wsKey); }) .on('reconnected', ({ wsKey }) => { console.log('WebSocket API reconnected:', wsKey); }) .on('exception', ({ wsKey, event }) => { console.error('WebSocket API exception:', wsKey, event); }); let btc; let orderBook; try { const metadata = await client.getPerpMetadata(); btc = metadata.universe.find((asset) => asset.name === 'BTC'); console.log('BTC metadata:', btc); } catch (error) { console.error('WebSocket metadata request failed:', error); client.closeAll(); return; } if (!btc) { console.error('BTC was not returned by the Testnet perpetual metadata.'); client.closeAll(); return; } try { orderBook = await client.getOrderBook({ coin: 'BTC' }); console.log('BTC order book received at:', orderBook?.time); } catch (error) { console.error('WebSocket order-book request failed:', error); client.closeAll(); return; } const bid = orderBook?.levels[0][4] ?? orderBook?.levels[0][0]; if (!bid) { console.error('The BTC order book did not contain a bid.'); client.closeAll(); return; } const clientOrderId = `0x${randomBytes(16).toString('hex')}`; const size = sizeForNotional(bid.px, btc.szDecimals, 12); let orderId; try { const result = await client.submitLimitOrder({ symbol: 'BTC', side: 'buy', price: bid.px, size, postOnly: true, clientOrderId, }); console.log('WebSocket order response:', result); if (result.status !== 'ok') { console.error('Hyperliquid rejected the order request:', result.response); client.closeAll(); return; } const orderStatus = result.response.data?.statuses[0]; if (!orderStatus) { console.error('The order response did not contain an order status.'); client.closeAll(); return; } if ('error' in orderStatus) { console.error('The order was rejected:', orderStatus.error); client.closeAll(); return; } if ('filled' in orderStatus) { console.log('The order filled immediately:', orderStatus.filled); client.closeAll(); return; } orderId = orderStatus.resting.oid; console.log('Resting order ID:', orderId); } catch (error) { console.error('WebSocket order submission failed:', error); client.closeAll(); return; } try { const currentOrder = await client.getOrderStatus({ oid: orderId }); console.log('Order before cancellation:', currentOrder); } catch (error) { console.error('WebSocket order-status request failed:', error); } try { const cancellation = await client.cancelOrdersByClientOrderId({ cancels: [{ asset: 'BTC', cloid: clientOrderId }], }); console.log('WebSocket cancellation response:', cancellation); } catch (error) { console.error('WebSocket cancellation failed:', error); } try { const finalOrder = await client.getOrderStatus({ oid: clientOrderId }); console.log('Final WebSocket order state:', finalOrder); } catch (error) { console.error('Final WebSocket order-status request failed:', error); } client.closeAll();} main();Hyperliquid API JavaScript Tutorial
A practical JavaScript guide to using @siebly/hyperliquid-api for Hyperliquid market data, account state, perpetual and Spot orders, WebSocket streams, WebSocket API requests, Testnet, proxies, and recovery.
Your app / service
bot, dashboard, worker
@siebly/hyperliquid-api
RestClient, WebsocketClient, WebsocketAPIClient
Hyperliquid APIs
Info requests, signed Exchange actions, streaming subscriptions, and WebSocket POST requests
Common Hyperliquid implementation tasks
Start from the behavior you need, not just from REST or WebSocket as a transport. Market-data driven systems should be event driven. Backfill via the REST API once and let WebSockets passively stream new data to you, as it becomes available.
REST API hydration or backfill
Start from the REST API quickstart and endpoint reference, then normalize exchange-specific IDs, timestamps, symbols, and product scope.
Open quickstartWebSocket consumer
Start from the WebSocket quickstart that matches the task boundary, verify subscription acknowledgement semantics, and keep reconnect handling explicit.
Open WebSocket quickstartAgent prompt recipe
Use the AI prompt generator when the task combines REST API hydration, live streams, in-memory state, operational outputs, or strategy code.
Build an agent promptFor coding agents
Give these files to an agent before implementation so it can find the package, examples, task guidance, and safety rules from the normal SDK-page flow.
AI prompt framework
Prompt generator and task recipes for exchange API projects.
llms.txt
Compact discovery file for agents choosing where to start.
llms-full.txt
Full route and implementation guidance index for machine readers.
SDK catalog
Machine-readable package, docs, examples, and task guidance.
Agent skill
Reusable workflow rules for coding agents using exchange APIs.
Hyperliquid JavaScript FAQ
What does the Hyperliquid JavaScript SDK cover?
Hyperliquid supports Perpetuals, Spot, Account State, WebSockets, WebSocket API, and Testnet workflows. The JavaScript guide covers the main REST and WebSocket integration patterns.
How do I authenticate private Hyperliquid API calls in JavaScript?
Install @siebly/hyperliquid-api from npm & pass API credentials into the SDK client options, as shown in the Hyperliquid JavaScript examples above. The SDK handles the exchange-specific signing requirements for private requests.
Does the Hyperliquid JavaScript SDK help with WebSocket connection management?
Yes. Use the SDK WebSocket client for subscriptions, reconnect handling, and stream lifecycle management instead of building raw socket flows yourself.
When should I use the Hyperliquid WebSocket API instead of REST?
Use REST for standard request and response workflows such as account queries and order management. Use the WebSocket API flow when you want persistent low-latency interactions over a connected session.
Direct Example Files
Open the example files below for JavaScript and TypeScript-compatible request, authentication, WebSocket, and Node.js service patterns.