# WebSocket stream

> Real-time Robinhood Chain data over one WebSocket - trades, prices, live candles, new launches, graduations, new pools, LP and tax changes, wallet activity, with replay and reorg handling.

Source: https://crius.sh/docs/reference/stream/

**WS** `wss://api.crius.sh/v1/{chain}/stream`

**Plan:** Free and above, key with the `stream` scope · **Cost:** 1 credit per connection

One connection carries many subscriptions. Messages are pushed as soon as a block is decoded, typically well under a second after it was produced.

## Connecting

Authenticate with the `x-api-key` header, or with `?api_key=` where a client can't set headers (browsers):

```js
const ws = new WebSocket(`wss://api.crius.sh/v1/robinhood/stream?api_key=${key}`);
```

On connect the server sends a greeting with your limits:

```json
{"ch": "hello", "data": {"chain": "robinhood", "heartbeat_s": 15, "max_subscriptions": 10}}
```

## Operations

Send JSON messages with an `op`:

| Op | Message | Reply |
|---|---|---|
| Subscribe | `{"op": "subscribe", "channels": ["trades:0x…", "launches:all"]}` | `{"ch": "subscribed", "data": {"channels": […], "finality": "latest"}}` |
| Unsubscribe | `{"op": "unsubscribe", "channels": ["trades:0x…"]}` | `{"ch": "unsubscribed", …}` |
| Settled data only | `{"op": "subscribe", "channels": […], "finality": "safe"}` | events are held until their block is `safe` |
| Resume after a reconnect | `{"op": "resume", "seqs": {"trades:0x…": 90455}}` | missed messages (up to 60 s), then `{"ch": "resumed"}` |
| Ping | `{"op": "ping"}` | `{"ch": "pong", "ts": …}` |

Channel names are lowercase. Subscribing over your plan's limit, or to an Enterprise channel, returns `{"ch": "error", "data": {"code": "channel_denied", …}}` for those channels.

## Channels

| Channel | Pushes |
|---|---|
| `trades:<token>` | Every trade of a token (same shape as the [trade tape](https://crius.sh/docs/reference/trades/#trade-tape)) |
| `trades:pool:<pool>` | Every trade in one pool |
| `price:<token>` | Price updates (`usd`, `eth`, `liquidity_usd`); a snapshot is sent right after subscribing |
| `candles:<token>:<interval>` | The live candle (`t`, `o`, `h`, `l`, `c`, `v`, `n`) for `1s` … `1d` |
| `token:<token>` | Price and holder count changes |
| `tax:<token>` | Realized buy/sell tax changes |
| `lp:<token>` | Liquidity added or removed in the token's pools |
| `launches:<launchpad>` / `launches:all` | New launches (`pons`, `flap`, …) |
| `graduations:<launchpad>` / `graduations:all` | Graduations, with the new pool |
| `pools:new` | Every new Uniswap v2 / v3 / v4 pool, with hook permissions |
| `wallet:<address>` | Trades and transfers of a wallet |
| `dev:<address>` | New tokens launched by a creator |
| `firehose:trades` | Every trade on the chain (Enterprise) |

Every message has the same envelope:

```json
{
  "ch": "trades:0x0bd7d308f8e1639fab988df18a8011f41eacad73",
  "seq": 90455,
  "block": 95503752,
  "ts": 1792712930000,
  "data": {
    "id": "95503752-4-7",
    "type": "buy",
    "token": "0x0bd7d308f8e1639fab988df18a8011f41eacad73",
    "symbol": "WETH",
    "dex": "uniswap_v4",
    "trader": "0x2192bc3b4028acc1113f2cd9ac2cba70c36520db",
    "amount_base": 0.02724675461168212,
    "amount_quote": 64.939074,
    "price_usd": 2383.37,
    "value_usd": 64.9391
  }
}
```

`seq` increases by one per channel. Keep the last `seq` you saw for each channel and send them in a `resume` op after reconnecting to receive what you missed (60-second replay buffer).

## Heartbeats, finality and reorgs

- `{"ch": "heartbeat", "ts": …, "uptime_s": …}` arrives every 15 seconds; reconnect if you hear nothing for 45 seconds.
- `{"ch": "finality", "data": {"safe_block": …, "finalized_block": …}}` arrives on every connection whenever the safe or finalized block moves.
- If blocks are replaced, a `{"ch": "reorg", "data": {"common_ancestor", "removed_blocks", "depth"}}` message comes first, then every affected event is re-sent with `"removed": true` (same `id`), then the replacement events. Subscribe with `"finality": "safe"` if you never want to see reorged events.

> **Tip:**
> A complete reconnecting client is in the [real-time stream example](https://crius.sh/docs/examples/stream/).
