Appearance
WebSocket ingest
Use the GET /recordings/{recordingId}/ingest/ws route when you want to stream rrweb payloads over a single WebSocket connection instead of issuing multiple HTTP POST requests.
Making a connection
- URL template:
wss://api.rrwebcloud.com/recordings/{recordingId}/ingest/ws - Query parameters:
contentType(application/x-ndjson|application/ndjson|application/json) — defaults toapplication/x-ndjson.contentEncoding(gzip|br|zstd) — optional, defaults to identity.debug— optional; when set totruethe server echoes the decoded payload back over the WebSocket along with the upstream response metadata.
- Authentication is handled server-side using your configured token/allowed origins, so clients do not need to add headers beyond the usual WebSocket handshake (see Authentication).
⚠️ Browsers do not allow custom request headers during the WebSocket handshake, so
contentType,contentEncoding, anddebugmust be supplied as query parameters.
Client lifecycle
- Open the socket with the desired query parameters.
- Stream NDJSON/JSON frames:
- Send text frames for uncompressed payloads.
- Send binary frames if the payload is pre-compressed.
- The server automatically flushes upstream whenever either
- about 256 KB of buffered data has been received, or
- the connection has been idle for roughly 1 second.
- Call
ws.close()when the batch is complete to force a final flush and close.
The server sends back:
- Zero or more debug frames (plain text NDJSON) when
debug=true. - One or more summary frames containing JSON. Intermediate summaries use
"final": falsewhile the last summary will use"final": true.
json
{
"type": "upstream-result",
"ok": true,
"status": 204,
"statusText": "",
"headers": {
"content-type": "application/json"
},
"final": true
}If forwarding fails, the server emits:
json
{
"type": "error",
"status": 502,
"message": "Unable to forward recording data."
}Connections close with code 1000 for success and 1011 for failures so that clients can react without parsing the summary payload.
Example
ts
const recordingId = window.crypto.randomUUID();
const ws = new WebSocket(
`wss://api.rrwebcloud.com/recordings/${recordingId}/ingest/ws?contentType=application%2Fx-ndjson`,
);
ws.addEventListener("open", () => {
ws.send(JSON.stringify({ type: "snapshot", data: {} }) + "\n");
ws.send(JSON.stringify({ type: "incremental", data: {} }) + "\n");
ws.close(); // flush to rrweb cloud
});
ws.addEventListener("message", (event) => {
try {
const payload = JSON.parse(event.data);
if (payload.type === "upstream-result") {
console.log("rrweb cloud accepted payload", payload.status);
}
} catch {
console.log("Debug payload", event.data);
}
});