Hyperliquid Docs
  • About Hyperliquid
    • Core contributors
  • Onboarding
    • How to start trading
    • How to use the HyperEVM
    • Connect mobile via QR code
    • Export your email wallet
    • Testnet faucet
  • HyperCore
    • Overview
    • Bridge
    • API servers
    • Clearinghouse
    • Oracle
    • Order book
    • Staking
    • Vaults
      • Protocol vaults
      • For vault leaders
      • For vault depositors
    • Multi-sig
  • HyperEVM
    • Tools for HyperEVM builders
  • Hyperliquid Improvement Proposals (HIPs)
    • HIP-1: Native token standard
    • HIP-2: Hyperliquidity
    • HIP-3: Builder-Deployed Perpetuals
    • Frontend checks
  • Trading
    • Perpetual assets
    • Contract specifications
    • Margin tiers
    • Fees
    • Builder codes
    • Order book
    • Order types
    • Take profit and stop loss orders (TP/SL)
    • Margining
    • Liquidations
    • Entry price and pnl
    • Funding
    • Miscellaneous UI
    • Auto-deleveraging
    • Robust price indices
    • Self-trade prevention
    • Portfolio graphs
    • Hyperps
    • Market making
  • Validators
    • Running a validator
    • Delegation program
  • Referrals
    • Staking referral program
  • Points
  • Historical data
  • Risks
  • Bug bounty program
  • Audits
  • Brand kit
  • For developers
    • API
      • Notation
      • Asset IDs
      • Tick and lot size
      • Nonces and API wallets
      • Info endpoint
        • Perpetuals
        • Spot
      • Exchange endpoint
      • Websocket
        • Subscriptions
        • Post requests
        • Timeouts and heartbeats
      • Error responses
      • Signing
      • Rate limits
      • Bridge2
      • Deploying HIP-1 and HIP-2 assets
      • Deploying HIP-3 assets
    • HyperEVM
      • Dual-block architecture
      • Raw HyperEVM block data
      • Interacting with HyperCore
      • HyperCore <> HyperEVM transfers
      • Wrapped HYPE
      • JSON-RPC
    • Nodes
      • L1 Data Schemas
Powered by GitBook
On this page
  • Subscription messages
  • Data formats
  • Data type definitions
  • Examples
  • Unsubscribing from WebSocket feeds
  1. For developers
  2. API
  3. Websocket

Subscriptions

This page describes subscribing to data streams using the WebSocket API.

Subscription messages

To subscribe to specific data feeds, you need to send a subscription message. The subscription message format is as follows:

{
  "method": "subscribe",
  "subscription": { ... }
}

The subscription ack provides a snapshot of previous data for time series data (e.g. user fills). These snapshot messages are tagged with isSnapshot: true and can be ignored if the previous messages were already processed.

