> ## 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.

# WebSocket

Broadcast events to connected WebSocket clients via the EventStream Durable Object.

The `websocket` provider broadcasts delivered events to any WebSocket client subscribed to a named channel. Under the hood it uses hookstream's `EventStream` Durable Object (one per org, Hibernatable WebSockets), so there's no extra infrastructure to manage.

**When to use this**: you're building a live dashboard, a developer tool that streams webhooks to the browser, or a multi-client broadcast fan-out where many viewers need the same events.

Unlike the other providers, WebSocket doesn't make an outbound HTTP call — it hands the event to the per-org `EventStream` DO, which fans it out to every connected subscriber on the configured channel.

## Configuration

Channel identifier to broadcast on. Alphanumeric with dots, underscores, or hyphens (`^[a-z0-9._-]+$/i`). Clients subscribe to this exact name.

## Authentication

**None (destination)**

The destination itself has no auth — it just publishes into your org's DO. Access control happens on the client side when subscribing.
  **Client subscribe**

Clients connect to `/v1/ws` with an API key and subscribe to the channel:

    ```
    wss://hookstream.io/v1/ws?token=$HOOKSTREAM_API_KEY
    ```

    After the upgrade, send a subscribe frame:

    ```json
    { "type": "subscribe", "channel": "live-orders" }
    ```

## Message Format

Broadcasts are sent as JSON frames with `type: "event.delivered"`:

```json
{
  "type": "event.delivered",
  "channel": "live-orders",
  "data": {
    "event_id": "evt_abc123",
    "destination_id": "dest_xyz",
    "payload": "{...webhook body as a string...}"
  }
}
```

The `payload` field is the raw event body as a string (so it matches exactly what would've been POSTed to an HTTP destination).

## Example

```bash
curl -X POST https://hookstream.io/v1/destinations \
  -H "X-API-Key: $HOOKSTREAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Live Dashboard",
    "type": "websocket",
    "config": {
      "channel_name": "live-orders"
    }
  }'
```

Browser client:

```js
const ws = new WebSocket(`wss://hookstream.io/v1/ws?token=${API_KEY}`);
ws.onopen = () => ws.send(JSON.stringify({ type: "subscribe", channel: "live-orders" }));
ws.onmessage = (e) => console.log(JSON.parse(e.data));
```

## Gotchas

**No persistence — only live clients receive events**

If no client is connected when an event is delivered, the broadcast is dropped. Use WebSocket alongside another destination (HTTP, SQS, S3) if you need durability.
  **Per-org fan-out**

One `EventStream` DO per org handles all channels, so subscribers on different channels inside the same org share the same hibernating DO. This is cheap — Hibernatable WebSockets incur no idle cost.

## Next Steps

**[HTTP / Webhook](/providers/http)**

Deliver to traditional HTTP endpoints.
  **[Destinations](/concepts/destinations)**

How destinations, retries, and circuit breakers work together.
  **[Delivery Pipeline](/concepts/delivery-pipeline)**

Full pipeline from ingest to delivery.
  **[Destinations API](/api/destinations)**

Full API reference.