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

# WebSockets

Real-time WebSocket connections for live event streaming and inbound sources.

hookstream provides three WebSocket endpoints for real-time communication. All connections use Cloudflare Durable Objects with the Hibernatable WebSocket API — efficient, stateful connections that survive idle periods without cost.

WebSocket upgrades cannot use custom request headers in browsers, so API keys are passed via the `token` query parameter instead of `X-API-Key`. Browser clients signed in to the dashboard use session cookies automatically.

## Dashboard Stream

GET `/v1/ws`

Upgrade to authenticated WebSocket for real-time organization-wide event streaming. After connecting, you receive real-time events for your organization across all sources and destinations. Messages are JSON with a `channel` field for filtering (e.g., `events`, `deliveries`, `issues`).

**Authentication:** API key via `token` query param, or session cookie.

### Query Parameters

API key for authentication. Browser clients with an active session cookie can omit this.

**JavaScript (browser)**

```js
    // Uses session cookie automatically
    const ws = new WebSocket("wss://hookstream.io/v1/ws");

    ws.addEventListener("message", (event) => {
      const msg = JSON.parse(event.data);
      console.log(msg.channel, msg.data);
    });
    ```
  **Node.js**

```js
    import WebSocket from "ws";

    const ws = new WebSocket(
      `wss://hookstream.io/v1/ws?token=${process.env.HOOKSTREAM_API_KEY}`
    );

    ws.on("message", (raw) => {
      const msg = JSON.parse(raw.toString());
      console.log(msg.channel, msg.data);
    });
    ```
  **CLI**

```bash
    hookstream listen
    ```

    See [`hookstream listen`](/cli/commands) for filtering and formatting options.

**Server message**

```json
{
  "type": "event",
  "channel": "events",
  "data": {
    "id": "evt_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
    "source_id": "src_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
    "method": "POST",
    "status": "delivered",
    "received_at": "2026-03-01T14:30:00Z"
  }
}
```

## Test Session Stream

GET `/v1/ws/test/:source_id`

Upgrade to unauthenticated WebSocket for a [test session's](/api/test-sessions) real-time event feed. Used by the browser-based test inspector.

**Authentication:** None. Validates the source is an ephemeral test session.

**JavaScript**

```js
    const sessionId = "a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8";
    const ws = new WebSocket(`wss://hookstream.io/v1/ws/test/${sessionId}`);

    ws.addEventListener("message", (event) => {
      const msg = JSON.parse(event.data);
      if (msg.type === "event") {
        console.log("New webhook:", msg.data);
      }
    });
    ```

**Server message**

```json
{
  "type": "event",
  "channel": "test",
  "data": {
    "id": "evt_001",
    "method": "POST",
    "body": { "test": true },
    "received_at": "2026-03-01T12:05:00Z"
  }
}
```

## Inbound WebSocket Source

GET `/v1/ws/source/:source_id`

Upgrade to authenticated WebSocket for **inbound event ingestion**. Instead of receiving HTTP webhooks, you can send events over a persistent WebSocket connection. Each message sent on this connection is ingested as an event and routed through the normal delivery pipeline. Useful for high-throughput or bidirectional scenarios.

**Authentication:** API key via `token` query param.

### Query Parameters

API key for authentication.

**Node.js**

```js
    import WebSocket from "ws";

    const ws = new WebSocket(
      `wss://hookstream.io/v1/ws/source/src_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6?token=${process.env.HOOKSTREAM_API_KEY}`
    );

    ws.on("open", () => {
      ws.send(JSON.stringify({
        type: "order.created",
        data: { id: "ord_123", amount: 4999 },
      }));
    });

    ws.on("message", (raw) => {
      const ack = JSON.parse(raw.toString());
      console.log("Event ID:", ack.event_id);
    });
    ```

**Client message**

```json
{
  "type": "order.created",
  "data": { "id": "ord_123", "amount": 4999 }
}
```

**Server ack**

```json
{
  "type": "ack",
  "event_id": "evt_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9"
}
```

## Message format

All WebSocket messages are JSON objects with a `type` field indicating the message kind.

**Server → client:**

| Type | Meaning |
| --- | --- |
| `event` | New event received at a source. |
| `delivery` | Delivery attempt completed. |
| `issue` | Issue created or updated. |
| `sync` | Database collection record synced. |
| `ping` | Heartbeat — respond with `pong`. |

**Client → server:**

| Type | Meaning |
| --- | --- |
| `subscribe` | Subscribe to a specific channel. |
| `pong` | Heartbeat response. |

## Related

**[Test Sessions](/api/test-sessions)**

Ephemeral testing endpoints.
  **[Events](/api/events)**

Browse past events via REST.