The subscription object contains the details of the specific feed you want to subscribe to. Choose from the following subscription types and provide the corresponding properties:

  1. allMids:

    • Subscription message: { "type": "allMids", "dex": "<dex>" }

    • Data format: AllMids

    • The dex field represents the perp dex to source mids from.

    • Note that the dex field is optional. If not provided, then the first perp dex is used. Spot mids are only included with the first perp dex.

  2. notification:

    • Subscription message: { "type": "notification", "user": "<address>" }

    • Data format: Notification

  3. webData2

    • Subscription message: { "type": "webData2", "user": "<address>" }

    • Data format: WebData2

  4. candle:

    • Subscription message: { "type": "candle", "coin": "<coin_symbol>", "interval": "<candle_interval>" }

    • Data format: Candle[]

  5. l2Book:

    • Subscription message: { "type": "l2Book", "coin": "<coin_symbol>" }

    • Optional parameters: nSigFigs: int, mantissa: int

    • Data format: WsBook

  6. trades:

    • Subscription message: { "type": "trades", "coin": "<coin_symbol>" }

    • Data format: WsTrade[]

  7. orderUpdates:

    • Subscription message: { "type": "orderUpdates", "user": "<address>" }

    • Data format: WsOrder[]

  8. userEvents:

    • Subscription message: { "type": "userEvents", "user": "<address>" }

    • Data format: WsUserEvent

  9. userFills:

    • Subscription message: { "type": "userFills", "user": "<address>" }

    • Optional parameter: aggregateByTime: bool

    • Data format: WsUserFills

  10. userFundings:

    • Subscription message: { "type": "userFundings", "user": "<address>" }

    • Data format: WsUserFundings

  11. userNonFundingLedgerUpdates:

    • Subscription message: { "type": "userNonFundingLedgerUpdates", "user": "<address>" }

    • Data format: WsUserNonFundingLedgerUpdates

  12. activeAssetCtx:

    • Subscription message: { "type": "activeAssetCtx", "coin": "coin_symbol>" }

    • Data format: WsActiveAssetCtx or WsActiveSpotAssetCtx

  13. activeAssetData: (only supports Perps)

    • Subscription message: { "type": "activeAssetData", "user": "<address>", "coin": "coin_symbol>" }

    • Data format: WsActiveAssetData

  14. userTwapSliceFills:

    • Subscription message: { "type": "userTwapSliceFills", "user": "<address>" }

    • Data format: WsUserTwapSliceFills

  15. userTwapHistory:

    • Subscription message: { "type": "userTwapHistory", "user": "<address>" }

    • Data format: WsUserTwapHistory

  16. bbo :

    • Subscription message: { "type": "bbo", "coin": "<coin>" }

    • Data format: WsBbo

Data formats

The server will respond to successful subscriptions with a message containing the channel property set to "subscriptionResponse", along with the data field providing the original subscription. The server will then start sending messages with the channel property set to the corresponding subscription type e.g. "allMids" and the data field providing the subscribed data.

The data field format depends on the subscription type:

  • AllMids: All mid prices.

    • Format: AllMids { mids: Record<string, string> }

  • Notification: A notification message.

    • Format: Notification { notification: string }

  • WebData2: Aggregate information about a user, used primarily for the frontend.

    • Format: WebData2

  • WsTrade[]: An array of trade updates.

    • Format: WsTrade[]

  • WsBook: Order book snapshot updates.

    • Format: WsBook { coin: string; levels: [Array<WsLevel>, Array<WsLevel>]; time: number; }

  • WsOrder: User order updates.

    • Format: WsOrder[]

  • WsUserEvent: User events that are not order updates

    • Format: WsUserEvent { "fills": [WsFill] | "funding": WsUserFunding | "liquidation": WsLiquidation | "nonUserCancel": [WsNonUserCancel] }

  • WsUserFills : Fills snapshot followed by streaming fills

  • WsUserFundings : Funding payments snapshot followed by funding payments on the hour

  • WsUserNonFundingLedgerUpdates: Ledger updates not including funding payments: withdrawals, deposits, transfers, and liquidations

  • WsBbo : Bbo updates that are sent only if the bbo changes on a block

For the streaming user endpoints such as WsUserFills,WsUserFundings the first message has isSnapshot: true and the following streaming updates have isSnapshot: false.

Data type definitions

Here are the definitions of the data types used in the WebSocket API:

interface WsTrade {
  coin: string;
  side: string;
  px: string;
  sz: string;
  hash: string;
  time: number;
  // tid is 50-bit hash of (buyer_oid, seller_oid). 
  // For a globally unique trade id, use (block_time, coin, tid)
  tid: number;  
  users: [string, string] // [buyer, seller]
}

// Snapshot feed, pushed on each block that is at least 0.5 since last push
interface WsBook {
  coin: string;
  levels: [Array<WsLevel>, Array<WsLevel>];
  time: number;
}

interface WsBbo {
  coin: string;
  time: number;
  bbo: [WsLevel | null, WsLevel | null];
}

interface WsLevel {
  px: string; // price
  sz: string; // size
  n: number; // number of orders
}

