> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xarchive.io/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket Replay

> Replay historical 0xArchive streams for backtesting, reconstruction, and incident review.

Replay sends historical data over the WebSocket at a controlled speed. Use it when order and timing matter more than a single REST response.

## Single-Channel Replay

```javascript theme={"theme":"github-dark"}
ws.send(JSON.stringify({
  op: "replay",
  channel: "orderbook",
  symbol: "BTC",
  start: 1681516800000,
  end: 1681603200000,
  speed: 10
}));
```

## Multi-Channel Replay

```javascript theme={"theme":"github-dark"}
ws.send(JSON.stringify({
  op: "replay",
  channels: ["orderbook", "trades", "funding"],
  symbol: "BTC",
  start: 1681516800000,
  end: 1681603200000,
  speed: 10
}));
```

Multi-channel replay should keep all channels inside the same venue family. Do not combine Hyperliquid core channels with Lighter, HIP-3, HIP-4, or Spot channels in one replay command.

## Controls

<CardGroup cols={2}>
  <Card title="Pause" icon="pause">
    `{"op":"replay.pause"}`
  </Card>

  <Card title="Resume" icon="play">
    `{"op":"replay.resume"}`
  </Card>

  <Card title="Seek" icon="skip-forward">
    `{"op":"replay.seek","timestamp":1681550000000}`
  </Card>

  <Card title="Stop" icon="square">
    `{"op":"replay.stop"}`
  </Card>
</CardGroup>

## Gap Handling

```javascript theme={"theme":"github-dark"}
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type === "gap_detected") {
    console.warn("Replay gap", msg.channel, msg.symbol, msg.gap_start, msg.gap_end);
  }
};
```

## Replay Event Flow

Replay control commands use dotted `op` values. Server events use underscore event names.

| Event              | Meaning                                         | Client behavior                                                          |
| ------------------ | ----------------------------------------------- | ------------------------------------------------------------------------ |
| `replay_started`   | Replay window accepted                          | Start the run manifest and record channel, symbol, start, end, and speed |
| `replay_snapshot`  | Initial state before timeline messages          | Build baseline state before processing historical messages               |
| `historical_data`  | Timeline data emitted in replay order           | Apply the message according to channel semantics and preserve timestamp  |
| `gap_detected`     | Missing or discontinuous interval               | Mark the output incomplete, stop, or rebuild from a known checkpoint     |
| `replay_paused`    | Replay paused after `replay.pause`              | Keep state but stop advancing the run clock                              |
| `replay_resumed`   | Replay resumed after `replay.resume`            | Continue processing from the current timestamp                           |
| `replay_completed` | Replay reached the end of the configured window | Close the manifest and label the output complete, partial, or rejected   |
| `replay_stopped`   | Replay stopped by `replay.stop`                 | Close the manifest as stopped and keep the stop reason                   |

## Replay Design

Replay is for workflows where event order matters: backtests, local book reconstruction, incident review, data QA, and model-input regeneration. Choose the narrowest channel set that can answer the question. A single-channel order-book replay is easier to audit than a broad multi-channel replay, and a broad replay should be split into windows that can be resumed independently.

## Replay Manifest

Store a manifest beside every replay output.

```json theme={"theme":"github-dark"}
{
  "surface": "websocket_replay",
  "venue_family": "hyperliquid_core",
  "symbol": "BTC",
  "channels": ["orderbook", "trades"],
  "window": {
    "start": 1681516800000,
    "end": 1681603200000
  },
  "speed": 10,
  "gap_events": [],
  "output": "s3://example/replay/btc-2023-04-15.jsonl"
}
```

Include replay controls used during the run, such as pause, resume, seek, or stop. If the client changes speed or seeks to a new timestamp, record that in the manifest so another run can explain the output sequence.

## Window Sizing

Start with a narrow window and one channel. Widen only after the consumer can keep messages ordered, write output without backlog, and handle gaps. For long jobs, split replay into resumable windows and keep a cursor or output checkpoint between them.

## Output Discipline

Store replay configuration with the output: channel list, symbol, start, end, speed, requested venue family, gap events, and any request or correlation IDs. If a replay emits a gap, mark the derived output as incomplete or rebuild from a safe checkpoint. Do not silently interpolate missing market events.

## REST Or Replay

Use REST history when you need records from a bounded window and ordering can be handled after retrieval. Use replay when the sequence itself is the product requirement: maintaining a book, testing a strategy against event cadence, or reproducing a historical stream.

## Review Rule

Replay examples should include stop conditions. A safe replay has a bounded window, controlled speed, gap handling, and a clear output destination. For backtests, store the replay config, replay events, and gap events beside the result so another engineer can inspect the run without reproducing the whole stream.
