> ## 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.

# Dictation Session Streaming

> Stream audio to an active Dictation session for real-time transcription

Use this WebSocket endpoint to stream audio to an active <Tooltip tip="The process of speaking aloud to create written text, often used by clinicians to create medical documentation using voice input." cta="View in Glossary" href="/Glossary/d">Dictation</Tooltip> session for **real-time transcription**.

## Related guides

<Columns col={2}>
  <Card title="Dictation Implementation Guide" icon="book" href="/documentation/concepts/dictation/dictation" horizontal />

  <Card title="Dictation Streaming Wire Format" icon="book" href="/documentation/how-to/audio-streaming/websocket-streaming-wire-format-dictation" horizontal />

  <Card title="Read Transcript Frames from Dictation Session" icon="book" href="/documentation/how-to/audio-streaming/dictation-streaming-transcripts" horizontal />

  <Card title="Audio Streaming vs Dictation Streaming" icon="book" href="/documentation/how-to/audio-streaming/audio-stream" horizontal />
</Columns>

## Prerequisites

Complete these steps **before** opening the WebSocket.

<Warning>
  Opening `/ws/transcribe` while another speech session is still finishing often leads to handshake failures (**`FailedPrecondition`**). After **`AUDIO_END`** and **`EOF`**, wait about **5 seconds** before you open the next WebSocket. Refer to [Stream Dictation audio](/documentation/how-to/audio-streaming/dictation-streaming) guide for more information.
</Warning>

* **Authenticate** and obtain `sdp_suki_token`.
* **Create a Dictation session** with <Badge color="blue" size="sm">POST</Badge> [`/api/v1/transcription/session/create`](/api-reference/audio-transcription/create-session). A successful create returns **201 Created**; keep the `transcription_session_id` from the response.
* **Authenticate and open the WebSocket** on `wss://sdp.suki-stage.com/ws/transcribe`. To stream audio, you must first establish an **authenticated** WebSocket connection. The authentication method you use depends on your client type: browser or non-browser.

<Tip>
  - Stream audio in **chunks** for the best latency and throughput.
  - For partial and final inbound transcript frames, **`EOF`**, and session state rules, refer to [Dictation transcript frames](/documentation/how-to/audio-streaming/dictation-streaming-transcripts).
</Tip>

## Inbound transcript messages

The server sends **JSON text frames** with top-level `transcript`, `is_final`, `transcript_id`, and `lang_id`. Use snake\_case **`is_final`** to identify whether the
transcript is a partial result or a final result. After the audio stream ends, the server sends `{ "transcript": { "transcript": "EOF" } }` and then closes the WebSocket connection.

<Tip>
  Refer to [Read Dictation transcript frames](/documentation/how-to/audio-streaming/dictation-streaming-transcripts) for frame examples, **`words`** and speaker IDs on finals, and client-side filtering rules.
</Tip>

## Authentication

Authentication is applied during the WebSocket handshake. The method depends on your client type. Use the `Sec-WebSocket-Protocol` header for browser clients, and `sdp_suki_token` and `transcription_session_id` headers for non-browser clients.

### Browser clients

If you are connecting from a browser, you must use the `Sec-WebSocket-Protocol` header during the WebSocket handshake.

The header must specify the `SukiAmbientAuth` protocol, followed by the **token** and the **transcription session ID** in the following format.

```bash theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
Sec-WebSocket-Protocol: SukiAmbientAuth,<sdp_suki_token>,<transcription_session_id>
```

### Non-browser clients

If you are connecting from a non-browser client, such as a mobile or server-side application, you must provide the **token** and **session ID** as separate HTTP headers in the initial WebSocket upgrade request.

* `sdp_suki_token`: Session token from login.
* `sdp_provider_id`: Provider identifier. Optional for standard partners; **Required** for Single Auth Token authentication.
* `transcription_session_id`: The ID for the current session.

<Warning>
  Important:

  * All messages must be sent as **JSON text** frames over the WebSocket connection.
  * Do not send raw binary data or use HTTP endpoints for streaming audio.
</Warning>

## Full code examples

For end-to-end Dictation streaming examples, start with these tutorials:

<div className="doc-guide-btn-row">
  <a href="/documentation/tutorials/dictation-websocket-code-example" className="doc-guide-btn">
    Build Dictation Streaming Client
  </a>

  <a href="/documentation/tutorials/overview" className="doc-guide-btn">
    All Tutorials
  </a>
</div>


## OpenAPI

````yaml GET /ws/transcribe
openapi: 3.0.1
info:
  title: Suki Developer Platform
  description: >-
    REST and WebSocket APIs for the Suki Developer Platform. Authenticate with
    Login or Register to obtain a Suki access token, then integrate ambient
    clinical documentation, form filling, transcription, and reference metadata
    endpoints.
  contact: {}
  version: '1.0'
servers:
  - url: https://sdp.suki.ai
    description: >-
      Production base URL for Suki Developer Platform REST APIs. WebSocket
      endpoints use the same host with `wss://`.
security:
  - SukiTokenAuth: []
paths:
  /ws/transcribe:
    get:
      tags:
        - /ws
      summary: Stream audio for transcription
      description: >-
        Opens a WebSocket to stream audio for real-time transcription. Browser
        clients authenticate with the `Sec-WebSocket-Protocol` header;
        non-browser clients send `sdp_suki_token` and `transcription_session_id`
        as HTTP headers on the upgrade request.
      parameters:
        - name: Sec-WebSocket-Protocol
          in: header
          description: >-
            Required FOR BROWSER CLIENTS ONLY. Sent during WebSocket handshake.
            Browsers must use the same subprotocol the grpc-wsproxy maps to
            Authorization:
            'SukiAmbientAuth,<sdp_suki_token>,<transcription_session_id>'
            (comma-separated; token second, transcription session id third).
            Other names (e.g. SukiTranscriptionAuth) are not mapped and
            typically yield 401.
          schema:
            type: string
        - name: transcription_session_id
          in: header
          description: >-
            Required for non-browser clients only. UUID from Create
            Transcription Session.
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/ProviderIdHeader'
      responses:
        '101':
          description: Switching Protocols - Indicates successful WebSocket handshake.
          content:
            application/json:
              schema:
                type: string
        '200':
          description: >-
            OK - May indicate successful stream processing or completion (e.g.,
            sending 'EOF' message). Specific meaning depends on implementation
            after handshake.
          content:
            application/json:
              schema:
                type: string
        '400':
          description: Bad Request - Invalid parameters, headers, or request format.
          content:
            application/json:
              schema:
                type: string
        '401':
          description: >-
            Unauthorized - Authentication failed (invalid token/session,
            incorrect protocol/headers).
          content:
            application/json:
              schema:
                type: string
        '403':
          description: >-
            Forbidden - Client is authenticated but not authorized for this
            action.
          content:
            application/json:
              schema:
                type: string
        '500':
          description: Internal Server Error - Abnormal closure or server-side issue.
          content:
            application/json:
              schema:
                type: string
      security:
        - SukiTokenAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request GET \
              --url https://sdp.suki.ai/ws/transcribe \
              --header 'sdp_suki_token: <sdp_suki_token>' \
              --header 'sdp_provider_id: <sdp_provider_id>' \
              --header 'transcription_session_id: <transcription_session_id>'
components:
  parameters:
    ProviderIdHeader:
      name: sdp_provider_id
      in: header
      description: >-
        **Optional** for standard partners.


        **Required** for:


        - **Bearer authentication.** Use the same `provider_id` returned by the
        Login or Register API.

        - **Single Auth Token authentication.** Include the same `provider_id`
        on every request as `sdp_provider_id`.
      required: false
      schema:
        type: string
        example: provider-123
  securitySchemes:
    SukiTokenAuth:
      type: apiKey
      in: header
      name: sdp_suki_token
      description: >-
        Suki access token (`suki_token`) from Login or Register. Expires after
        one hour.

````