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

# End Dictation with AUDIO_END

> End Dictation WebSocket audio with EVENT AUDIO_END, wait for EOF, then end the Dictation session with REST

**Problem:** You copied an ambient streaming client and the Dictation stream never finishes.

**Solution:** On `/ws/transcribe`, send `{ "type": "AUDIO", "audioData": "<base64 pcm>" }` chunks, then `{ "type": "EVENT", "event": "AUDIO_END" }`. Wait for inbound `transcript.transcript === "EOF"`, close the socket, then call [End Dictation session](/api-reference/audio-transcription/end-session). Do not send ambient `RU9G`.

<Note>
  This cookbook assumes you already have your Partner ID, authentication tokens, and an active Dictation `transcription_session_id`.
</Note>

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    // After Dictation AUDIO chunks that use audioData (not ambient data):
    // ws.send(JSON.stringify({ type: "AUDIO", audioData: base64PcmChunk }));

    ws.send(JSON.stringify({ type: "EVENT", event: "AUDIO_END" }));

    await new Promise<void>((resolve, reject) => {
      ws.onmessage = (event) => {
        try {
          const payload = JSON.parse(String(event.data));
          if (payload?.transcript?.transcript === "EOF") {
            resolve();
          }
        } catch (err) {
          reject(err);
        }
      };
      ws.onerror = () => reject(new Error("WebSocket error while waiting for EOF"));
    });

    ws.close();

    const endRes = await fetch(
      `https://sdp.suki.ai/api/v1/transcription/session/${transcriptionSessionId}/end`,
      {
        method: "POST",
        headers: {
          sdp_suki_token: sdpSukiToken,
          sdp_provider_id: sdpProviderId,
        },
      }
    );
    if (!endRes.ok) {
      throw new Error(`End Dictation session failed: ${endRes.status}`);
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    import json
    import requests

    # After Dictation AUDIO chunks that use audioData (not ambient data):
    # ws.send(json.dumps({"type": "AUDIO", "audioData": base64_pcm_chunk}))

    ws.send(json.dumps({"type": "EVENT", "event": "AUDIO_END"}))

    while True:
        raw = ws.recv()
        payload = json.loads(raw)
        transcript = (payload.get("transcript") or {}).get("transcript")
        if transcript == "EOF":
            break

    ws.close()

    end = requests.post(
        f"https://sdp.suki.ai/api/v1/transcription/session/{transcription_session_id}/end",
        headers={
            "sdp_suki_token": sdp_suki_token,
            "sdp_provider_id": sdp_provider_id,
        },
    )
    end.raise_for_status()
    ```
  </Tab>
</Tabs>

## Common mistakes

* Send `{ "type": "AUDIO", "data": "RU9G" }` on Dictation. That marker is ambient-only.
* Close the socket or call REST end before you receive inbound **`EOF`**.
* Open `/ws/transcribe` again before the session returns to `READY` or `IDLE`.

## Other cookbooks

<div className="cookbook-hub-wrap">
  <div className="hp-io-method-grid tut-hub-card-grid" data-cookbook-related-grid>
    <a className="hp-io-method-card tut-hub-method-card" href="/documentation/cookbooks/browser-websocket-auth">
      <div className="tut-hub-card-media" aria-hidden="true" />

      <div className="hp-io-method-card-body">
        <div className="tut-hub-card-badges">
          <span className="hp-wn-badge hp-wn-badge-new">Ambient</span>
          <span className="hp-wn-badge cookbook-hub-badge-surface cookbook-hub-badge-surface--api">API</span>
        </div>

        <h3 className="hp-io-method-card-title">Authenticate Browser WebSocket Handshake</h3>

        <p className="hp-io-method-card-desc cookbook-hub-card-desc">
          Auth Dictation WebSocket with protocols.
        </p>

        <div className="hp-io-method-card-meta tut-hub-card-foot" aria-label="5 min">
          <div className="tut-hub-card-foot-meta">
            <span className="hp-io-method-card-meta-time">5 min</span>
          </div>
        </div>
      </div>
    </a>

    <a className="hp-io-method-card tut-hub-method-card" href="/documentation/cookbooks/dictation-onsubmit-chart-field">
      <div className="tut-hub-card-media tut-hub-card-media--blue" aria-hidden="true" />

      <div className="hp-io-method-card-body">
        <div className="tut-hub-card-badges">
          <span className="hp-wn-badge hp-wn-badge-new">Dictation</span>
          <span className="hp-wn-badge cookbook-hub-badge-surface cookbook-hub-badge-surface--sdk">SDK</span>
        </div>

        <h3 className="hp-io-method-card-title">Write Dictation Text to an EHR Field</h3>

        <p className="hp-io-method-card-desc cookbook-hub-card-desc">
          Write Dictation text with onSubmit.
        </p>

        <div className="hp-io-method-card-meta tut-hub-card-foot" aria-label="5 min">
          <div className="tut-hub-card-foot-meta">
            <span className="hp-io-method-card-meta-time">5 min</span>
          </div>
        </div>
      </div>
    </a>
  </div>
</div>
