WebSocket API

One socket for live subscriptions, replay, and continuity signals.

Endpoint
wss://api.0xarchive.io/ws
Modes
Live and replay
Commands
Subscribe, replay, keep-alive
Health
Status on /status

Connection

Connect once, keep the heartbeat alive, then issue subscribe or replay commands.

Open the socket

Connect to wss://api.0xarchive.io/ws with your API key.

JavaScriptJavaScript
const ws = new WebSocket(
"wss://api.0xarchive.io/ws?apiKey=0xa_your_api_key"
);
ws.onopen = () => {
console.log("Connected to 0xArchive WebSocket");
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Received:", data);
};
PythonPython
import asyncio
import websockets
import json
async def connect():
uri = "wss://api.0xarchive.io/ws?apiKey=0xa_your_api_key"
async with websockets.connect(uri) as ws:
print("Connected to 0xArchive WebSocket")
async for message in ws:
data = json.loads(message)
print("Received:", data)
asyncio.run(connect())

Keep-alive

The server sends ping frames every 30 seconds. Clients that do not answer within 60 seconds are disconnected.

JavaScript
// Send a ping to keep connection alive
ws.send(JSON.stringify({ op: "ping" }));
// Server responds with:
// {"type": "pong"}

Command model

The same socket handles subscribe, unsubscribe, replay, and keep-alive commands.

Real-time Subscriptions

subscribe

Subscribe to a real-time channel

Params: channel, symbol

Send

{
"op": "subscribe",
"channel": "orderbook",
"symbol": "BTC"
}

Receive

{
"type": "subscribed",
"channel": "orderbook",
"symbol": "BTC"
}
unsubscribe

Unsubscribe from a channel

Params: channel, symbol

Send

{
"op": "unsubscribe",
"channel": "orderbook",
"symbol": "BTC"
}

Receive

{
"type": "unsubscribed",
"channel": "orderbook",
"symbol": "BTC"
}

Historical Replay

replay

Start historical replay. Use "channel" for single or "channels" (array) for multi-channel synchronized replay. All channels must be from the same exchange. Use interval for candles (1m-1w). Use granularity for lighter_orderbook.

Params: channel|channels, symbol, start, end, speed, [interval], [granularity]

Send

{
"op": "replay",
"channel": "trades",
"symbol": "BTC",
"start": 1704067200000,
"end": 1704153600000,
"speed": 10
}

Receive

{
"type": "replay_started",
"replay_id": "rpl_abc123",
"channel": "trades",
"symbol": "BTC",
"speed": 10
}
replay.pause

Pause current replay

Params: -

Send

{
"op": "replay.pause"
}

Receive

{
"type": "replay_paused",
"replay_id": "rpl_abc123"
}
replay.resume

Resume paused replay

Params: -

Send

{
"op": "replay.resume"
}

Receive

{
"type": "replay_resumed",
"replay_id": "rpl_abc123"
}
replay.seek

Seek to specific timestamp

Params: timestamp

Send

{
"op": "replay.seek",
"timestamp": 1704100000000
}

Receive

{
"type": "replay_seeked",
"replay_id": "rpl_abc123",
"timestamp": 1704100000000
}
replay.stop

Stop current replay

Params: -

Send

{
"op": "replay.stop"
}

Receive

{
"type": "replay_stopped",
"replay_id": "rpl_abc123"
}

Utility

ping

Send a ping to keep connection alive (server responds with pong)

Params: -

Send

{
"op": "ping"
}

Receive

{
"type": "pong",
"timestamp": "2026-01-01T12:00:00Z"
}

Channels

Channel inventory by venue, plus live vs replay availability and depth detail.

Hyperliquid

Historical data from April 2023. Symbols: BTC, ETH, SOL, etc.

Channel

orderbook

Description

High-frequency L2 order book snapshots (spacing varies by market activity and query window)

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "orderbook",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"bids": [
{
"px": "42150.50",
"sz": "2.5",
"n": 5
}
],
"asks": [
{
"px": "42151.00",
"sz": "1.8",
"n": 3
}
],
"mid_price": "42150.75"
}
}

Channel

trades

Description

