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

# Authenticate Browser WebSocket Handshake

> Pass SukiAmbientAuth token and session ID in Sec-WebSocket-Protocol for browser clients

**Problem:** Browser WebSocket handshake returns **401** because you cannot set custom auth headers, or the protocol string is wrong.

**Solution:** Pass `Sec-WebSocket-Protocol` as `SukiAmbientAuth,<sdp_suki_token>,<session_id>` with the token before the session ID. Use `ambient_session_id` for Ambient (`/ws/stream`) or `transcription_session_id` for Dictation (`/ws/transcribe`). Do not use `SukiTranscriptionAuth`.

<Note>
  This cookbook assumes you already have a valid `sdp_suki_token` and an open ambient or Dictation session ID.
</Note>

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    // Ambient browser handshake
    const ambientWs = new WebSocket("wss://sdp.suki.ai/ws/stream", [
      `SukiAmbientAuth,${sdpSukiToken},${ambientSessionId}`,
    ]);

    // Dictation uses the same auth scheme, different path and session id
    const dictationWs = new WebSocket("wss://sdp.suki.ai/ws/transcribe", [
      `SukiAmbientAuth,${sdpSukiToken},${transcriptionSessionId}`,
    ]);

    ambientWs.onerror = () => {
      console.error("WebSocket error. Check protocol order: token before session id.");
    };
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    # Non-browser clients send headers instead of Sec-WebSocket-Protocol.
    import websocket

    # Ambient
    ambient_ws = websocket.create_connection(
        "wss://sdp.suki.ai/ws/stream",
        header=[
            f"sdp_suki_token: {sdp_suki_token}",
            f"ambient_session_id: {ambient_session_id}",
            # Optional for standard partners; required for Bearer / Single Auth:
            f"sdp_provider_id: {sdp_provider_id}",
        ],
        timeout=60,
    )

    # Dictation: use transcription_session_id (not ambient_session_id)
    dictation_ws = websocket.create_connection(
        "wss://sdp.suki.ai/ws/transcribe",
        header=[
            f"sdp_suki_token: {sdp_suki_token}",
            f"transcription_session_id: {transcription_session_id}",
            # Optional for standard partners; required for Bearer / Single Auth:
            f"sdp_provider_id: {sdp_provider_id}",
        ],
        timeout=60,
    )
    ```
  </Tab>
</Tabs>

## Common mistakes

* Put the session ID before the token in the protocol string.
* Use `SukiTranscriptionAuth` for Dictation. Both products use `SukiAmbientAuth`.

## 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/end-ambient-after-streaming">
      <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">End Ambient After Streaming</h3>

        <p className="hp-io-method-card-desc cookbook-hub-card-desc">
          Send RU9G, then end session.
        </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/end-dictation-with-audio-end">
      <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--api">API</span>
        </div>

        <h3 className="hp-io-method-card-title">End Dictation with AUDIO\_END</h3>

        <p className="hp-io-method-card-desc cookbook-hub-card-desc">
          Use AUDIO\_END, not ambient RU9G.
        </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>