interface Notification {
  notification: string;
}

interface AllMids {
  mids: Record<string, string>;
}

interface Candle {
  t: number; // open millis
  T: number; // close millis
  s: string; // coin
  i: string; // interval
  o: number; // open price
  c: number; // close price
  h: number; // high price
  l: number; // low price
  v: number; // volume (base unit)
  n: number; // number of trades
}

type WsUserEvent = {"fills": WsFill[]} | {"funding": WsUserFunding} | {"liquidation": WsLiquidation} | {"nonUserCancel" :WsNonUserCancel[]};

interface WsUserFills {
  isSnapshot?: boolean;
  user: string;
  fills: Array<WsFill>;
}

interface WsFill {
  coin: string;
  px: string; // price
  sz: string; // size
  side: string;
  time: number;
  startPosition: string;
  dir: string; // used for frontend display
  closedPnl: string;
  hash: string; // L1 transaction hash
  oid: number; // order id
  crossed: boolean; // whether order crossed the spread (was taker)
  fee: string; // negative means rebate
  tid: number; // unique trade id
  liquidation?: FillLiquidation;
  feeToken: string; // the token the fee was paid in
  builderFee?: string; // amount paid to builder, also included in fee
}

interface FillLiquidation {
  liquidatedUser?: string;
  markPx: number;
  method: "market" | "backstop";
}

interface WsUserFunding {
  time: number;
  coin: string;
  usdc: string;
  szi: string;
  fundingRate: string;
}

interface WsLiquidation {
  lid: number;
  liquidator: string;
  liquidated_user: string;
  liquidated_ntl_pos: string;
  liquidated_account_value: string;
}

interface WsNonUserCancel {
  coin: String;
  oid: number;
}

interface WsOrder {
  order: WsBasicOrder;
  status: string; // Possible values: open, filled, canceled, triggered, rejected, marginCanceled
  statusTimestamp: number;
}

interface WsBasicOrder {
  coin: string;
  side: string;
  limitPx: string;
  sz: string;
  oid: number;
  timestamp: number;
  origSz: string;
  cloid: string | undefined;
}

interface WsActiveAssetCtx {
  coin: string;
  ctx: PerpsAssetCtx;
}

interface WsActiveSpotAssetCtx {
  coin: string;
  ctx: SpotAssetCtx;
}

type SharedAssetCtx = {
  dayNtlVlm: number;
  prevDayPx: number;
  markPx: number;
  midPx?: number;
};

type PerpsAssetCtx = SharedAssetCtx & {
  funding: number;
  openInterest: number;
  oraclePx: number;
};

type SpotAssetCtx = SharedAssetCtx & {
  circulatingSupply: number;
};

interface WsActiveAssetData {
  user: string;
  coin: string;
  leverage: Leverage;
  maxTradeSzs: [number, number];
  availableToTrade: [number, number];
}

interface WsTwapSliceFill {
  fill: WsFill;
  twapId: number;
}

interface WsUserTwapSliceFills {
  isSnapshot?: boolean;
  user: string;
  twapSliceFills: Array<WsTwapSliceFill>;
}

interface TwapState {
  coin: string;
  user: string;
  side: string;
  sz: number;
  executedSz: number;
  executedNtl: number;
  minutes: number;
  reduceOnly: boolean;
  randomize: boolean;
  timestamp: number;
}

type TwapStatus = "activated" | "terminated" | "finished" | "error";
interface WsTwapHistory {
  state: TwapState;
  status: {
    status: TwapStatus;
    description: string;
  };
  time: number;
}

interface WsUserTwapHistory {
  isSnapshot?: boolean;
  user: string;
  history: Array<WsTwapHistory>;
}
WsUserNonFundingLedgerUpdates
interface WsUserNonFundingLedgerUpdate {
  time: number;
  hash: string;
  delta: WsLedgerUpdate;
}