Trade/fill updates (pre-March 2025 fills are taker-only)

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "trades",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"side": "B",
"price": "42150.50",
"size": "0.25",
"trade_id": 12345678
}
]
}

Channel

candles

Description

OHLCV candles. Interval param: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w

Mode

Historical only (March 2025+)

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "candles",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"interval": "1h",
"data": {
"open": "42100.00",
"high": "42200.00",
"low": "42050.00",
"close": "42180.00",
"volume": "125.5"
}
}

Channel

open_interest

Description

Open interest snapshots

Mode

Real-time & Historical (May 2023+)

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "open_interest",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"open_interest": "12500.5",
"mark_price": "42150.75"
}
}

Channel

funding

Description

Funding rate snapshots

Mode

Real-time & Historical (May 2023+)

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "funding",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"funding_rate": "0.0001",
"premium": "0.00005"
}
}

Channel

liquidations

Description

Fills with is_liquidation: true (filtered subset of trades). Real-time emits the trades wire format with is_liquidation:true; historical replay emits the ClickHouse liquidations row shape (camelCase fields, liquidatedUser, tradeId).

Mode

Real-time & Historical (December 2025+)

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "liquidations",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"side": "A",
"price": "42150.50",
"size": "1.5",
"trade_id": 12345678,
"is_liquidation": true,
"direction": "Close Long",
"closed_pnl": -118.4
}
]
}

Channel

ticker

Description

Price and 24h volume

Mode

Real-time only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "ticker",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"price": "42150.75",
"volume_24h": "1250000000"
}
}

Channel

all_tickers

Description

All market tickers at once (no symbol param needed)

Mode

Real-time only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "all_tickers",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"symbol": "BTC",
"price": "42150.75",
"volume_24h": "1250000000"
}
]
}

Channel

l4_diffs

Description

L4 orderbook diffs with user wallet attribution. Batched by block (~100ms).

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "l4_diffs",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"side": "B",
"price": "42150.50",
"size_delta": "0.5"
}
]
}

Channel

l4_orders

Description

Order lifecycle events (new, partial fill, filled, cancelled) with wallet attribution. Batched by block.

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "l4_orders",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"status": "filled",
"side": "B",
"price": "42150.50",
"size": "1.2"
}
]
}

HIP-3

Builder-deployed perpetuals on Hyperliquid. Historical trades, candles, orderbook, OI/funding, and liquidations begin in February 2026. Symbols: km:US500, hyna:BTC, etc.

Channel

hip3_orderbook

Description

L2 order book snapshots

Mode

Real-time & Historical

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "hip3_orderbook",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"bids": [
{
"px": "42150.50",
"sz": "2.5",
"n": 5
}
],
"asks": [
{
"px": "42151.00",
"sz": "1.8",
"n": 3
}
],
"mid_price": "42150.75"
}
}

Channel

hip3_trades

Description

Trade/fill updates

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "hip3_trades",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"side": "B",
"price": "42150.50",
"size": "0.25",
"trade_id": 12345678
}
]
}

Channel

hip3_candles

Description

OHLCV candles. Interval param: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w

Mode

Historical only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "hip3_candles",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"interval": "1h",
"data": {
"open": "42100.00",
"high": "42200.00",
"low": "42050.00",
"close": "42180.00",
"volume": "125.5"
}
}

Channel

hip3_open_interest

Description

Open interest snapshots

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "hip3_open_interest",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"open_interest": "12500.5",
"mark_price": "42150.75"
}
}

Channel

hip3_funding

Description

Funding rate snapshots

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "hip3_funding",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"funding_rate": "0.0001",
"premium": "0.00005"
}
}

Channel

hip3_liquidations

Description

Fills with is_liquidation: true (filtered subset of hip3_trades). Real-time emits the hip3_trades wire format with is_liquidation:true; historical replay emits the ClickHouse hip3_fills-derived shape (camelCase fields, liquidatedUser, tradeId).

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "hip3_liquidations",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"side": "A",
"price": "42150.50",
"size": "1.5",
"trade_id": 12345678,
"is_liquidation": true,
"direction": "Close Long",
"closed_pnl": -118.4
}
]
}

Channel

hip3_l4_diffs

Description

