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

# 手動コミットによる ElevenLabs からの移行

このガイドでは、`commit_strategy=manual` で使用している ElevenLabs Realtime Speech to Text からの移行について説明します。

<Card horizontal title="すべての移行ガイド" icon="arrow-left-from-arc" href="/ja-jp/use-the-api/stt/migrations" />

このガイドには、素の API の説明と SDK コードの両方が含まれています。SDK をインストールするには次のようにします。

<CodeGroup>
  ```bash Python theme={null}
  pip install cartesia
  ```

  ```bash TypeScript theme={null}
  npm i @cartesia/cartesia-js
  ```
</CodeGroup>

<Info>
  すでに Cartesia SDK を使用している場合は、バージョン `>=3.2.0` にアップグレードしてください
</Info>

## 接続

ElevenLabs の WebSocket URL と認証ヘッダーを Cartesia の `/stt/websocket` に置き換えます。

```diff theme={null}
- wss://api.elevenlabs.io/v1/speech-to-text/realtime?model_id=scribe_v2_realtime&audio_format=pcm_16000&commit_strategy=manual
+ wss://api.cartesia.ai/stt/websocket?model=ink-2&encoding=pcm_s16le&sample_rate=16000
```

```diff theme={null}
- xi-api-key: <ELEVENLABS_API_KEY>
+ x-api-key: <CARTESIA_API_KEY>
+ cartesia-version: 2026-03-01
```

ブラウザでは、WebSocket はリクエストヘッダーをサポートしていません。代わりに、API バージョンを `cartesia_version` クエリパラメーターとして渡し、API キーの代わりに `access_token` クエリパラメーターで短命の[アクセストークン](/get-started/authenticate-your-client-applications)を使用してください。

Cartesia SDK で手動ファイナライズ用の WebSocket に接続します。

<CodeGroup>
  ```python Python theme={null}
  import os
  from cartesia import AsyncCartesia

  client = AsyncCartesia(api_key=os.getenv("CARTESIA_API_KEY"))

  async with client.stt.manual_finalize.websocket(
      model="ink-2", encoding="pcm_s16le", sample_rate=16000
  ) as connection:
      ...
  ```

  ```typescript TypeScript theme={null}
  import Cartesia from "@cartesia/cartesia-js";

  const client = new Cartesia({ apiKey: process.env.CARTESIA_API_KEY });

  const connection = client.stt.manualFinalize.websocket({
    model: "ink-2",
    encoding: "pcm_s16le",
    sample_rate: 16000,
  });
  ```

  ```typescript TypeScript (Browser) theme={null}
  // Server-side: Generate access-tokens using your API key
  import Cartesia from '@cartesia/cartesia-js';

  const client = new Cartesia({ apiKey: process.env.CARTESIA_API_KEY });

  export async function GET() {
    const { token } = await client.accessToken.create({
      grants: { stt: true, tts: false, agent: false },
      // How long the token lasts in seconds
      // Allowed values: 0–3600
      expires_in: 3600,
    });
    return Response.json({ token });
  }


  // Client-side
  // 1. Fetch an access token from your server
  // 2. Connect to Cartesia via WebSocket
  import Cartesia from "@cartesia/cartesia-js";

  async function getToken(): Promise<string> {
    const res = await fetch('/replace-with-your-server');
    const { token } = await res.json();
    return token;
  }
  const audioContext = new AudioContext();

  const client = new Cartesia({ token: await getToken() });

  const connection = client.stt.manualFinalize.websocket({
    model: "ink-2",
    encoding: "pcm_f32le",
    sample_rate: audioContext.sampleRate,
  });
  ```
</CodeGroup>

## クエリパラメーター