type WsLedgerUpdate = 
  | WsDeposit
  | WsWithdraw 
  | WsInternalTransfer 
  | WsSubAccountTransfer 
  | WsLedgerLiquidation 
  | WsVaultDelta 
  | WsVaultWithdrawal
  | WsVaultLeaderCommission
  | WsSpotTransfer
  | WsAccountClassTransfer
  | WsSpotGenesis
  | WsRewardsClaim;
  
interface WsDeposit {
  type: "deposit";
  usdc: number;
}

interface WsWithdraw {
  type: "withdraw";
  usdc: number;
  nonce: number;
  fee: number;
}

interface WsInternalTransfer {
  type: "internalTransfer";
  usdc: number;
  user: string;
  destination: string;
  fee: number;
}

interface WsSubAccountTransfer {
  type: "subAccountTransfer";
  usdc: number;
  user: string;
  destination: string;
}

interface WsLedgerLiquidation {
  type: "liquidation";
  // NOTE: for isolated positions this is the isolated account value
  accountValue: number;
  leverageType: "Cross" | "Isolated";
  liquidatedPositions: Array<LiquidatedPosition>;
}

interface LiquidatedPosition {
  coin: string;
  szi: number;
}

interface WsVaultDelta {
  type: "vaultCreate" | "vaultDeposit" | "vaultDistribution";
  vault: string;
  usdc: number;
}

interface WsVaultWithdrawal {
  type: "vaultWithdraw";
  vault: string;
  user: string;
  requestedUsd: number;
  commission: number;
  closingCost: number;
  basis: number;
  netWithdrawnUsd: number;
}

interface WsVaultLeaderCommission {
  type: "vaultLeaderCommission";
  user: string;
  usdc: number;
}

interface WsSpotTransfer = {
  type: "spotTransfer";
  token: string;
  amount: number;
  usdcValue: number;
  user: string;
  destination: string;
  fee: number;
}

interface WsAccountClassTransfer = {
  type: "accountClassTransfer";
  usdc: number;
  toPerp: boolean;
}

interface WsSpotGenesis = {
  type: "spotGenesis";
  token: string;
  amount: number;
}

interface WsRewardsClaim = {
  type: "rewardsClaim";
  amount: number;
}

Please note that the above data types are in TypeScript format, and their usage corresponds to the respective subscription types.

Examples

Here are a few examples of subscribing to different feeds using the subscription messages:

  1. Subscribe to all mid prices:

    { "method": "subscribe", "subscription": { "type": "allMids" } }
  2. Subscribe to notifications for a specific user:

    { "method": "subscribe", "subscription": { "type": "notification", "user": "<address>" } }
  3. Subscribe to web data for a specific user:

    { "method": "subscribe", "subscription": { "type": "webData", "user": "<address>" } }
  4. Subscribe to candle updates for a specific coin and interval:

    { "method": "subscribe", "subscription": { "type": "candle", "coin": "<coin_symbol>", "interval": "<candle_interval>" } }
  5. Subscribe to order book updates for a specific coin:

    { "method": "subscribe", "subscription": { "type": "l2Book", "coin": "<coin_symbol>" } }
  6. Subscribe to trades for a specific coin:

    { "method": "subscribe", "subscription": { "type": "trades", "coin": "<coin_symbol>" } }

Unsubscribing from WebSocket feeds

To unsubscribe from a specific data feed on the Hyperliquid WebSocket API, you need to send an unsubscribe message with the following format:

{
  "method": "unsubscribe",
  "subscription": { ... }
}

The subscription object should match the original subscription message that was sent when subscribing to the feed. This allows the server to identify the specific feed you want to unsubscribe from. By sending this unsubscribe message, you inform the server to stop sending further updates for the specified feed.

Please note that unsubscribing from a specific feed does not affect other subscriptions you may have active at that time. To unsubscribe from multiple feeds, you can send multiple unsubscribe messages, each with the appropriate subscription details.

PreviousWebsocketNextPost requests

Last updated 10 days ago