WebSocket API
Subscribe to live webhook events for an endpoint with one long-lived connection. You need an API key created in the web app.
Connection URL
wss://api.hooknexus.com/ws/:endpointId?apikey=<your_api_key>- Replace
:endpointIdwith your endpoint’s ID (UUID from the dashboard). - Replace
<your_api_key>with the secret you copied when the key was created (URL-encode it if it contains special characters).
The key must belong to the same account as the endpoint, and your plan must allow API keys and WebSocket usage.
This connection also counts toward the endpoint’s shared WebSocket concurrency limit, alongside dashboard and CLI listeners.
Server message types
Messages are JSON with a type field and a numeric timestamp (milliseconds).
| Type | Purpose |
|---|---|
connected | Sent right after the connection opens; may include a small payload (for example a connection id). |
new_request | Fired when a webhook hits your /h/:endpointId URL; payload contains the captured request (method, path, headers, query, body, etc.). |
replay_request | Fired when the dashboard dispatches a saved request to this non-web client; payload.request contains the original request snapshot. |
error | Describes a connection or processing error. |
pong | Reply to a client ping. |
Client ping / pong
Send a JSON text frame:
{ "type": "ping" }The server responds with:
{ "type": "pong", "timestamp": 1711180800123 }If your client only cares about live traffic, safely ignore unknown type values so future protocol additions do not break it.
Examples
const endpointId = 'YOUR_ENDPOINT_ID';const apiKey = 'YOUR_API_KEY';
const ws = new WebSocket( `wss://api.hooknexus.com/ws/${endpointId}?apikey=${encodeURIComponent(apiKey)}`);
ws.addEventListener('open', () => { console.log('connected');});
ws.addEventListener('message', (ev) => { const msg = JSON.parse(ev.data); if (msg.type === 'new_request') { console.log('Webhook:', msg.payload?.method, msg.payload?.body); }});const WebSocket = require('ws');
const endpointId = process.env.ENDPOINT_ID;const apiKey = process.env.HOOKNEXUS_API_KEY;
const ws = new WebSocket( `wss://api.hooknexus.com/ws/${endpointId}?apikey=${encodeURIComponent(apiKey)}`);
ws.on('open', () => { console.log('connected');});
ws.on('message', (data) => { const msg = JSON.parse(data.toString()); if (msg.type === 'new_request') { console.log(JSON.stringify(msg.payload, null, 2)); } if (msg.type === 'replay_request') { console.log('Replay request received:', msg.payload?.request?.id); }});
setInterval(() => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'ping' })); }}, 25000);
ws.on('close', (code, reason) => { console.log('closed', code, reason.toString());});
ws.on('error', (error) => { console.error('socket error:', error.message);});For a copy-pasteable end-to-end sample, see Node.js API key listener demo.
Example new_request envelope
{ "type": "new_request", "timestamp": 1711180800123, "payload": { "id": "log-uuid", "method": "POST", "path": "/h/your-endpoint-id", "headers": { "content-type": "application/json" }, "query": {}, "body": "{}", "contentType": "application/json", "ip": "203.0.113.10", "size": 2, "createdAt": "2026-03-23T12:00:00.000Z" }}Example replay_request envelope
{ "type": "replay_request", "timestamp": 1711180800999, "payload": { "replayId": "replay_123", "sourceRequestId": "log-uuid", "dispatchedAt": "2026-03-28T10:00:00.000Z", "target": { "connectionId": "conn_123", "clientType": "api_key", "clientMode": null, "connectedAt": 1711180800000, "userAgent": null }, "request": { "id": "log-uuid", "endpointId": "your-endpoint-id", "method": "POST", "path": "/h/your-endpoint-id", "headers": { "content-type": "application/json" }, "query": {}, "body": "{}", "contentType": "application/json", "ip": "203.0.113.10", "userAgent": "stripe/1.0", "size": 2, "createdAt": "2026-03-23T12:00:00.000Z" } }}