Skip to content

wrytes/deribit-api-client

Repository files navigation

@wrytes/deribit-api-client

A lightweight, fully-typed WebSocket client for the Deribit API (v2). Built on JSON-RPC 2.0 over WebSocket with automatic reconnection, scope-aware authentication, and generic response modifiers.


Table of Contents


Installation

npm install @wrytes/deribit-api-client
# or
pnpm add @wrytes/deribit-api-client

Quick Start

import { createDeribitClient, createDeribitClientPublic, GrantType, Currency } from '@wrytes/deribit-api-client'

// Public client — no credentials needed
const client = createDeribitClientPublic()

const currencies = await client.market.getCurrencies({})
console.log(currencies.result)

// Authenticated client
const authClient = createDeribitClient({
  type: GrantType.client_credentials,
  baseUrl: 'wss://www.deribit.com/ws/api/v2',
  clientId: 'YOUR_CLIENT_ID',
  clientSecret: 'YOUR_CLIENT_SECRET',
})

const summary = await authClient.account.getAccountSummary({ currency: Currency.BTC })
console.log(summary.result)

// Close the connection when done
authClient.close()

Client Initialization

Public Client

Use createDeribitClientPublic for read-only market data that does not require authentication.

import { createDeribitClientPublic, GrantType } from '@wrytes/deribit-api-client'

// Uses wss://www.deribit.com/ws/api/v2 by default
const client = createDeribitClientPublic()

// Override the base URL (e.g. testnet)
const testClient = createDeribitClientPublic({
  type: GrantType.client_public,
  baseUrl: 'wss://test.deribit.com/ws/api/v2',
})

Authenticated Client

Use createDeribitClient with GrantType.client_credentials to access private endpoints. Authentication happens automatically when the WebSocket connection opens.

import { createDeribitClient, GrantType } from '@wrytes/deribit-api-client'

const client = createDeribitClient({
  type: GrantType.client_credentials,
  baseUrl: 'wss://www.deribit.com/ws/api/v2',
  clientId: 'YOUR_CLIENT_ID',
  clientSecret: 'YOUR_CLIENT_SECRET',
})

Type definitions:

type ClientPublicOptions = {
  type: GrantType.client_public
  baseUrl: string
}

type ClientCredentialsOptions = {
  type: GrantType.client_credentials
  baseUrl: string
  clientId: string
  clientSecret: string
}

type ClientOptions = ClientPublicOptions | ClientCredentialsOptions

Architecture

DeribitApiClient
├── .account        → AccountMapping
├── .market         → MarketMapping
├── .trading        → TradingMapping
├── .wallet         → WalletMapping
├── .authentication → AuthenticationMapping
├── .session        → SessionMapping        (placeholder)
└── .subscription   → SubscriptionMapping   (placeholder)

Internally, all methods call client.send(), which:

  1. Verifies the WebSocket is open (reconnects if needed)
  2. Validates that the client has required auth/scope for private endpoints
  3. Sends a JSON-RPC 2.0 request with a unique numeric ID
  4. Returns a Promise that resolves when the matching response arrives (10s timeout)

The core send signature (for library authors / contributors):

send<RequestParams, ApiResult, Modifier = RequestQuery<ApiResult>>(
  method: string,
  scope: string[],
  params: RequestParams,
  callback?: (data: RequestQuery<ApiResult>) => Modifier
): Promise<Modifier>

API Surface

Account

All account methods require an authenticated client with at least account:read scope.

client.account.getAccountSummary(params, modifier?)

Returns a full account summary for a single currency.

import { Currency } from '@wrytes/deribit-api-client'

const res = await client.account.getAccountSummary({
  currency: Currency.BTC,
  extended: true,       // include user details and fees (optional)
  subaccount_id: 123,   // optional
})

console.log(res.result.balance)
console.log(res.result.equity)
console.log(res.result.margin_balance)

Params:

Field Type Required Description
currency Currency Yes Target currency
subaccount_id number No Subaccount to query
extended boolean No Include user details and fee info

client.account.getAccountSummaries(params, modifier?)

