Overview

The Provider API offers WebSocket endpoints for real-time data streaming. Each vertical has its own WebSocket path with multiplexed channels supporting multiple providers on a single connection.

Connection URLs

VerticalWebSocket Path
Perpswss://api.perps.studio/ws/v1/perps
Spotwss://api.perps.studio/ws/v1/spot
RWAswss://api.perps.studio/ws/v1/rwas
Predictionswss://api.perps.studio/ws/v1/predictions

Authentication

Authenticate by passing your API key as a query parameter on connect:
wss://api.perps.studio/ws/v1/perps?apiKey=ps_live_abc123def456
If the API key is missing or invalid, the connection will be closed immediately with code 4001.

Subscribe / Unsubscribe

After connecting, send JSON messages to subscribe to channels:

Subscribe

{
  "event": "subscribe",
  "data": {
    "provider": "hyperliquid",
    "channel": "orderbook",
    "params": {
      "symbol": "BTC"
    }
  }
}

Unsubscribe

{
  "event": "unsubscribe",
  "data": {
    "provider": "hyperliquid",
    "channel": "orderbook",
    "params": {
      "symbol": "BTC"
    }
  }
}

Available Channels

Perps Channels

ChannelDescriptionRequired ParamsHL UpstreamAster Upstream
orderbookLevel 2 orderbook updatessymboll2Bookdepth
tradesReal-time trade executionssymboltradesaggTrade
ticker24h ticker statisticssymbolactiveAssetCtxticker
candleCandlestick/kline updatessymbol, intervalcandlekline
pricesAll mid prices (broadcast)noneallMids!ticker@arr

Spot Channels

ChannelDescriptionRequired ParamsHL UpstreamAster Upstream
orderbookLevel 2 orderbook updatessymboll2Bookdepth
tradesReal-time trade executionssymboltradesaggTrade
ticker24h ticker statisticssymbolactiveAssetCtxticker

RWA Channels

ChannelDescriptionRequired Params
orderbookHIP-3 dex orderbook updatessymbol, dex
tradesHIP-3 dex trade executionssymbol, dex
tickerHIP-3 dex ticker statisticssymbol, dex

Prediction Channels

ChannelDescriptionRequired Params
orderbookOutcome token orderbooktokenId
pricesMarket price updatesmarketId

Message Format

All messages from the server follow this format:
{
  "channel": "orderbook",
  "provider": "hyperliquid",
  "data": {
    // Channel-specific payload
  }
}
Error messages:
{
  "error": {
    "code": "UNKNOWN_CHANNEL",
    "message": "Unknown channel: invalid_channel"
  }
}

Full Example

const ws = new WebSocket(
  "wss://api.perps.studio/ws/v1/perps?apiKey=ps_live_abc123def456"
);

ws.onopen = () => {
  // Subscribe to BTC orderbook on Hyperliquid
  ws.send(JSON.stringify({
    event: "subscribe",
    data: {
      provider: "hyperliquid",
      channel: "orderbook",
      params: { symbol: "BTC" },
    },
  }));

  // Subscribe to ETH trades on Aster
  ws.send(JSON.stringify({
    event: "subscribe",
    data: {
      provider: "aster",
      channel: "trades",
      params: { symbol: "ETH" },
    },
  }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.error) {
    console.error("WS Error:", msg.error);
    return;
  }

  switch (msg.channel) {
    case "orderbook":
      handleOrderbookUpdate(msg.data);
      break;
    case "trades":
      handleTradeUpdate(msg.data);
      break;
  }
};

ws.onclose = (event) => {
  console.log(`Disconnected: ${event.code} ${event.reason}`);
  // Implement reconnection logic
};

Reconnection Best Practices

1

Detect Disconnection

Listen for the close event. Normal closure is code 1000. Anything else indicates an unexpected disconnect.
2

Exponential Backoff

Wait 1s, 2s, 4s, 8s, … up to 30s between reconnection attempts. Add random jitter to avoid thundering herd.
3

Re-subscribe

After reconnecting, re-send all your subscription messages. The server does not remember previous subscriptions.
4

Handle Gaps

After reconnection, fetch a REST snapshot (e.g., full orderbook) to ensure your local state is consistent.
WebSocket connections have an idle timeout of 30 seconds. Send a ping frame or subscribe to at least one channel to keep the connection alive.