機能比較
| 1 接続あたりの複数生成 | タイムスタンプ | 継続 | |
|---|---|---|---|
| WebSocket | はい | はい | はい |
| Bytes | いいえ(生成ごとに 1 回 POST) | いいえ | いいえ |
| SSE | いいえ(生成ごとに 1 回 POST) | はい | いいえ |
context_id を共有する複数の WebSocket メッセージとして送信できます。詳細は 継続を使った入力ストリーミング と contexts を参照してください。
毎ターンの time-to-first-byte が重要な場合、新しい HTTPS リクエストは TCP と TLS のコストを再度払うことを忘れないでください。そのオーバーヘッドは、音声自体の TTFB と同程度の桁数になることがよくあります。WebSocket はソケットを開いたままにすることで、そのコストを償却します。
SSE は、すでに Server-Sent Events を扱っているスタックや、HTTP のままタイムスタンプが必要な場合のためにサポートを継続しています。音声のみの場合は、bytes の方が通常 HTTP の選択肢として優れています(JSON ラップされたチャンクより小さいエンコーディング)。
1 分でエンドポイントを選ぶ
| 作っているもの | 使うもの | 短いラベル |
|---|---|---|
| 完全なトランスクリプトを 1 リクエストで送信し、ストリーミング HTTP ボディが欲しい(効率的、プレイグラウンドと同じパターン) | POST /tts/bytes | Stream speech (bytes) |
| 完全なトランスクリプトを 1 リクエストで送信し、WebSocket なしでタイムスタンプが必要、またはスタックが既に SSE を使っている | POST /tts/sse | Stream speech with timestamps (SSE) |
| 長時間セッション、部分的なトランスクリプト(例: LLM トークン)、多数のターンにわたる最低レイテンシー、タイムスタンプ、または 1 ソケット上の複数発話 | WebSocket /tts/websocket | Live session (WebSocket) |
Bytes (POST /tts/bytes)
バッチジョブ、ファイルキャッシュ、通知、生成あたり 1 回の POST で十分なあらゆる用途に最適です。
レスポンスボディは音声が生成されると同時にストリーミングされます。逐次的に読むことも、最後までバッファすることもできます。多くの出力フォーマットでは、JSON ラップされたチャンクではなく生または file bytes を受け取るため、SSE よりも転送データ量が少なくなります。
典型的なフロー:
- 完全な
transcript、ボイス、モデル、出力フォーマット(WAV、MP3、raw PCM など)を含む 1 つの JSON ペイロード。 /tts/bytesにPOSTする。- データが到着するに従ってボディを読むか、完了まで消費する。
POST を送信します。
bytes リファレンス を参照してください。
SSE (POST /tts/sse)
WebSocket なしで HTTP のままタイムスタンプが必要な場合、またはインテグレーションがすでに SSE を使っている場合に最適です。音声のみ必要で SSE 形式のイベントが不要な場合は、bytes の方が通常シンプルです。それ以外の場合、WebSocket がリアルタイム用途における全機能対応のオプションであり、タイムスタンプもサポートしています。
SSE は主に下位互換性のため、および Server-Sent Events で標準化しているチームのために提供されています。
典型的なフロー:
- bytes と同じ: 完全なトランスクリプトを含む 1 つの JSON ボディ。
/tts/sseにPOSTする。- Server-Sent Events を消費する。各イベントが完了まで次のチャンクを運ぶ。
| Bytes | SSE | |
|---|---|---|
| 形状 | 1 つのストリーミングレスポンスボディ(生または file bytes) | 多数の SSE イベント(多くは JSON と base64 音声) |
| タイムスタンプ | いいえ | はい(イベントペイロード内) |
POST をまたぐ継続をサポートしていません。オプションの context_id はログ用にエコーされるだけで、複数の HTTP リクエストを 1 つの発話にまとめません。テキストを時系列で分割して送信するには WebSocket を使用してください。
SSE リファレンス を参照してください。
WebSocket (/tts/websocket)
アシスタント、ゲーム、テレフォニー型スタック、または接続が開いたまま時間とともにトランスクリプトテキストが到着する可能性のあるあらゆるケースに最適です。
WebSocket を選ぶ理由:
- レイテンシー: 接続コストを一度だけ支払い、以降の生成では追加の TCP/TLS ラウンドトリップを回避できます(ターンあたり数十から低い 3 桁 ms 単位)。
- ストリーミング入力: 到着するに従って断片を送信し(例: LLM から)、その間プロソディを維持できます。継続 と contexts を参照してください。
- タイムスタンプ: 単語またはセグメントレベルの timing(モデルや言語の制約あり。WebSocket ドキュメント参照)。
- 多重化: 1 接続上で複数の
context_id値により発話を重ねられます。
- WebSocket を開く。
- JSON メッセージを送信する。1 つの発話を複数メッセージに分ける場合、
context_idとcontinueを使い、部分メッセージにはcontinue: trueを、その発話の最終部分にはcontinue: falseを設定します(最終文字列がまだわからない場合は、contexts の空トランスクリプトパターンを使ってください)。 - サーバーがそのコンテキストを完了するまで音声を読み取る。
継続
モデルからテキストをストリーミングしていない場合は、継続ではなく bytes か SSE から始めてください。 WebSocket ストリーミングを使う場合は、発話ごとに 1 つの安定したcontext_id を維持し、すべての部分メッセージに continue: true、その発話の最終メッセージには continue: false を設定してください(contexts を参照)。
テキストやプロソディを壊すもの:
- 連結: チャンクは逐語的に結合されます。スペースが欠けると
"...world! How..."ではなく"...world!How..."になります。 - SSML や数値: 一緒に保つべきトークンを分割しないでください(例: SSML 内の小数)。継続ガイド の
max_buffer_delay_msを参照してください。
continue: true を維持しても、コンテキストはいずれ自動的に期限切れとなり、音声はサーバールールに従って生成・フラッシュされます。暴走モードにはなりません。それでも、クライアントの状態とサーバーを一致させるため、発話が完了したとわかった時点で continue: false を送信してください。古い context_id 値を無関係な発話に再利用しないでください。
なぜ WebSocket は context_id を使い、HTTP は使わないのか
POST /tts/bytes と POST /tts/sse では、完全なトランスクリプトを 1 つの JSON ボディで送信します。リクエストをまたぐ継続プロトコルはありません。
context_id と continue は、1 つの発話のテキストが複数メッセージに分かれる WebSocket で重要になります。サーバーは context_id を共有するチャンクを連結します。continue: true は「もっとテキストが来る」を意味し、continue: false はその発話を確定します。
メンタルモデル:
- 1 つの文字列に発話まるごと: bytes か SSE。コンテキスト API なし。
- テキストが断片で到着: WebSocket、発話ごとに 1 つの
context_id、継続あり。
API の使い勝手(全エンドポイント)
- サーバーサイドからの呼び出しでは、クエリ文字列ではなく
Authorizationヘッダーで API キーを渡すことを推奨します(ヘッダーはアクセスログに残りにくいため)。ブラウザの WebSocket URL は、プラットフォームに応じて異なるパターンが必要な場合があります。 - モデル ID、ボイス、コア生成パラメータは bytes、SSE、WebSocket で同じです。違うのは、ワイヤーフォーマット、チャンクの公開方法、入力を継続でストリーミングできるかどうかです。
次に進む
音声をストリーミング (bytes)
1 つの POST、ストリーミングレスポンスボディ
タイムスタンプ付き音声ストリーミング (SSE)
タイムスタンプと SSE チャンク音声
ライブセッション (WebSocket)
入力ストリーミング、多重化、ターンにわたる最低レイテンシー