Returns account summaries for all currencies in a single call.

const res = await client.account.getAccountSummaries({ extended: false })
console.log(res.result.summaries) // GetAccountSummariesItem[]

client.account.getPosition(params, modifier?)

Returns the current position for a specific instrument.

const res = await client.account.getPosition({
  instrument_name: 'BTC-PERPETUAL',
})

// Returns GetPositionResultAll | GetPositionResultOption
// Discriminated by `kind` field
if (res.result.kind === 'option') {
  console.log(res.result.delta) // option-specific fields
} else {
  console.log(res.result.size)
}

client.account.getPortfolioMargins(params, modifier?)

Returns portfolio margin calculations and risk metrics for a currency.

const res = await client.account.getPortfolioMargins({
  currency: Currency.ETH,
  simulated_positions: { 'ETH-PERPETUAL': 1.5 }, // optional
})

client.account.getTransactionLog(params, modifier?)

Returns a paginated transaction history for a currency and time window.

import { TransactionQuery } from '@wrytes/deribit-api-client'

const res = await client.account.getTransactionLog({
  currency: Currency.BTC,
  start_timestamp: 1700000000000,
  end_timestamp: Date.now(),
  query: TransactionQuery.trade,
  count: 50,
  continuation: undefined, // use res.result.continuation for next page
})

console.log(res.result.logs)         // TransactionLog[]
console.log(res.result.continuation) // pass this to get the next page

Market

All market methods are public — no authentication required.

client.market.getCurrencies(params, modifier?)

Returns all supported currencies with their withdrawal configurations.

const res = await client.market.getCurrencies({})
console.log(res.result) // MarketGetCurrenciesResult[]

client.market.getInstruments(params, modifier?)

Returns all instruments for a currency, optionally filtered by kind.

import { InstrumentKind } from '@wrytes/deribit-api-client'

const res = await client.market.getInstruments({
  currency: 'BTC',
  kind: InstrumentKind.option,
  expired: false, // exclude expired instruments
})

client.market.getBookSummaryByCurrency(params, modifier?)

Returns market data (bid, ask, last, volume, funding, etc.) for all instruments in a currency.

const res = await client.market.getBookSummaryByCurrency({
  currency: Currency.ETH,
  kind: InstrumentKind.future,
})

client.market.getBookSummaryByInstrument(params, modifier?)

Returns market book data for a single instrument.

const res = await client.market.getBookSummaryByInstrument({
  instrument_name: 'BTC-PERPETUAL',
})

console.log(res.result.mark_price)
console.log(res.result.current_funding)
console.log(res.result.volume_usd)

client.market.getIndexPrice(params, modifier?)

Returns the current spot index price and estimated delivery price for an index.

const res = await client.market.getIndexPrice({
  index_name: 'btc_usd',
})

console.log(res.result.index_price)
console.log(res.result.estimated_delivery_price)

client.market.getDeliveryPrices(params, modifier?)

Returns historical delivery prices for a given index, with pagination.

import { MarketGetDeliveryPricesNames } from '@wrytes/deribit-api-client'

const res = await client.market.getDeliveryPrices({
  index_name: MarketGetDeliveryPricesNames.btc_usd,
  offset: 0,
  count: 25,
})

client.market.getVolatilityIndexData(params, modifier?)

Returns OHLC candles for a volatility index over a time range.

const res = await client.market.getVolatilityIndexData({
  currency: 'BTC',
  start_timestamp: 1700000000000,
  end_timestamp: Date.now(),
  resolution: '3600', // 1 | 60 | 3600 | 43200 | 86400 | '1D'
})

// res.result.data: VolatilityIndexDataPoint[]
// res.result.continuation: string | undefined

Trading

All trading methods require an authenticated client.

Method Required Scope
buy trade:read_write
sell trade:read_write
cancel trade:read_write
getOpenOrdersByCurrency trade:read
getOpenOrdersByInstrument trade:read
getOrderState trade:read

client.trading.buy(params, modifier?)

Places a buy order.

import { OrderType, TimeInForce } from '@wrytes/deribit-api-client'

