Genesys Cloud WebSocket subscription failing with 401 despite valid token

I’m trying to set up a simple Node.js script to listen for conversation events via the Notification API WebSocket. I’ve got the OAuth token generation working fine using the client credentials flow, and I can hit the REST endpoints without issue. The problem is connecting to the WebSocket endpoint.

Here’s the relevant code snippet using the ws library:

const WebSocket = require('ws');

const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'; // Valid token from console
const baseUrl = 'wss://api.mypurecloud.com/v2/analytics/events';

const ws = new WebSocket(baseUrl, {
 headers: {
 'Authorization': `Bearer ${token}`,
 'Content-Type': 'application/json'
 }
});

ws.on('open', () => {
 console.log('Connected');
 // Attempt to subscribe
 ws.send(JSON.stringify({
 type: 'subscribe',
 subscriptions: [
 {
 eventTypes: ['conversation:updated'],
 filters: {
 conversationType: 'voice'
 }
 }
 ]
 }));
});

ws.on('error', (err) => {
 console.error('WebSocket error:', err);
});

When I run this, the error event fires immediately with Error: Unexpected server response: 401. I’ve double-checked the token by using it in Postman to call /api/v2/authorization/oauth/token, and it’s valid. The token doesn’t expire for another hour. I’m not sure if I’m sending the subscription payload correctly or if there’s a specific header missing for the WebSocket handshake. The documentation mentions using the token in the query string for some endpoints, but the WebSocket examples show it in the headers. What am I missing here?