L4 orderbook diffs with user wallet attribution. Batched by block (~100ms).

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "hip3_l4_diffs",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"side": "B",
"price": "42150.50",
"size_delta": "0.5"
}
]
}

Channel

hip3_l4_orders

Description

Order lifecycle events with wallet attribution. Batched by block.

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "hip3_l4_orders",
"symbol": "km:US500",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"status": "filled",
"side": "B",
"price": "42150.50",
"size": "1.2"
}
]
}

Hyperliquid Spot

Hyperliquid spot pairs. 294 pairs live from May 2026. Symbols use dash form (PURR-USDC, HYPE-USDC, HFUN-USDC); the bare token (e.g. HFUN) is also accepted. No funding, OI, or liquidations (perp-only constructs).

Channel

spot_orderbook

Description

L2 order book snapshots (~1.9/sec) for spot pairs

Mode

Real-time only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "spot_orderbook",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"bids": [
{
"px": "42150.50",
"sz": "2.5",
"n": 5
}
],
"asks": [
{
"px": "42151.00",
"sz": "1.8",
"n": 3
}
],
"mid_price": "42150.75"
}
}

Channel

spot_trades

Description

Spot trade/fill updates

Mode

Real-time only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "spot_trades",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"side": "B",
"price": "42150.50",
"size": "0.25",
"trade_id": 12345678
}
]
}

Channel

spot_l4_diffs

Description

L4 orderbook diffs with wallet attribution. Batched ~250ms (per-block, sourced from the Singapore prod node).

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "spot_l4_diffs",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"side": "B",
"price": "42150.50",
"size_delta": "0.5"
}
]
}

Channel

spot_l4_orders

Description

Order lifecycle events (open, filled, canceled, selfTradeCanceled, badAloPxRejected, insufficientSpotBalanceRejected, iocCancelRejected, minTradeNtlRejected) with wallet attribution.

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "spot_l4_orders",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"status": "filled",
"side": "B",
"price": "42150.50",
"size": "1.2"
}
]
}

Channel

spot_twap

Description

TWAP order lifecycle for spot (activated, finished, error, terminated). Joinable by twap_id.

Mode

Real-time only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "spot_twap",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"status": "ok"
}
}

HIP-4

Binary outcome markets on Hyperliquid L1. Per-side coins are #-prefixed (e.g. #0 for Yes, #1 for No). No funding, no liquidations, no candles by design (build candles client-side from hip4_trades). Live data from May 2026.

Channel

hip4_orderbook

Description

L2 order book snapshots per outcome side

Mode

Real-time & Historical

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "hip4_orderbook",
"symbol": "#0",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"bids": [
{
"px": "42150.50",
"sz": "2.5",
"n": 5
}
],
"asks": [
{
"px": "42151.00",
"sz": "1.8",
"n": 3
}
],
"mid_price": "42150.75"
}
}

Channel

hip4_trades

Description

Per-side fill/trade updates

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "hip4_trades",
"symbol": "#0",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"side": "B",
"price": "42150.50",
"size": "0.25",
"trade_id": 12345678
}
]
}

Channel

hip4_open_interest

Description

Per-side OI snapshots (upstream channel name: activeSpotAssetCtx; server translates)

Mode

Real-time & Historical

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "hip4_open_interest",
"symbol": "#0",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"open_interest": "12500.5",
"mark_price": "42150.75"
}
}

Channel

hip4_l4_diffs

Description

L4 orderbook diffs with user wallet attribution. Initial l4_snapshot then l4_batch event stream. Symbol required.

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "hip4_l4_diffs",
"symbol": "#0",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"side": "B",
"price": "42150.50",
"size_delta": "0.5"
}
]
}

Channel

hip4_l4_orders

Description

Order lifecycle events with wallet attribution. Symbol required.

Mode

Real-time only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "hip4_l4_orders",
"symbol": "#0",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"order_id": "0xabc",
"user_address": "0x1234...abcd",
"status": "filled",
"side": "B",
"price": "42150.50",
"size": "1.2"
}
]
}

Lighter.xyz

Data from August 2025 for fills, candles, open interest, and funding; January 2026 for L2 orderbook; March 2026 for L3 orderbook. Symbols: BTC, ETH, SOL, etc.

Channel

lighter_orderbook

Description