const res = await client.trading.buy({
  instrument_name: 'BTC-PERPETUAL',
  amount: 10,
  type: OrderType.limit,
  price: 60000,
  time_in_force: TimeInForce.good_til_cancelled,
  post_only: true,
  reduce_only: false,
  label: 'my-order-1',
})

console.log(res.result.order)   // OrderState
console.log(res.result.trades)  // Trade[]

client.trading.sell(params, modifier?)

Places a sell order. Same parameters and return shape as buy.

const res = await client.trading.sell({
  instrument_name: 'ETH-PERPETUAL',
  amount: 1,
  type: OrderType.market,
})

client.trading.cancel(params, modifier?)

Cancels an open order by ID.

const res = await client.trading.cancel({
  order_id: 'ETH-123456789',
})

console.log(res.result.order_state) // 'cancelled'

client.trading.getOpenOrdersByCurrency(params, modifier?)

Returns all open orders for a currency.

const res = await client.trading.getOpenOrdersByCurrency({
  currency: 'BTC',
  kind: 'future', // optional
  type: 'limit',  // optional
})

console.log(res.result) // OrderState[]

client.trading.getOpenOrdersByInstrument(params, modifier?)

Returns all open orders for a specific instrument.

const res = await client.trading.getOpenOrdersByInstrument({
  instrument_name: 'BTC-PERPETUAL',
})

client.trading.getOrderState(params, modifier?)

Returns the current state of a single order.

const res = await client.trading.getOrderState({
  order_id: 'BTC-987654321',
})

console.log(res.result.filled_amount)
console.log(res.result.order_state)

Wallet

All wallet methods require an authenticated client.

Method Required Scope
withdraw wallet:read_write
cancelWithdrawal wallet:read_write
cancelTransferById wallet:read_write
createDepositAddress wallet:read_write
getWithdrawals wallet:read
getDeposits wallet:read
getTransfers wallet:read
getCurrentDepositAddress wallet:read

client.wallet.withdraw(params, modifier?)

Initiates a withdrawal.

import { WalletWithdrawPriority } from '@wrytes/deribit-api-client'

const res = await client.wallet.withdraw({
  currency: Currency.BTC,
  address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7Divf0a',
  amount: 0.01,
  priority: WalletWithdrawPriority.high,
})

client.wallet.getWithdrawals(params, modifier?)

Returns paginated withdrawal history.

const res = await client.wallet.getWithdrawals({
  currency: Currency.ETH,
  count: 20,
  offset: 0,
})

console.log(res.result.count)  // total withdrawals
console.log(res.result.data)   // WalletGetWithdrawalsItem[]

client.wallet.getDeposits(params, modifier?)

Returns paginated deposit history.

const res = await client.wallet.getDeposits({
  currency: Currency.USDC,
  count: 20,
  offset: 0,
})

client.wallet.getTransfers(params, modifier?)

Returns paginated internal transfer history.

const res = await client.wallet.getTransfers({
  currency: Currency.BTC,
  count: 10,
})

client.wallet.getCurrentDepositAddress(params, modifier?)

Returns the current deposit address for a currency, or null if none exists.

const res = await client.wallet.getCurrentDepositAddress({
  currency: Currency.BTC,
})

if (res.result) {
  console.log(res.result.address)
}

client.wallet.createDepositAddress(params, modifier?)

Generates a new deposit address for a currency.

const res = await client.wallet.createDepositAddress({
  currency: Currency.ETH,
})

console.log(res.result.address)

client.wallet.cancelWithdrawal(params, modifier?)

Cancels a pending withdrawal by numeric ID.

const res = await client.wallet.cancelWithdrawal({
  currency: Currency.BTC,
  id: 42,
})

client.wallet.cancelTransferById(params, modifier?)

Cancels an internal transfer by numeric ID.

const res = await client.wallet.cancelTransferById({
  currency: Currency.BTC,
  id: 7,
})

Authentication

The authentication mapping is used internally when the client is initialized with GrantType.client_credentials. Direct usage is available for custom flows.

client.authentication.auth(params, modifier?)

