> ## 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 Basic Usage

> Learn how to create a transcription session, stream audio, receive transcripts, and end the session when capture is finished

<Info>
  **This guide covers:** Audio Dictation [REST and WebSocket APIs](/api-reference/audio-transcription/create-session).

  * For a **browser** app, use the [Web SDK for Audio Dictation](/web-sdk/dictation-overview) or the [Dictation SDK](/dictation-sdk/introduction) <Badge color="yellow" size="sm" icon="sparkles">Beta</Badge> instead of building this REST and WebSocket flow yourself.
  * For wire format, handshake rules, and troubleshooting, refer to the [Dictation streaming](/documentation/dictation-streaming) guide.
</Info>

This guide walks you through how to build a standalone Audio Dictation workflow with the Audio Dictation REST APIs. In this workflow, you:

* Create an Audio Dictation session
* Stream audio over WebSocket
* Receive transcript updates
* End the session when Dictation is complete

Before you start, register the provider and get an **`sdp_suki_token`**. Refer to [Provider authentication](/api-reference/provider-authentication) and [Partner authentication](/documentation/partner-authentication) for more information.

## How the Audio Dictation works

The dictation workflow uses both REST APIs and a WebSocket connection.

1. Authenticate and create a session with the REST API.
2. Stream audio to the session over WebSocket and process transcript updates.
3. End the session.

## Create a Dictation session

Create a parent transcription session before you open the WebSocket connection. The response includes a **`transcription_session_id`**, which identifies the session across the workflow.

Use the **`transcription_session_id`** when you:

* Connect to **`/ws/transcribe`**
* End the dictation session with [End dictation session](/api-reference/audio-transcription/end-session)

Call <Badge color="blue" size="sm">POST</Badge> [Create dictation session](/api-reference/audio-transcription/create-session):

```bash theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
curl --request POST \
  --url https://sdp.suki-stage.com/api/v1/transcription/session/create \
  --header 'Content-Type: application/json' \
  --header 'sdp_suki_token: <sdp_suki_token>' \
  --header 'sdp_provider_id: <sdp_provider_id>' \
  --data '{
    "audio_config": {
      "audio_encoding": "LINEAR16",
      "audio_language": "en-US",
      "sample_rate_hertz": 16000
    }
  }'
```

Example response:

```json theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{
  "transcription_session_id": "123dfg-456dfg-789dfg-012dfg"
}
```

The API returns **`201 Created`** when the session is created successfully.

### Request details

* Include **`sdp_suki_token`** in every REST request and during the WebSocket handshake.
* **`transcription_session_id`** is optional in the create request. If you omit it, Suki generates one.
* **`audio_config`** is optional.
* **`audio_encoding`** must be **`LINEAR16`**.

## Stream audio over WebSocket

After you create the session, connect to <Badge color="green" size="sm">GET</Badge> **`wss://sdp.suki-stage.com/ws/transcribe`** when the session is **`READY`** or **`IDLE`**.

If the session is already **`RUNNING`**, **`COMPLETED`**, or in another state, the WebSocket handshake fails with **`FailedPrecondition`**.
For push-to-talk workflows that use multiple speech sessions with the same transcription\_session\_id, refer to [Dictation streaming](/documentation/dictation-streaming) for more information.

<Tip>
  Authenticate during the WebSocket handshake instead of sending credentials with each message.
</Tip>

### Authentication

For non-browser clients, send these headers during the upgrade request:

* `sdp_suki_token`
* `transcription_session_id`

For browser clients, use **`Sec-WebSocket-Protocol`**:

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

### Send audio messages

Send audio data as JSON text frames.

Example audio message:

```json theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{ "type": "AUDIO", "audioData": "<base64-encoded PCM_S16LE bytes>" }
```

After you finish streaming audio on the connection, send:

```json theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{ "type": "EVENT", "event": "AUDIO_END" }
```

### Streaming requirements

* Send one JSON object per WebSocket **`send`**.
* Do not send raw binary frames.
* Use **`audioData`** for dictation audio payloads.
* Base64-encode **PCM\_S16LE** audio bytes in **`audioData`**.
* Do not use ambient streaming fields such as **`data`** or **`RU9G`**.

For wire format details, refer to [Dictation streaming](/documentation/dictation-streaming).

### Receive transcript events

Parse transcript messages from **`event.data`** in your WebSocket **`onmessage`** handler. Refer to [Stream audio to dictation session](/api-reference/audio-transcription/stream-transcription) for Python and TypeScript code examples, and [Dictation streaming](/documentation/dictation-streaming) for partial and final frames, **`EOF`**, and filtering rules.

Example partial frame:

```json theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{
  "transcript": {
    "transcript": "the recognized text so far",
    "words": []
  },
  "is_final": false,
  "transcript_id": "01J9XABCDEFGHJKMNPQRSTVWXYZ" // example transcript_id
}
```

Example final frame:

```json theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{
  "transcript": {
    "transcript": "The patient reports feeling better today",
    "words": [
      { "word": "The", "speaker": { "id": "S1" } },
      { "word": "patient", "speaker": { "id": "S1" } }
    ]
  },
  "is_final": true,
  "transcript_id": "01J9XWXYZABCDEFGHJKMNPQRSTUV" // example transcript_id
}
```

* **`is_final: false`**: partial (interim) text that may change in later messages.
* **`is_final: true`**: final text for that segment; the recognizer will not revise it.
* After the speech stream ends, the server sends **`{ "transcript": { "transcript": "EOF" } }`**. Treat that as end-of-results for that WebSocket; the connection closes shortly after.