Full-depth order book. Finer L2 granularity is tier-gated, and tick reconstruction is Enterprise-only.

Mode

Historical only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "lighter_orderbook",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"bids": [
{
"px": "42150.50",
"sz": "2.5",
"n": 5
}
],
"asks": [
{
"px": "42151.00",
"sz": "1.8",
"n": 3
}
],
"mid_price": "42150.75"
}
}

Channel

lighter_trades

Description

Trade/fill updates

Mode

Historical only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "lighter_trades",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": [
{
"side": "B",
"price": "42150.50",
"size": "0.25",
"trade_id": 12345678
}
]
}

Channel

lighter_candles

Description

OHLCV candles. Interval param: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w

Mode

Historical only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "lighter_candles",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"interval": "1h",
"data": {
"open": "42100.00",
"high": "42200.00",
"low": "42050.00",
"close": "42180.00",
"volume": "125.5"
}
}

Channel

lighter_open_interest

Description

Open interest snapshots

Mode

Historical only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "lighter_open_interest",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"open_interest": "12500.5",
"mark_price": "42150.75"
}
}

Channel

lighter_funding

Description

Funding rate snapshots

Mode

Historical only

Tier

Build+

Message sample

{
"type": "market_data",
"channel": "lighter_funding",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"funding_rate": "0.0001",
"premium": "0.00005"
}
}

Channel

lighter_l3_orderbook

Description

L3 order-level orderbook snapshots with individual order IDs and sizes

Mode

Historical only

Tier

Pro+

Message sample

{
"type": "market_data",
"channel": "lighter_l3_orderbook",
"symbol": "BTC",
"timestamp": "2026-01-01T12:00:00Z",
"data": {
"bids": [
{
"px": "42150.50",
"sz": "2.5",
"n": 5
}
],
"asks": [
{
"px": "42151.00",
"sz": "1.8",
"n": 3
}
],
"mid_price": "42150.75"
}
}

Real-time subscriptions

Subscribe to proxied venue streams.

JavaScript
// Subscribe to real-time order book updates
ws.send(JSON.stringify({
op: "subscribe",
channel: "orderbook",
symbol: "BTC"
}));
// Subscribe to real-time trades
ws.send(JSON.stringify({
op: "subscribe",
channel: "trades",
symbol: "ETH"
}));
// Subscribe to L4 orderbook diffs (Pro+, real-time only)
// Messages are batched by block and include user wallet addresses
ws.send(JSON.stringify({
op: "subscribe",
channel: "l4_diffs",
symbol: "BTC"
}));
// Subscribe to L4 order lifecycle events (Pro+, real-time only)
// Streams order state changes (new, partial fill, filled, cancelled)
ws.send(JSON.stringify({
op: "subscribe",
channel: "l4_orders",
symbol: "ETH"
}));
// Subscribe to HIP-3 L4 channels
ws.send(JSON.stringify({
op: "subscribe",
channel: "hip3_l4_diffs",
symbol: "km:US500"
}));
ws.send(JSON.stringify({
op: "subscribe",
channel: "hip3_l4_orders",
symbol: "km:US500"
}));
// Subscribe to HIP-4 outcome-market channels
// HIP-4 coins are #-prefixed: #0 = Yes side, #1 = No side
ws.send(JSON.stringify({
op: "subscribe",
channel: "hip4_orderbook",
symbol: "#0"
}));
ws.send(JSON.stringify({
op: "subscribe",
channel: "hip4_l4_diffs",
symbol: "#0"
}));
// Unsubscribe
ws.send(JSON.stringify({
op: "unsubscribe",
channel: "orderbook",
symbol: "BTC"
}));

L4 orderbook streaming

L4 starts with a snapshot and follows with diff batches.