| ElevenLabs Scribe（手動）                                                       | Cartesia Realtime STT（手動）                                                                | 備考                                                                                                                 |
| --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `model_id=scribe_v2_realtime` <Badge color="red" size="sm">required</Badge> | `model=ink-2` <Badge color="red" size="sm">required</Badge>                              | すべての選択肢については[モデル](/build-with-cartesia/stt/latest)を参照してください。                                                       |
| `audio_format=pcm_16000`                                                    | `encoding=pcm_s16le` + `sample_rate=16000` <Badge color="red" size="sm">required</Badge> | ElevenLabs はフォーマットとレートをまとめていますが、Cartesia はこれらを分離しています。[エンコーディング](#encoding)を参照してください。                              |
| `commit_strategy=manual`                                                    | —                                                                                        | 自動コミットについては[自動ファイナライズ](/use-the-api/stt/migrate-from-elevenlabs-realtime-speech-to-text/auto)を参照してください。            |
| `language_code`                                                             | `language`                                                                               | `ink-2` は現在 `en` のみをサポートしています。[他の言語](/build-with-cartesia/stt/older-models#ink-whisper)には `ink-whisper` を使用してください。 |
| —                                                                           | `cartesia_version=2026-03-01` <Badge color="red" size="sm">required</Badge>              | 詳細は [API 規約](/use-the-api/api-conventions#always-send-a-cartesia-version-header)を参照してください。                         |
| `include_timestamps`                                                        | —                                                                                        | モデルがサポートしている場合は常に含まれます（現時点では `ink-whisper` のみ）。                                                                    |
| `keyterms`                                                                  | `keyterm`                                                                                | 単数形の `keyterm` に注意してください。[キータームプロンプティング](/use-the-api/stt/keyterms)を参照してください。                                      |
| `enable_logging`                                                            | —                                                                                        | 組織によって制御されます。                                                                                                      |

<Accordion title="encoding">
  ElevenLabs はサンプル形式とレートを 1 つの `audio_format` トークンにまとめています。Cartesia はこれらを `encoding` と `sample_rate` に分けています。

  | ElevenLabs `audio_format` | Cartesia `encoding` | Cartesia `sample_rate` |
  | ------------------------- | ------------------- | ---------------------- |
  | `pcm_8000`                | `pcm_s16le`         | `8000`                 |
  | `pcm_16000`               | `pcm_s16le`         | `16000`                |
  | `pcm_22050`               | `pcm_s16le`         | `22050`                |
  | `pcm_24000`               | `pcm_s16le`         | `24000`                |
  | `pcm_44100`               | `pcm_s16le`         | `44100`                |
  | `pcm_48000`               | `pcm_s16le`         | `48000`                |
  | `ulaw_8000`               | `pcm_mulaw`         | `8000`                 |

  Cartesia は `pcm_s32le`、`pcm_f16le`、`pcm_f32le`、`pcm_alaw` も受け付けます。\
  Cartesia のすべてのエンコーディングは、すべてのサンプルレートに対応しています。
</Accordion>

## 音声の送信

ElevenLabs は各音声チャンクを JSON 形式のテキストフレームでラップし、音声バイトを base64 エンコードします。\
Cartesia は音声チャンクをバイナリフレームとして受け取ります。生の音声バイトを直接送信してください。

```diff theme={null}
- { "message_type": "input_audio_chunk", "audio_base_64": "<base64 PCM>", "commit": false, "sample_rate": 16000 }
+ <raw PCM bytes>
```

> * 以前のテキストを渡す必要はありません
> * サンプルレートは接続時に `sample_rate` クエリパラメーターによって決定されます

Cartesia の制御コマンドは JSON ではなく、プレーンなテキストフレームです。

バッファ済みの音声をコミットし、セッションを終了せずにトランスクリプトを出力するには、`finalize` フレームを送信します。

```text theme={null}
finalize
```

| ElevenLabs                                                                | Cartesia                                                                              |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `partial_transcript` イベントをストリーミングし、コミットすると `committed_transcript` を送信します。 | **確定トランスクリプトのデルタを音声の到着に合わせて継続的にストリーミングします**。`finalize` は、数秒間保留される可能性のあるテキストをフラッシュします。 |

<Warning>
  音声ストリームの適切なタイミングで `finalize` コマンドを送信することが重要です。

  ユーザーがいつ話し終えるかわからない場合は、[自動ファイナライズ](./auto)の使用を検討してください。
</Warning>

残りのすべての音声をコミットしてセッションを閉じるには、`close` フレームを送信します。

```text theme={null}
close
```

Cartesia はバッファ済みのすべての音声を文字起こしした後、ソケットを閉じます。

### SDK での音声の送信

<CodeGroup>
  ```python Python theme={null}
  # ElevenLabs
  await elevenlabs_connection.send({
    "audio_base_64": b64encode(raw_audio),
  })

  # Cartesia
  # raw_audio (bytes) - Raw audio data, about 100 ms at a time
  await connection.send_raw(raw_audio)
  ```

  ```typescript TypeScript theme={null}
  // ElevenLabs
  elevenLabsConnection.send({ audioBase64: rawAudio.toBase64() })

  // Cartesia
  // @param {ArrayBufferLike} rawAudio - raw audio data, about 100 ms at a time
  connection.sendRaw(rawAudio);
  ```
</CodeGroup>

### 送信前に base64 エンコードされた音声をデコードする

<CodeGroup>
  ```python Python theme={null}
  # ElevenLabs
  await elevenlabs_connection.send({
    "audio_base_64": audio_base_64,
  })

  # Cartesia
  from base64 import b64decode
  await connection.send_raw(b64decode(audio_base_64))
  ```

  ```typescript TypeScript theme={null}
  // ElevenLabs
  elevenLabsConnection.send({ audioBase64 });

  // Cartesia
  connection.sendRaw(Uint8Array.fromBase64(audioBase64));
  ```
</CodeGroup>

### コミットとクローズ

<CodeGroup>
  ```python Python theme={null}
  # ElevenLabs
  await elevenlabs_connection.commit()

  # Cartesia
  await connection.send("finalize")

  # ElevenLabs: close the socket immediately
  await elevenlabs_connection.close()

  # Cartesia: commit remaining audio
  # and let the server close the socket once done
  await connection.send("close")

  # Cartesia: Close the socket early (optional)
  await connection.close()
  ```

  ```typescript TypeScript theme={null}
  // ElevenLabs
  elevenLabsConnection.commit();

  // Cartesia
  connection.send("finalize");

  // ElevenLabs: close the socket immediately
  elevenLabsConnection.close();

  // Cartesia: commit remaining audio
  // and let the server close the socket once done
  connection.send("close");

  // Cartesia: Close the socket early (optional)
  connection.close();
  ```
</CodeGroup>

## イベントのマッピング

Scribe は中間の `partial_transcript` イベントを送信し、コミットすると `committed_transcript` を送信します。\
Cartesia は `transcript` デルタに加えて、`finalize` および `close` コマンドの確認応答を送信します。

| ElevenLabs `message_type`              | Cartesia `type`                               | 備考                                                                                                                                |
| -------------------------------------- | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `partial_transcript`                   | `transcript`（`is_final: false`）               | Ink 2 と Whisper では送信されません（将来のモデル向けに予約）。                                                                                           |
| `committed_transcript`                 | `transcript`（`is_final: true`） + `flush_done` | ElevenLabs は確定トランスクリプトを 1 つのメッセージで送信します。Cartesia はデルタを含む `transcript` メッセージを送信し、そのセグメントのすべてのデルタを送信し終えると `flush_done` メッセージを送信します。 |
| `committed_transcript_with_timestamps` | `transcript`（`is_final: true`） + `flush_done` | 現時点でタイムスタンプをサポートするのは `ink-whisper` のみです。                                                                                          |
| —                                      | `done`                                        | `close` までのすべての音声が文字起こしされた後、WebSocket が閉じる直前に送信されます。                                                                              |
| `error`                                | `error`                                       | クライアントまたはサーバーのエラー。                                                                                                                |
| `auth_error`                           | —                                             | Cartesia は WebSocket のアップグレードを HTTP ステータス 401 または 403 で拒否します。                                                                     |
| `quota_exceeded`                       | `error`                                       | Cartesia のエラーレスポンスには `"error_code": "quota_exceeded"` が含まれます。                                                                     |
| `rate_limited`                         | `error`                                       | Cartesia のエラーレスポンスには `"error_code": "concurrency_limited"` が含まれます。                                                                |
| `session_time_limit_exceeded`          | —                                             | Cartesia はコード `1001` の WebSocket クローズフレームを送信します。                                                                                  |

### 確定トランスクリプト

Scribe の `committed_transcript` は、直前のコミット以降のセグメントの**完全なテキスト**を保持します。

```json theme={null}
{
  "message_type": "committed_transcript",
  "text": "Hello world! This is the full transcript."
}
```

これは、それぞれが**デルタ**を保持する 1 つ以上の Cartesia `transcript` イベントになります。

```json theme={null}
{
  "type": "transcript",
  "is_final": true,
  "text": "Hello world!",
  "duration": 0.5,
  "words": [
    {
      "word": "Hello",
      "start": 0,
      "end": 0.2
    },
    {
      "word": " world!",
      "start": 0.2,
      "end": 0.5
    }
  ],
  "request_id": "2ff8af53-4d38-479d-8287-58940f01c701"
}
```

> * Ink 2 はまだ `duration` や `words` を返しません
> * Ink 2 と Whisper は現在、確定トランスクリプト（`is_final: true`）のみを送信します

続いて Cartesia の `flush_done` イベントが送信されます。

```json theme={null}
{
  "type": "flush_done",
  "is_final": false,
  "request_id": "2ff8af53-4d38-479d-8287-58940f01c701"
}
```

> `flush_done` および `done` イベントの `is_final` プロパティは無視してください

<Tip>Cartesia の確定トランスクリプトは**デルタ**です。空白を除去したり追加したりせずに連結してください。</Tip>

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from cartesia.types.stt import STTManualFinalizeWebsocketResponse

  partial_transcript = ""

  def on_message(message: STTManualFinalizeWebsocketResponse) -> None:
      global partial_transcript
      if message.type == "transcript" and message.is_final:
          # Do not strip or add whitespace!
          partial_transcript += message.text
          print(f"partial_transcript: {partial_transcript}")
      elif message.type == "flush_done" or message.type == "done":
          print(f"committed_transcript: {partial_transcript}")
          partial_transcript = ""
      elif message.type == "error":
          error_code = message.error_code or "unknown_error"
          if error_code == "quota_exceeded":
              print("You are out of credits")
          elif error_code == "concurrency_limited":
              print("You have too many open STT connections")
          else:
              print(f"{error_code}: {message.message}")

  connection.on("event", on_message)

  # ElevenLabs dispatches to your callbacks automatically;
  # with Cartesia you run the dispatch loop yourself
  recv_task = asyncio.create_task(connection.dispatch_events())
  ```

  ```typescript TypeScript theme={null}
  import Cartesia from '@cartesia/cartesia-js';

  let partialTranscript = '';

  connection.on("event", (message: Cartesia.STT.ManualFinalize.STTManualFinalizeWebsocketResponse) => {
    switch (message.type) {
      case "transcript":
        if (message.is_final) {
          // Do not trim or add whitespace!
          partialTranscript += message.text;
          console.log(`partial_transcript: ${partialTranscript}`);
        }
        break;
      case "flush_done":
      case "done":
        console.log(`committed_transcript: ${partialTranscript}`);
        partialTranscript = '';
        break;
    }
  });

  connection.on("error", (error) => {
    if (error.error) {
      // Server sent error (may be a bad request or internal server error)
      const errorCode = error.error.error_code || "unknown_error";
      switch (errorCode) {
        case "quota_exceeded":
          console.error("You are out of credits");
          break;
        case "concurrency_limited":
          console.error("You have too many open STT connections");
          break;
        default:
          console.error(`${errorCode}: ${error.error.message}`);
          break;
      }
    } else {
      // Client error
      console.error(`Client had an error: ${error.message}`);
    }
  });

  connection.on("close", (code: number, reason: string) => {
    if (code === 1001) {
      console.log("WebSocket closed due to inactivity");
    } else {
      console.log(`WebSocket closed (${code}): ${reason}`);
    }
  });
  ```
</CodeGroup>

## サーバーメッセージの例

> Scribe は完全なトランスクリプトを送信します。Ink はデルタを送信し、単語の途中で区切ることがあります。

| ElevenLabs Scribe（手動）                                                                                          | Cartesia Realtime STT（手動）                                                  |
| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| <Badge color="orange">partial\_transcript</Badge> `"Scribe sends"`                                             | <Badge color="green">is\_final: true</Badge> `"Scribe sends"`              |
| <Badge color="orange">partial\_transcript</Badge> `"Scribe sends full transcripts."`                           | <Badge color="green">is\_final: true</Badge> `" full transc"`              |
| <Badge>commit</Badge> *(client)*                                                                               | <Badge>finalize</Badge> *(client)*                                         |
| <Badge color="green">committed\_transcript</Badge> `"Scribe sends full transcripts."`                          | <Badge color="green">is\_final: true</Badge> `"ripts."`                    |
| <Badge color="green">committed\_transcript\_with\_timestamps</Badge> `"Scribe sends full transcripts."`        | <Badge>flush\_done</Badge>                                                 |
| <Badge color="orange">partial\_transcript</Badge> `"Ink sends deltas"`                                         | <Badge color="green">is\_final: true</Badge> `" Ink sends"`                |
| <Badge color="orange">partial\_transcript</Badge> `"Ink sends deltas and may break words."`                    | <Badge color="green">is\_final: true</Badge> `" deltas and may break wor"` |
| <Badge>commit</Badge> *(client)*                                                                               | <Badge>finalize</Badge> *(client)*                                         |
| <Badge color="green">committed\_transcript</Badge> `"Ink sends deltas and may break words."`                   | <Badge color="green">is\_final: true</Badge> `"ds."`                       |
| <Badge color="green">committed\_transcript\_with\_timestamps</Badge> `"Ink sends deltas and may break words."` | <Badge>flush\_done</Badge>                                                 |

## リファレンス

<CardGroup cols={2}>
  <Card icon="code" title="API リファレンス" href="/api-reference/stt/websocket">
    Cartesia Realtime STT (Manual)
  </Card>

  <Card icon="brackets-curly" title="完全なコード例" href="/examples/stt-manual-finalize-websocket">
    Cartesia SDK を使用
  </Card>
</CardGroup>