import { GrantType } from '@wrytes/deribit-api-client'

const res = await client.authentication.auth({
  grant_type: GrantType.client_credentials,
  client_id: 'YOUR_CLIENT_ID',
  client_secret: 'YOUR_CLIENT_SECRET',
})

console.log(res.result.access_token)
console.log(res.result.scope)
console.log(res.result.expires_in)

Response Shape

Every method returns a Promise<RequestQuery<Result>>, which is a discriminated union:

// Success
type RequestQueryReceived<ApiResult> = {
  jsonrpc: `${number}.${number}`
  id: number
  result: ApiResult     // the actual payload
  testnet: boolean
  usDiff: number        // server processing time (microseconds)
  usIn: number          // time until request received (microseconds)
  usOut: number         // time until response sent (microseconds)
}

// API-level error
type RequestQueryError = {
  jsonrpc: `${number}.${number}`
  id: number
  error: {
    code: number
    message: string
    data?: any
  }
  testnet: boolean
  usDiff: number
  usIn: number
  usOut: number
}

type RequestQuery<ApiResult> = RequestQueryReceived<ApiResult> | RequestQueryError

Check for errors by inspecting the response:

const res = await client.market.getIndexPrice({ index_name: 'btc_usd' })

if ('error' in res) {
  console.error(res.error.message)
} else {
  console.log(res.result.index_price)
}

Response Modifiers

Every method accepts an optional second argument — a callback that transforms the raw response before the Promise resolves. This is useful for extracting just the result or reshaping data inline.

// Return only the result payload, not the full JSON-RPC envelope
const price = await client.market.getIndexPrice(
  { index_name: 'eth_usd' },
  (res) => ('result' in res ? res.result.index_price : null)
)

console.log(price) // number | null

The generic type parameter is inferred from the modifier's return type:

// TypeScript infers res as number
const balance = await client.account.getAccountSummary(
  { currency: Currency.BTC },
  (data) => ('result' in data ? data.result.balance : 0)
)

Error Handling

Client-level errors are thrown (not returned) and have a code and message:

Error Code Cause
ErrorClientNotReady -1 WebSocket is not in OPEN state
ErrorClientRequestTimeout -2 No response received within 10 seconds
ErrorClientRestrictedToPublic -3 Private method called on a public client
ErrorClientRestrictedToScope -4 Client lacks required scope for the method
import {
  ErrorClientNotReady,
  ErrorClientRequestTimeout,
  ErrorClientRestrictedToPublic,
  ErrorClientRestrictedToScope,
} from '@wrytes/deribit-api-client'

try {
  const res = await client.trading.buy({ ... })
} catch (err: any) {
  if (err.code === ErrorClientRestrictedToPublic.code) {
    console.error('Use an authenticated client for trading.')
  } else if (err.code === ErrorClientRequestTimeout.code) {
    console.error('Request timed out.')
  }
}

API-level errors (invalid params, insufficient balance, etc.) are returned in the response body — see Response Shape.


Enums & Types Reference

GrantType

enum GrantType {
  client_public      = 'client_public'
  client_credentials = 'client_credentials'
  client_signature   = 'client_signature'
  refresh_token      = 'refresh_token'
}

Currency

enum Currency {
  BTC  = 'BTC'
  ETH  = 'ETH'
  USDC = 'USDC'
  USDT = 'USDT'
  EURR = 'EURR'
}

InstrumentKind

enum InstrumentKind {
  future       = 'future'
  option       = 'option'
  spot         = 'spot'
  future_combo = 'future_combo'
  option_combo = 'option_combo'
}

OrderType

enum OrderType {
  limit       = 'limit'
  market      = 'market'
  stop_limit  = 'stop_limit'
  stop_market = 'stop_market'
}

TimeInForce

enum TimeInForce {
  good_til_cancelled  = 'good_til_cancelled'
  good_til_day        = 'good_til_day'
  fill_or_kill        = 'fill_or_kill'
  immediate_or_cancel = 'immediate_or_cancel'
}

WalletWithdrawPriority

