> ## Documentation Index
> Fetch the complete documentation index at: https://developer.suki.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Complete Streaming Session

> Close the WebSocket, end the session with REST, retrieve results, and troubleshoot for Ambient /ws/stream and Dictation /ws/transcribe

After you finish streaming audio, close the WebSocket and complete the session with REST APIs. Click on each tab below to learn more about how to complete the session after streaming for Ambient and Dictation.

<Tabs>
  <Tab title="Ambient">
    ## Complete the session after streaming audio

    After sending the final **`RU9G`** message, close the WebSocket connection and complete the ambient session with REST.

    <Steps>
      <Step title="Close the WebSocket Connection">
        Close the WebSocket connection from the client when you are done sending audio for that segment.
      </Step>

      <Step title="End the Session Using REST">
        End the session using [End ambient session API](/api-reference/ambient-sessions/end).
      </Step>

      <Step title="Retrieve Results Using REST">
        Poll session status and fetch transcript and structured data using these REST APIs:

        * [Poll Session status API](/api-reference/ambient-content/status)
        * [Get Transcript API](/api-reference/ambient-content/transcript)
        * [Get Structured data API](/api-reference/ambient-content/content)
      </Step>
    </Steps>

    <Note>
      Final transcripts and notes are not guaranteed to arrive over WebSocket. Treat REST APIs as the source of truth.
    </Note>

    ## Troubleshooting common issues while streaming audio

    Use this table to troubleshoot common ambient streaming errors. It explains what each error or behavior means, why it occurs, and how to resolve it.

    | Problem                                                                        | Why it happens                                                                                                                                   | How to fix it                                                                                                                                                                                                        |
    | :----------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Server returns JSON parse errors (for example, invalid character or null byte) | The WebSocket received a binary frame, a non-JSON payload, or multiple JSON objects in a single frame.                                           | Send one UTF-8 JSON object per WebSocket text frame. Do not send binary frames or concatenate multiple JSON objects.                                                                                                 |
    | Audio is ignored or transcription is incorrect                                 | Audio was not encoded as expected. Common causes include hexadecimal encoding, URL-safe Base64, or sending WAV headers instead of raw PCM audio. | Encode raw LINEAR16 PCM audio using standard Base64 ([RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648)) before sending it in the **`data`** field.                                                           |
    | The session never completes                                                    | The server never received the end-of-stream marker.                                                                                              | End the stream by sending a final **`AUDIO`** message with **`"data": "RU9G"`** (Base64 for EOF).                                                                                                                    |
    | Control messages are ignored                                                   | A control action was sent in the **`data`** field instead of as an event message.                                                                | Send control actions as **`{"type":"EVENT","event":"<VALUE>"}`**. Do not place control values in **`data`**.                                                                                                         |
    | No final note or transcript is available                                       | Closing the WebSocket does not end the ambient session or trigger note generation.                                                               | After streaming completes, call the ambient REST API to end the session, then retrieve the generated note and transcript.                                                                                            |
    | The WebSocket disconnects during a long pause                                  | No messages were sent before the keep-alive timeout expired.                                                                                     | While audio is paused, send a **`KEEP_ALIVE`** event at least every **5 seconds**. Ambient supports pauses of up to **30 minutes** when keep-alives are maintained. See the [Quickstart](/api-reference/quickstart). |
    | Unable to reconnect after a disconnect                                         | The session has already moved beyond the **`CREATED`** state.                                                                                    | Reconnect to **`/ws/stream`** using the same **`ambient_session_id`** only while the session status is **`CREATED`**. Otherwise, the handshake returns **`FailedPrecondition`**.                                     |
  </Tab>

  <Tab title="Dictation">
    ## Complete the session after streaming

    After you send **`AUDIO_END`** and finish reading results from the WebSocket, close the connection and complete the session with REST.

    <Steps>
      <Step title="Close the WebSocket Connection">
        Close the WebSocket connection from the client when you are done sending audio on that connection.
      </Step>

      <Step title="End the Dictation Session Using REST">
        End the transcription session using [End Dictation session API](/api-reference/audio-transcription/end-session).
      </Step>

      <Step title="Retrieve Results Using REST">
        Follow [Audio Dictation documentation](/documentation/concepts/dictation/dictation) to retrieve final or cumulative transcripts and clean up the session. Use the same **`transcription_session_id`** and **`sdp_suki_token`** patterns as the rest of the Dictation APIs.
      </Step>
    </Steps>

    <Note>
      End the session and retrieve transcripts using the REST flows linked in the steps above. The outbound WebSocket contract in this guide does not replace those APIs.
    </Note>

    ## Troubleshooting common issues for Dictation streaming

    Use this table to troubleshoot common Dictation streaming errors. It explains what each error or behavior means, why it occurs, and how to resolve it.

    | Problem                                                                                      | Why it happens                                                                                                               | How to fix it                                                                                                                                                                                                                                                                                            |
    | :------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Handshake fails with **`FailedPrecondition`** (session is not accepting new speech sessions) | The Dictation session is **`RUNNING`**, **`COMPLETED`**, or otherwise not ready for a new speech session.                    | Open **`/ws/transcribe`** only when the session is **`READY`** or **`IDLE`**. Wait until the previous speech session on that **`transcription_session_id`** has finished, you sent **`AUDIO_END`**, received **`EOF`**, and the session returned to **`READY`** or **`IDLE`**, before you connect again. |
    | **401** on handshake or immediate disconnect                                                 | The browser **`Sec-WebSocket-Protocol`** string is wrong, or the token and session ID are in the wrong order.                | Use **`SukiAmbientAuth,<sdp_suki_token>,<transcription_session_id>`**, not **`SukiTranscriptionAuth`**. Put the token before the session ID. Only the session ID value differs from Ambient (`transcription_session_id` vs `ambient_session_id`).                                                        |
    | Server returns JSON parse errors (for example, invalid character or null byte)               | The WebSocket received a binary frame, a non-JSON payload, or multiple JSON objects in a single frame.                       | Send one UTF-8 JSON object per WebSocket text frame. Do not send binary frames or concatenate multiple JSON objects.                                                                                                                                                                                     |
    | Audio is ignored or transcription is incorrect                                               | The payload used the ambient **`data`** field, non-PCM bytes, hexadecimal or URL-safe Base64, or WAV headers treated as PCM. | Encode raw **PCM\_S16LE** with standard Base64 ([RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648)) and send it in **`audioData`**. Strip the WAV header (for example **44** bytes) or decode to raw PCM before encoding.                                                                         |
    | The session never completes                                                                  | The server never received the end-of-audio message.                                                                          | After the last **`AUDIO`** chunk, send **`{"type":"EVENT","event":"AUDIO_END"}`**.                                                                                                                                                                                                                       |
    | Partial UI flicker or empty **`words`**                                                      | Every inbound frame is treated as committed text, or **`words`** is read from partial frames.                                | Show **`is_final: false`** frames as draft text. Use **`words`** on **`is_final: true`** frames for word-level or speaker-aware display. Do not treat **`transcript_id`** as a stable key for the same utterance across partials.                                                                        |
    | No final transcript is available, or the session is left open                                | Closing the WebSocket does not end the Dictation session or guarantee a final transcript.                                    | After you finish reading frames, call [End Dictation session](/api-reference/audio-transcription/end-session) to close the session and retrieve results.                                                                                                                                                 |
  </Tab>
</Tabs>

## Next steps

<Icon icon="file-lines" iconType="solid" /> Open the [Ambient audio streaming API](/api-reference/ambient-sessions/audio-stream) for the ambient WebSocket request and response contract.

<Icon icon="file-lines" iconType="solid" /> Open [Stream audio to a Dictation session](/api-reference/audio-transcription/stream-transcription) for the Dictation WebSocket handshake and message fields.

<Icon icon="file-lines" iconType="solid" /> Review [Audio capture and streaming FAQs](/api-reference/faqs/audio-capture-streaming) for codec, chunk size, and reconnect guidance.
