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

token string

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

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); });
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 real-time event feed. Used by the browser-based test inspector.

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

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); } });
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

token string required

API key for authentication.

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); });
json
{ "type": "order.created", "data": { "id": "ord_123", "amount": 4999 } }
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:

TypeMeaning
eventNew event received at a source.
deliveryDelivery attempt completed.
issueIssue created or updated.
syncDatabase collection record synced.
pingHeartbeat — respond with pong.

Client → server:

TypeMeaning
subscribeSubscribe to a specific channel.
pongHeartbeat response.
Test Sessions

Ephemeral testing endpoints.

Learn More
Events

Browse past events via REST.

Learn More
Ask a question... ⌘I