enum WalletWithdrawPriority {
  insane       = 'insane'
  extreme_high = 'extreme_high'
  very_high    = 'very_high'
  high         = 'high'
  mid          = 'mid'
  low          = 'low'
  very_low     = 'very_low'
}

TransactionQuery

Filter type for getTransactionLog:

enum TransactionQuery {
  trade, maker, taker, open, close, liquidation,
  buy, sell, withdrawal, delivery, settlement, deposit,
  transfer, option, future, correction, block_trade, swap
}

GetPositionDirection

enum GetPositionDirection {
  buy  = 'buy'
  sell = 'sell'
  zero = 'zero'
}

OrderState

type OrderState = {
  order_id: string
  instrument_name: string
  direction: 'buy' | 'sell'
  order_type: string
  order_state: 'open' | 'filled' | 'rejected' | 'cancelled' | 'untriggered'
  amount: number
  filled_amount: number
  price: number
  average_price: number
  label: string
  creation_timestamp: number
  last_update_timestamp: number
  time_in_force: string
  reduce_only: boolean
  post_only: boolean
}

Trade

type Trade = {
  trade_id: string
  order_id: string
  instrument_name: string
  direction: 'buy' | 'sell'
  amount: number
  price: number
  fee: number
  fee_currency: string
  timestamp: number
}

AccountLimits / RateLimit

type RateLimit = {
  rate: number   // requests per second
  burst: number  // maximum burst capacity
}

type AccountLimits = {
  matching_engine: {
    block_rfq_maker: RateLimit
    cancel_all: RateLimit
    guaranteed_mass_quotes: RateLimit
    maximum_mass_quotes: RateLimit
    maximum_quotes: RateLimit
    spot: RateLimit
    trading: { total: RateLimit }
  }
  limits_per_currency: boolean
  non_matching_engine: RateLimit
}

MarketGetDeliveryPricesNames

Supported index names for delivery prices — covers major crypto pairs with _usd, _usdc, and _usdt suffixes:

ada_usd, algo_usd, avax_usd, bch_usd, btc_usd, doge_usd, dot_usd, eth_usd,
link_usd, ltc_usd, matic_usd, near_usd, shib_usd, sol_usd, trx_usd, uni_usd,
usdc_usd, xrp_usd, btcdvol_usdc, ethdvol_usdc,
... and _usdc / _usdt variants of the above

Scope & Permissions

When authenticated, the client stores scopes returned by the auth endpoint and uses them to validate private requests. The scopes correspond to the Deribit OAuth 2.0 permission model:

Scope Methods
account:read All client.account.* methods
trade:read getOpenOrdersByCurrency, getOpenOrdersByInstrument, getOrderState
trade:read_write buy, sell, cancel
wallet:read getWithdrawals, getDeposits, getTransfers, getCurrentDepositAddress
wallet:read_write withdraw, createDepositAddress, cancelWithdrawal, cancelTransferById

Requesting a method without the required scope will throw ErrorClientRestrictedToScope.


WebSocket Behavior

  • Protocol: WebSocket JSON-RPC 2.0
  • Default URL: wss://www.deribit.com/ws/api/v2
  • Testnet URL: wss://test.deribit.com/ws/api/v2
  • Auto-reconnect: 60 seconds after connection closes
  • Request timeout: 10 seconds per individual request
  • Authentication: Automatic on socket open for client_credentials clients

JSON-RPC 2.0 request format:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "public/get_index_price",
  "params": { "index_name": "btc_usd" }
}

Responses are matched to pending requests by their id field. Unmatched or timed-out requests are rejected via the timeout error.


Build & Distribution

# Install dependencies
pnpm install

# Build for distribution (CommonJS + ESM + type defs)
pnpm npm:build

# TypeScript compile only
pnpm build

# Publish to npm
pnpm npm:publish

Output:

File Format Use
dist/index.js CommonJS Node.js require()
dist/index.mjs ESM import / bundlers
dist/index.d.ts TypeScript IDE type checking

Built with tsup. Source in src/, compiled to dist/.


License

MIT

About

light websocket client to connect to the deribit api, including types.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors