Building custom chat UI with Guest API WebSocket instead of widget

We are ditching the default web widget for a custom frontend build. The goal is to use the WebSocket-based Guest API directly to handle messages without the overhead of the full widget library.

I’ve successfully obtained the guest token via /api/v2/conversations/messaging/guest/token. The response looks valid. I’m using the standard WebSocket connection string pattern from the docs:

var ws = new WebSocket('wss://<org_id>.mypurecloud.com/api/v2/conversations/messaging/guest/session');

I’m passing the token in the initial handshake payload:

{
 "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
 "sessionId": "gen-session-123"
}

The connection opens successfully (onopen fires). However, as soon as I try to send a message event or even just a ping, the socket closes immediately with no error code in onclose. The server seems to drop it.

I’ve checked the network tab. The HTTP upgrade request returns 101 Switching Protocols. So the tunnel is established. It’s just the application layer that fails.

Is there a specific header or payload structure required for the initial WebSocket frame that isn’t in the public docs? I’m looking at the messaging namespace endpoints, but the WebSocket protocol for guest sessions is pretty sparse on examples.

Here is the exact JSON I’m pushing on onopen:

{
 "type": "message",
 "text": "Hello world"
}

Nothing happens. Socket dies. Any idea what I’m missing in the handshake or the first message payload?