Python
import websockets, json, asyncio
async def stream_l4():
uri = "wss://api.0xarchive.io/ws?apiKey=YOUR_KEY"
async with websockets.connect(uri, max_size=20_000_000) as ws:
# Subscribe to L4 diffs (works for l4_diffs, hip3_l4_diffs, or hip4_l4_diffs)
await ws.send(json.dumps({
"op": "subscribe",
"channel": "l4_diffs",
"symbol": "BTC"
}))
book = {"bids": {}, "asks": {}}
snapshot_ts = None
async for msg in ws:
data = json.loads(msg)
if data["type"] == "l4_snapshot":
# Full book delivered first (every order including triggers)
snapshot_ts = data["timestamp"]
for order in data["data"]["bids"]:
book["bids"][order["oid"]] = order
for order in data["data"]["asks"]:
book["asks"][order["oid"]] = order
print(f"Snapshot: {len(book['bids'])} bids, {len(book['asks'])} asks")
elif data["type"] == "l4_batch" and snapshot_ts is not None:
# Apply diffs to maintain the book
for diff in data["data"]:
if diff["ts"] <= snapshot_ts:
continue
side = "bids" if diff["side"] == "B" else "asks"
oid = diff["oid"]
if diff["dt"] == "new":
book[side][oid] = {
"oid": oid, "side": diff["side"],
"price": diff["px"], "size": diff["sz"],
"user_address": diff["user"]
}
elif diff["dt"] == "update":
if oid in book[side]:
book[side][oid]["size"] = diff["sz"]
elif diff["dt"] == "remove":
book[side].pop(oid, None)
asyncio.run(stream_l4())

Replay & Backtesting

Replay historical data over the same socket, then feed it through your live event loop for backtests.

Historical replay

Replay historical data with original timing and adjustable speed.

JavaScript
// Start historical replay at 10x speed (Hyperliquid)
ws.send(JSON.stringify({
op: "replay",
channel: "orderbook",
symbol: "BTC",
start: 1681516800000, // Unix timestamp in ms
end: 1681603200000,
speed: 10 // 10x playback speed
}));
// Start Lighter.xyz orderbook replay with granularity
ws.send(JSON.stringify({
op: "replay",
channel: "lighter_orderbook",
symbol: "BTC",
start: 1706140800000,
end: 1706227200000,
speed: 10,
granularity: "10s" // Options: checkpoint, 30s, 10s, 1s, tick
}));
// Replay candles with specific interval
ws.send(JSON.stringify({
op: "replay",
channel: "candles",
symbol: "ETH",
start: 1681516800000,
end: 1681603200000,
speed: 10,
interval: "1h" // Options: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w
}));
// Replay OI/funding data
ws.send(JSON.stringify({
op: "replay",
channel: "open_interest",
symbol: "BTC",
start: 1684540800000,
end: 1684627200000,
speed: 10
}));
// Multi-channel synchronized replay (all channels must be same exchange)
// Data is interleaved in timestamp order across channels
ws.send(JSON.stringify({
op: "replay",
channels: ["orderbook", "trades", "funding"], // Use "channels" (plural) for multi-channel
symbol: "BTC",
start: 1681516800000,
end: 1681603200000,
speed: 10
}));
// Multi-channel Lighter replay
ws.send(JSON.stringify({
op: "replay",
channels: ["lighter_orderbook", "lighter_trades", "lighter_funding"],
symbol: "ETH",
start: 1706140800000,
end: 1706227200000,
speed: 10,
granularity: "10s" // Applies to lighter_orderbook channel
}));
// Multi-channel replay sends "replay_snapshot" messages before the timeline
// starts, providing initial state for each channel:
// {"type": "replay_snapshot", "channel": "orderbook", "coin": "BTC", "symbol": "BTC", "timestamp": ..., "data": {...}}
// {"type": "replay_snapshot", "channel": "funding", "coin": "BTC", "symbol": "BTC", "timestamp": ..., "data": {...}}
// Then interleaved historical_data messages follow in timestamp order
// Pause replay
ws.send(JSON.stringify({ op: "replay.pause" }));
// Resume replay
ws.send(JSON.stringify({ op: "replay.resume" }));
// Seek to specific timestamp
ws.send(JSON.stringify({
op: "replay.seek",
timestamp: 1681550000000
}));
// Stop replay
ws.send(JSON.stringify({ op: "replay.stop" }));

Gap detection

gap_detected marks missing windows during replay.

JavaScript
// Gap detection during replay
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'gap_detected') {
console.log(`Gap in ${msg.channel}/${msg.symbol}:`);
console.log(` From: ${new Date(msg.gap_start).toISOString()}`);
console.log(` To: ${new Date(msg.gap_end).toISOString()}`);
console.log(` Duration: ${msg.duration_minutes} minutes`);
}
// Handle other message types...
if (msg.type === 'historical_data') {
// Process data
}
};

Gap thresholds

  • - orderbook, candles, liquidations: 2 minutes
  • - trades: 60 minutes

Backtesting

Feed synchronized historical market data through the same event loop you use for live handling.

Python
import asyncio, json, websockets
async def backtest_strategy():
uri = "wss://api.0xarchive.io/ws?apiKey=0xa_your_api_key"
async with websockets.connect(uri) as ws:
# Replay orderbook + trades together at 50x speed
await ws.send(json.dumps({
"op": "replay",
"channels": ["orderbook", "trades"],
"symbol": "BTC",
"start": 1704067200000, # Jan 1 2024
"end": 1704153600000, # Jan 2 2024
"speed": 50
}))
orderbook = None
trades = []
async for message in ws:
msg = json.loads(message)
if msg["type"] == "replay_snapshot":
# Initial state before timeline starts
if msg["channel"] == "orderbook":
orderbook = msg["data"]
elif msg["type"] == "historical_data":
if msg["channel"] == "orderbook":
orderbook = msg["data"]
# Run strategy on each orderbook update
signal = my_strategy(orderbook, trades)
if signal:
execute_paper_trade(signal, msg["timestamp"])
elif msg["channel"] == "trades":
trades.append(msg["data"])
elif msg["type"] == "gap_detected":
print(f"Data gap: {msg['duration_minutes']}min at {msg['gap_start']}")
elif msg["type"] == "replay_completed":
print(f"Backtest done. {msg['snapshots_sent']} data points processed.")
break
asyncio.run(backtest_strategy())

Tips

  • Use multi-channel replay (orderbook + trades + funding) to get a complete market picture with synchronized timestamps.
  • Begin at low speed (1-10x) to verify your strategy logic, then increase speed for full backtests.
  • Handle replay_snapshot messages first to build initial state before the timeline begins.
  • Monitor gap_detected messages: gaps in orderbook data (>2 min) or trades (>60 min) indicate periods where your backtest may be unreliable.
  • Replay is limited to 1 task per connection. Open multiple connections to backtest different symbols in parallel.
  • For bulk analysis over long periods, consider the REST API with cursor pagination instead of replay (no speed limit, lower credit cost).

Limits

Subscription caps, replay limits, idle timeouts, and range constraints.

WebSocket limits by tier

TierSymbolsHistorical DepthMax Range/RequestMax SubscriptionsMax Replay Speed
FreeNo WebSocket access----
BuildAll365 daysUnlimited2550x
ProAllUnlimitedUnlimited100100x
EnterpriseAllUnlimitedUnlimited2001000x

WebSocket access is available on Build tier and above. See pricing for the current tier posture.

Connection constraints

ConstraintLimitDescription
Message metering1 credit/msgEach WebSocket message counts as 1 API credit toward monthly quota
Idle timeout (with subscriptions)60 secondsSend ping every 30s to keep alive
Idle timeout (no subscriptions)5 minutesConnections without subscriptions timeout after 5 minutes
Subscription rate limit10/secondMax subscribe/unsubscribe operations per second
Concurrent replay tasks1One replay per connection at a time (multi-channel counts as one replay)
Multi-channel constraintSame exchangeAll channels in a multi-channel replay must be from the same exchange (e.g., all Hyperliquid or all Lighter; HIP-3 and HIP-4 are separate exchanges and cannot be mixed)
Per-request range limitTier-basedFree: 30 days max, Build/Pro/Enterprise: Unlimited
Data availabilityVaries by channelHyperliquid: April 2023+ (orderbook snapshot spacing varies by market activity and query window; OI/funding: May 2023+, candles: March 2025+, liquidations: December 2025+, L4: March 2026+). Lighter: August 2025+ (trades, candles, OI, funding), January 2026+ (L2 orderbook), March 2026+ (L3 orderbook). HIP-3: February 2026+ for trades, candles, orderbook, OI/funding, and liquidations; L4 March 2026+. HIP-4: May 2026+ for L2/L4 orderbook, trades, OI, and order lifecycle (no funding, no liquidations, no candles by design).