Connect to Stream and Transcribe APIs, handle real-time messages, and manage session lifecycle
The SDK wraps both WebSocket APIs — Stream and Transcribe — with a unified interface: a promise-based connect(), automatic reconnection, and typed message events.
Both WebSocket APIs require a handshake before audio can flow. After the connection opens, the client must send a configuration message and wait for the server to respond with CONFIG_ACCEPTED. Only then is it safe to start streaming audio. If configuration is rejected (CONFIG_DENIED, CONFIG_TIMEOUT), the session cannot be used.By default, the SDK handles this handshake for you. Pass configuration to connect() and the promise resolves only after CONFIG_ACCEPTED is received — or rejects (and closes the socket) if the configuration is refused.
Because connect() awaits the handshake before returning, your socket.on("message", ...) handler is registered after the config exchange completes. CONFIG_* messages are never visible in the message handler — they are consumed internally by the SDK.
By default connect() waits for CONFIG_ACCEPTED before resolving. Set awaitConfiguration: false to get the socket returned immediately — before the WebSocket even opens. This lets you attach event handlers right away and guarantees you won’t miss any messages, including early config status events. You are then responsible for waiting for CONFIG_ACCEPTED before sending audio. If configuration is rejected, error events are emitted on the socket rather than the promise rejecting.
awaitConfiguration: false was the default behavior prior to v1.0.0. If you are migrating from an older version, set it explicitly to preserve the previous behavior.
const socket = await client.stream.connect({ id: interactionId, configuration: { transcription: { primaryLanguage: "en", participants: [{ channel: 0, role: "doctor" }], }, mode: { type: "facts", outputLocale: "en" }, }, awaitConfiguration: false, // socket returned as soon as the WebSocket opens});// Must wait for CONFIG_ACCEPTED before sending audiosocket.on("message", (msg) => { if (msg.type === "CONFIG_ACCEPTED") { console.log("Configuration accepted — ready to send audio"); socket.sendAudio(audioBuffer); } if (msg.type === "CONFIG_DENIED") { console.error("Configuration denied:", msg.reason); socket.close(); }});
If you want to manage the whole handshake flow manually and only use the SDK for types and reconnection, omit configuration from connect(). The socket opens asynchronously, so wait for it to reach OPEN and then call sendConfiguration() manually — you are responsible for waiting for CONFIG_ACCEPTED before sending audio.
const socket = await client.stream.connect({ id: interactionId });// Wait for CONFIG_ACCEPTED before sending audiosocket.on("message", (msg) => { if (msg.type === "CONFIG_ACCEPTED") { console.log("Configuration accepted — ready to send audio"); socket.sendAudio(audioBuffer); } if (msg.type === "CONFIG_DENIED") { console.error("Configuration denied:", msg.reason); socket.close(); }});// The socket opens asynchronously; wait for OPEN before sending configurationawait socket.waitForOpen();socket.sendConfiguration({ type: "config", configuration: { transcription: { primaryLanguage: "en", participants: [{ channel: 0, role: "doctor" }], }, mode: { type: "facts", outputLocale: "en" }, },});
After the socket is OPEN and configuration has been accepted, you can use the SDK’s methods to send audio, flush, end, and subscribe to typed messages.
SDK method reference: See the socket methods and connect() parameters in the JavaScript SDK reference.
Protocol behavior & message semantics: If you want to understand what each message means (and the underlying wire format), refer to the WebSocket API docs.