<Note>
  Do not dedupe messages by **`transcript_id`**. The server assigns a new ID per frame, including partials.
</Note>

## End the Dictation session

When Dictation is complete:

1. Send **`AUDIO_END`**
2. Close the WebSocket connection
3. End the session with the REST API

Call <Badge color="blue" size="sm">POST</Badge> [End Dictation session](/api-reference/audio-transcription/end-session):

```bash theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
curl --request POST \
  --url https://sdp.suki-stage.com/api/v1/transcription/session/<transcription_session_id>/end \
  --header 'sdp_suki_token: <sdp_suki_token>' \
  --header 'sdp_provider_id: <sdp_provider_id>'
```

Example response:

```json theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{
  "transcription_session_id": "123dfg-456dfg-789dfg-012dfg",
  "status": "completed",
  "final_transcript": "The patient reports feeling better today. Blood pressure is stable at 120/80.",
  "duration": 300,
  "ended_at": "2024-11-26T10:35:00Z"
}
```

The API returns **`200 OK`** on success.

Possible **`status`** values include:

* **`completed`**
* **`cancelled`**
* **`failed`**

Use **`final_transcript`** as the complete transcript for the session.

## Common integration patterns

### Pattern 1: Standard Audio Dictation flow

A typical Audio Dictation workflow follows these steps:

<Steps>
  <Step title="Authenticate">
    Obtain an **`sdp_suki_token`** for the provider.
  </Step>

  <Step title="Create the session">
    Call [Create dictation session](/api-reference/audio-transcription/create-session) and save the **`transcription_session_id`**.
  </Step>

  <Step title="Stream audio">
    Open a WebSocket connection to **`/ws/transcribe`** when the session is **`READY`** or **`IDLE`**. Send **`AUDIO`** messages, handle partial and final inbound frames, and finish with **`AUDIO_END`**.
  </Step>

  <Step title="Process transcripts">
    Update the UI with partial and final transcript updates from incoming WebSocket messages.
  </Step>

  <Step title="End the session">
    Call [End dictation session](/api-reference/audio-transcription/end-session) and store the final transcript output.
  </Step>
</Steps>

### Pattern 2: Push-to-talk or reconnect

For push-to-talk, open **`/ws/transcribe`** when the session is **`READY`** or **`IDLE`**, stream one utterance, send **`AUDIO_END`**, wait for **`EOF`**, then close the WebSocket. When the session is **`READY`** or **`IDLE`** again, open a new WebSocket on the same **`transcription_session_id`** for the next utterance.

If a connection drops mid-utterance, open a new WebSocket with the same **`transcription_session_id`** and **`sdp_suki_token`** only when the session accepts a new speech session. End the parent session with REST only when the full dictation workflow is complete.

### Pattern 3: Configure audio settings

Pass **`audio_config`** in the create request when you need to specify:

* Audio encoding
* Language
* Sample rate

Ensure that the streamed audio format matches the configuration you provide.

### Pattern 4: Stream audio in chunks

For lower latency, send smaller **`AUDIO`** messages as audio becomes available instead of buffering the entire recording.

After the final audio chunk, send **`AUDIO_END`**.

## What you can build

<CardGroup cols={2}>
  <Card title="Live Dictation Experiences" icon="microphone">
    Display partial and final transcript updates in real time while the provider speaks.
  </Card>

  <Card title="Server-side Transcription Pipelines" icon="server">
    Capture audio on a backend service, stream it through **`/ws/transcribe`**, and store the final transcript output.
  </Card>

  <Card title="Telehealth and In-person Workflows" icon="video">
    Add transcription workflows to virtual or in-person clinical experiences without ambient note generation.
  </Card>

  <Card title="EHR and Form Integrations" icon="file-lines">
    Send transcript output into forms, notes, or downstream clinical systems after the session ends.
  </Card>
</CardGroup>

## Related API references

<CardGroup cols={3}>
  <Card title="Create Dictation Session" icon="code" href="/api-reference/audio-transcription/create-session" arrow={true}>
    Create a transcription session
  </Card>

  <Card title="Stream Audio for Dictation" icon="wifi" href="/api-reference/audio-transcription/stream-transcription" arrow={true}>
    Connect and stream audio over WebSocket
  </Card>

  <Card title="End Dictation Session" icon="circle-xmark" href="/api-reference/audio-transcription/end-session" arrow={true}>
    End a Dictation session
  </Card>
</CardGroup>

## Best practices

<Tip>
  * **Stream audio in small chunks** to reduce latency.
  * **Reuse the same `transcription_session_id`** when reconnecting WebSocket sessions.
  * **End sessions** after dictation completes to release resources.
  * **Match streamed audio settings** to your configured sample rate and encoding.
  * **Validate audio quality** before production deployment.
</Tip>

## FAQs

<Accordion title="What's the difference between Audio Dictation and Clinical Documentation?">
  | Feature                        | Description                                                                                  |
  | :----------------------------- | :------------------------------------------------------------------------------------------- |
  | Audio Dictation                | Converts speech into transcript text with formatting such as punctuation and capitalization. |
  | Ambient clinical documentation | Transcribes conversations and generates structured clinical documentation outputs.           |
</Accordion>

<Accordion title="How is /ws/transcribe different from ambient /ws/stream?">
  Dictation uses **`/ws/transcribe`** with **`audioData`** payloads and **`AUDIO_END`** events.

  Ambient clinical documentation uses **`/ws/stream`** with different authentication flows and message formats.

  For more information, refer to [Audio streaming](/documentation/audio-stream) and [Dictation streaming](/documentation/dictation-streaming).
</Accordion>
