Relay protocol
The Connect relay is a small Cloudflare Worker that takes HTTPS POST events on one side and fans them out to subscribed WebSocket clients on the other. It runs on Workers + Durable Objects, holds no Twitch credentials, and never inspects the bodies it forwards.
If you just want to point the recorder at a hosted relay, see Connect relay instead.
What it does
Section titled “What it does”- Accepts HTTPS
POSTat/u/{token}with an arbitrary body. - Forwards bytes to every open WebSocket on
/u/{token}/subscribe. - Buffers events for up to five minutes so a brief client reconnect doesn’t drop them.
- Echoes a synchronous response back to the original
POSTfor webhook verification challenges.
What it doesn’t
Section titled “What it doesn’t”- Verify, parse, or log payload bodies. Your client verifies the HMAC.
- Store events to disk beyond the 5-minute buffer.
- Hold any Twitch credentials.
- Tunnel arbitrary HTTP. Only
POST→ WebSocket fan-out. - Provide encryption beyond standard HTTPS / WebSocket transport.
Tokens
Section titled “Tokens”Tokens namespace a Durable Object — each token gets its own buffer and connection set. Multiple clients may subscribe to the same token. Tokens must match [a-zA-Z0-9_-]{16,128}.
Ingest
Section titled “Ingest”POST /u/{token}Content-Type: application/json
<body>Normal async deliveries return 202 Accepted immediately. For Twitch EventSub verification challenges, the relay waits for the subscribed client to replay the request locally and returns the local handler’s response to Twitch.
Subscribe
Section titled “Subscribe”GET /u/{token}/subscribe?cursor={last_cursor}Upgrade: websocketOn connect, the relay replays any buffered events with a monotonic cursor newer than cursor, then streams new events as they arrive.
Frames the relay sends
Section titled “Frames the relay sends”{ "id": "uuid", "cursor": 42, "ts": 1714291200000, "headers": { "twitch-eventsub-message-id": "...", "...": "..." }, "body": "<base64-encoded body>", "requires_response": false}Headers are forwarded verbatim with lower-cased keys, so the receiving client can reconstruct the original request and verify HMAC signatures itself. The relay does not parse, validate, or filter headers.
Frames the subscriber sends back
Section titled “Frames the subscriber sends back”After replaying a frame locally, the subscriber posts:
{ "type": "dispatch_result", "id": "uuid", "status": 200, "headers": { "content-type": "text/plain; charset=utf-8" }, "body": "<base64-encoded response body>"}For normal async deliveries, a non-2xx/3xx dispatch result causes the relay to close that subscriber so it reconnects and replays from the last acknowledged cursor.
When requires_response is true, the relay returns the response to the original HTTP caller. This is required for Twitch EventSub verification challenges.
Token validation
Section titled “Token validation”Self-hosted deployments can leave token validation unset and use any token matching the pattern above.
The hosted Connect deployment validates every ingest and subscribe request against the cloud Worker, so revoked tokens and inactive subscriptions are rejected before reaching the Durable Object:
TOKEN_VALIDATE_URL=https://api.replayvod.com/relay/tokens/validateRELAY_SHARED_SECRET=...Self-host
Section titled “Self-host”The relay is MIT-licensed and intended to be self-hostable. You need a Cloudflare account and wrangler installed.
-
Install dependencies.
Terminal window cd relaynpm install -
Develop locally.
Terminal window npm run dev -
Deploy to your own Workers account.
Terminal window npm run deploy
License
Section titled “License”The relay is MIT-licensed; the recorder, dashboard, and supporting code are GPL-3.0.