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

tokenstringquery

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

js
// Uses session cookie automaticallyconst ws = new WebSocket("wss://hookstream.io/v1/ws");ws.addEventListener("message", (event) => { const msg = JSON.parse(event.data); console.log(msg.channel, msg.data);});
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 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); }});
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

tokenstringrequiredquery

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

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