- Create a session using a REST API.
- Open a WebSocket connection.
- Stream live audio over the WebSocket.
- End the session using a REST API.
GET /ws/stream) with an ambient session ID.What this guide covers
Use this page to understand the end-to-end WebSocket streaming flow before implementing a client. This guide explains:- What Ambient, Form filling, and Dictation have in common.
- How their WebSocket endpoints, messages, and result workflows differ.
- The network and connection rules that apply across the streaming workflows.
- The step-by-step flow for Ambient, Form filling, and Dictation.
Whatโs common for WebSocket streaming
Ambient, Form filling, and Dictation use different WebSocket contracts, but they follow the same high-level integration pattern:Common steps for WebSocket streaming
Common steps for WebSocket streaming
-
Authenticate with Suki.
Use the Partner APIs to authenticate and obtain an
sdp_suki_token. See Partner authentication. - Create a session with REST. Create the appropriate session using the REST API before opening the WebSocket connection.
-
Open a secure WebSocket connection.
Connect using
wss://and use the same base host as your REST API connection. - Send JSON text frames. Each WebSocket message must be a UTF-8 text frame containing exactly one JSON object. See WebSocket streaming wire format.
- Send audio as Base64 inside JSON. Encode the audio as Base64 and place it in the audio field required by the workflow. Do not send audio as a binary WebSocket frame.
- End the WebSocket stream according to the workflow. After the final audio chunk, send the required end-of-stream message for that workflow. The exact message differs between Ambient/Form filling and Dictation.
- Complete the session and retrieve final data using REST when required. WebSocket streaming and REST session APIs work together. Depending on the workflow, use REST to complete the session and retrieve final results. See Complete the session after streaming.
Ambient/Form filling vs Dictation WebSocket streaming
Ambient, Form filling, and Dictation all use WebSockets to stream audio, but they support different use cases and have different streaming contracts.- Ambient streams clinical visit audio to Suki for note generation and related processing. See Stream Ambient audio.
- Form filling can use the Ambient WebSocket when it runs on the same socket. See Ambient vs Dictation streaming.
- Dictation streams speech to Suki and returns transcript text in real time. See Stream Dictation audio.
/ws/stream, the final AUDIO.data value must be RU9G. This is the Base64 encoding of the EOF marker used by the Ambient wire format.Send RU9G exactly as specified. Do not send EOF as plain text in the data field.Refer to End the stream segment for more information.ambient_session_id, but the IDs are not interchangeable.- For Ambient, use the ID returned by Create ambient session.
- For Form filling, use the ID returned by Create Form filling session when using Form filling with
/ws/stream.
High-level architecture
Below is the high-level architecture for Ambient, Form filling, and Dictation flows. Where they differ is the:- Endpoint.
- Outbound message contract.
- How results come back.
Network and connection management
Plan your integration around the following network requirements and connection behaviors.Network requirements
For reliable real-time streaming, Suki recommends these minimums:How do you keep the connection alive
While a stream is paused, send anEVENT message with event: KEEP_ALIVE at least once every five seconds. Ambient streaming allows a maximum pause of 30 minutes.
For related idle-timeout guidance (including the 25 second audio inactivity window), see the Ambient API quickstart and Audio capture and streaming FAQs.
Call duration and reconnection
Ambient- There is no upper limit on call duration while the stream is active.
- You can reopen
GET /ws/streamwith the sameambient_session_idonly while the ambient job is still in theCREATEDstate. If the job has moved to another status (for exampleRUNNING,COMPLETED, orCANCELLED), the handshake fails withFailedPrecondition. - Suki needs a minimum amount of audio to generate content. For calls shorter than 1 minute, Suki may not have enough data, returns empty content, and marks the session as
skipped.
- One Dictation session can support multiple speech sessions over time (for example push-to-talk).
- Open
/ws/transcribeonly when the session isREADYorIDLE. See Stream Dictation audio for the session-state rules.
How streaming works
Choose the tab for your product. Ambient, Form filling, and Dictation share the REST โ WebSocket โ REST pattern. Ambient and Form filling use the sameGET /ws/stream wire format. Dictation uses GET /ws/transcribe with a different message contract.
- Ambient
- Form Filling
- Dictation
GET /ws/stream with the same wire format, but you create a Form filling session and retrieve structured form data through Form filling REST APIs. Open the Form filling tab for that path.- Create an ambient session and seed session context with REST.
- Open a WebSocket connection to
GET /ws/stream. - Send one
START_TIMEmessage for the stream segment. - Send one JSON message per audio chunk (Base64 PCM in
data). - Optionally send
EVENTmessages, such asPAUSE,RESUME, orKEEP_ALIVE, when control is needed. - Send the ambient end marker as the final
AUDIOmessage (data:RU9G). - Close the socket, then end the ambient session with REST and retrieve results.
Create the Ambient session and seed context
Create the session with REST, then seed session context before you stream. Do not open the WebSocket until the ambient session exists and context is seeded.Open WebSocket GET /ws/stream
Authenticate with the documented handshake:- Browser
Sec-WebSocket-Protocol:SukiAmbientAuth,<sdp_suki_token>,<ambient_session_id>(token before session ID). - Non-browser headers:
sdp_suki_tokenandambient_session_id.
CREATED state. Other statuses return FailedPrecondition.Send START_TIME
Send one START_TIME message for the stream segment before audio chunks. This is required for Ambient in the documented contract.Send AUDIO chunks
Send one JSON text frame per chunk. Audio bytes are Base64 PCM in the data field.Do not:- Send binary WebSocket frames.
- Send multiple JSON objects in one frame.
- Stream raw audio over HTTP.
Optional EVENT messages
When control is needed, send EVENT messages such as PAUSE, RESUME, KEEP_ALIVE, CANCEL, or ABORT. The gateway acts on PAUSE, RESUME, and CANCEL. While paused, send KEEP_ALIVE at least once every five seconds per the documented idle-timeout guidance. Refer to the Audio capture and streaming FAQs for the full event enum.End the stream with RU9G
End the stream segment with a final AUDIO message whose data is RU9G (Base64 of the bytes EOF).Close the socket, then finish with REST
Close the WebSocket, then end the ambient session with REST and retrieve results. Final transcripts and notes are not guaranteed on the WebSocket. Treat REST as the source of truth after streaming.For field-level message shapes, refer to Ambient streaming wire format. For end-of-session steps, refer to Complete the session after streaming.Available cookbooks
Available tutorials
Build an Ambient Streaming Client
Authenticate, create a session, stream PCM audio over WebSocket, and retrieve clinical note results.
Build a Dictation Streaming Client
Create a transcription session, stream audio, read partial frames, and print the final transcript.
Build a Form filling Session Client
Create a Form filling session, send template context, stream audio, and retrieve structured form data.
Next steps
Follow Ambient vs Dictation streaming to compare endpoints, auth, and message contracts. Read Audio capture best practices before you open the WebSocket. Follow Stream ambient audio when you already have an ambient session and need to push live audio on/ws/stream.
Follow Stream Dictation audio when you have a Dictation session and need real-time transcript frames on /ws/transcribe.
Open WebSocket streaming wire format for Ambient and Dictation wire format pages, send order, and chunking.