Real-Time Streaming

WebSocket API

Subscribe to real-time market data, order updates, and account events. Same format as Hyperliquid's WebSocket API.

Connection

Public Endpoint (Market Data)

wss://api.paperx.co/v1/exchanges/hyperliquid/ws

Authenticated Endpoint (User Data)

wss://api.paperx.co/v1/exchanges/hyperliquid/ws/user?token=YOUR_API_KEY

Available Subscriptions

Public Channels (no auth)

allMids

Mid prices for every asset (updates ~500ms)

{"method":"subscribe","subscription":{"type":"allMids"}}

l2Book

Order book depth (requires coin). Updates ~250ms.

{"method":"subscribe","subscription":{"type":"l2Book","coin":"BTC"}}

trades

Real-time public trade feed per coin

{"method":"subscribe","subscription":{"type":"trades","coin":"ETH"}}

candle

OHLCV candles (coin + interval)

{"method":"subscribe","subscription":{"type":"candle","coin":"SOL","interval":"1m"}}

activeAssetCtx

Funding, open interest, mark/oracle price

{"method":"subscribe","subscription":{"type":"activeAssetCtx","coin":"ARB"}}

bbo

Best bid/offer snapshot stream

{"method":"subscribe","subscription":{"type":"bbo","coin":"OP"}}

Private Channels (auth required)

Authenticate with X-API-Key. We support every Hyperliquid channel.

orderUpdates

Auth

Order status changes (open/filled/cancelled)

{"method":"subscribe","subscription":{"type":"orderUpdates"}}

userFills

Auth

Your fills (supports aggregateByTime flag)

{"method":"subscribe","subscription":{"type":"userFills","aggregateByTime":true}}

userEvents

Auth

Combined stream of fills, funding, risk events

{"method":"subscribe","subscription":{"type":"userEvents"}}

userFunding / userFundings

Auth

Funding payments (both Hyperliquid variants supported)

{"method":"subscribe","subscription":{"type":"userFundings"}}

webData2 / webData3

Auth

Clearinghouse state (legacy + current)

{"method":"subscribe","subscription":{"type":"webData3"}}

notification

Auth

System notifications: liquidations, margin, billing

{"method":"subscribe","subscription":{"type":"notification"}}

twapStates

Auth

TWAP order lifecycle + progress

{"method":"subscribe","subscription":{"type":"twapStates"}}

clearinghouseState

Auth

Direct clearinghouse state mirror

{"method":"subscribe","subscription":{"type":"clearinghouseState"}}

openOrders

Auth

Live list of all open orders

{"method":"subscribe","subscription":{"type":"openOrders"}}

userTwapSliceFills

Auth

TWAP slice executions

{"method":"subscribe","subscription":{"type":"userTwapSliceFills"}}

userTwapHistory

Auth

Historical TWAP execution summary

{"method":"subscribe","subscription":{"type":"userTwapHistory"}}

userNonFundingLedgerUpdates

Auth

Ledger events excluding funding

{"method":"subscribe","subscription":{"type":"userNonFundingLedgerUpdates"}}

activeAssetData

Auth

Per-asset context tied to your positions

{"method":"subscribe","subscription":{"type":"activeAssetData","coin":"BTC"}}

JavaScript Example

const ws = new WebSocket('wss://api.paperx.co/v1/exchanges/hyperliquid/ws');

ws.onopen = () => {
  console.log('Connected to PaperExchange WebSocket');
  
  // Subscribe to BTC price updates
  ws.send(JSON.stringify({
    method: 'subscribe',
    subscription: { type: 'allMids' }
  }));
  
  // Subscribe to BTC order book
  ws.send(JSON.stringify({
    method: 'subscribe',
    subscription: { type: 'l2Book', coin: 'BTC' }
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  
  if (data.channel === 'allMids') {
    console.log('Price update:', data.data.mids);
  }
  
  if (data.channel === 'l2Book') {
    console.log('Order book:', data.data);
  }
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = () => {
  console.log('Disconnected from WebSocket');
};

Python Example

import asyncio
import websockets
import json

async def connect():
    uri = "wss://api.paperx.co/v1/exchanges/hyperliquid/ws"
    
    async with websockets.connect(uri) as ws:
        # Subscribe to all mid prices
        await ws.send(json.dumps({
            "method": "subscribe",
            "subscription": {"type": "allMids"}
        }))
        
        # Listen for messages
        async for message in ws:
            data = json.loads(message)
            if data.get("channel") == "allMids":
                print(f"BTC: {data['data']['mids'].get('BTC', 'N/A')}")

asyncio.run(connect())

Message Format

Subscription Response

{
  "channel": "subscriptionResponse",
  "data": {
    "method": "subscribe",
    "subscription": {"type": "allMids"}
  }
}

Price Update (allMids)

{
  "channel": "allMids",
  "data": {
    "mids": {
      "BTC": "98500.50",
      "ETH": "3450.25",
      "SOL": "185.30"
    }
  }
}

Order Book Update (l2Book)

{
  "channel": "l2Book",
  "data": {
    "coin": "BTC",
    "levels": [
      [{"px": "98500.00", "sz": "1.5"}, {"px": "98499.00", "sz": "2.3"}],
      [{"px": "98501.00", "sz": "0.8"}, {"px": "98502.00", "sz": "1.2"}]
    ]
  }
}