既存の Conversation に WebSocket で接続し、リアルタイムの音声・テキスト対話およびバックグラウンドタスクイベントを送受信します。
Realtime は現在 Beta 機能です。API 定義、イベント構造、および動作は変更される可能性があります。ドキュメントの更新を確認し、本番環境で使用する前に互換性を検証してください。
GET /api/v1/forward/realtime
1 つの Realtime 接続を維持できる最長時間は 60 分です。
ヘッダー
| Header | 必須 | 説明 |
|---|---|---|
| Authorization | はい | Bearer <PAT または SAT> |
| Upgrade | はい | websocket。WebSocket クライアントが生成します。 |
| Connection | はい | Upgrade。WebSocket クライアントが生成します。 |
クエリパラメーター
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| conversation_id | string | はい | 現在の認証情報でアクセスでき、ステータスが ready の Conversation ID。 |
リクエスト例
wss://api.qoder.com/api/v1/forward/realtime?conversation_id=conv_xxx
レスポンス例
HTTP 101 Switching Protocols
WebSocket 接続の準備が整うと、サーバーは voice.ready を送信します。
voice.ready.payload のフィールド
イベントの共通フィールドについては、Realtime イベントを参照してください。
| フィールド | 型 | 説明 |
|---|---|---|
| config | object | 現在の接続で有効な Conversation 設定。 |
| config.audio.output.voice | string | 現在の接続で有効な音声識別子。 |
| provider | string | サービスプロバイダー。公開環境では常に qoder。 |
| input_audio | object | audio.append で使用する音声形式。 |
| input_audio.format | string | 常に pcm16。WAV ヘッダーを含まない、リトルエンディアンの符号付き 16 ビット Raw PCM。 |
| input_audio.sample_rate | integer | 常に 16000 Hz。 |
| input_audio.channels | integer | 常に 1(モノラル)。 |
| output_audio | object | audio.delta で使用する音声形式。 |
| output_audio.format | string | 常に pcm16。入力音声と同じ方法でエンコードされます。 |
| output_audio.sample_rate | integer | 常に 24000 Hz。 |
| output_audio.channels | integer | 常に 1(モノラル)。 |
| capabilities | object | 現在の接続でサポートされるプロトコル機能。 |
| capabilities.graceful_close | boolean | 正常終了プロトコルをサポートするかどうか。現在は true。 |
エラー
ハンドシェイク完了前のエラーは HTTP レスポンスで返されます。
| HTTP | Code | 発生条件 |
|---|---|---|
| 400 | conversation_id_required、unsupported_query_parameter | WSS クエリパラメーターがないか、サポートされていません。 |
| 401 | authentication_required、ゲートウェイの TOKEN_INVALID | PAT または SAT が無効または期限切れであるか、Service Account Key が直接使用されています。 |
| 403 | permission_error | SAT が利用可能な Workspace に紐付けられていません。 |
| 404 | conversation_not_found | Conversation が存在しないか、現在の認証情報では関連するユーザー、Workspace、または Identity にアクセスできません。 |
| 409 | conversation_not_ready | Conversation の準備ができていません。 |
| 500 | conversation_persistence_error | サービス内部エラーが発生しました。 |
| 502 | forward_unavailable、forward_protocol_error | 依存サービスでエラーが発生しました。 |
| 503 | gateway_unavailable | サービスが一時的に利用できません。 |
error イベントで返されます。WebSocket エラーを参照してください。
Realtime イベント
イベントは UTF-8 JSON テキストメッセージとして送信されます。バイナリメッセージは使用できません。クライアントメッセージは JSON と Base64 を含めて最大 256 KiB です。音声またはテキストは voice.ready を受信した後に送信してください。
共通フィールド
| フィールド | 型 | 説明 |
|---|---|---|
| version | string | 双方向で必須。常に voice.realtime.v1。 |
| type | string | 双方向で必須。イベントタイプ。 |
| payload | object | 双方向で必須。イベントデータ。ビジネスフィールドがない場合は {}。 |
| event_id | string | サーバーが常に返します。履歴イベント ID ではなく、現在の WSS 配信 ID です。クライアントは送信しません。 |
| sequence | integer | サーバーが常に返します。現在の接続内で増加し、再接続後にリセットされます。再開カーソルとしては使用されません。 |
| conversation_id | string | サーバーが常に返します。関連する Conversation。 |
| timestamp | string | サーバーが常に返します。RFC 3339 形式の時刻で、ナノ秒精度の小数部を含む場合があります。 |
| work_id | string | サーバーが任意で返す、関連タスクの ID。 |
| announcement_id | string | サーバーが任意で返す、関連アナウンスの ID。 |
クライアントイベント
| type | payload フィールド | 説明 |
|---|---|---|
audio.append | audio: string | 空でない Base64 PCM16 を分割して送信します。エンコードは voice.ready.payload.input_audio を参照してください。サーバーが音声アクティビティを検出するため、commit イベントは不要です。 |
text.message | text: string | 前後の空白を削除した後で空ではなく、UTF-8 で最大 16 KiB。 |
interrupt | なし | 現在のレスポンスを中断します。クライアントは再生を停止し、キューをクリアします。 |
playback.started | work_id: string、announcement_id: string。対応する音声イベントに含まれる場合は必須。 | 再生が実際に開始されました。対応する音声イベントのトップレベル識別子をそのまま返します。識別子がない場合は {} を送信します。 |
playback.ended | work_id: string、announcement_id: string。対応する音声イベントに含まれる場合は必須。 | 現在の音声セグメントの再生が完了し、キューが空になりました。 |
playback.cancelled | work_id: string、announcement_id: string。対応する音声イベントに含まれる場合は必須。 | 再生を開始できないか、再生がキャンセルされました。中断時は再生を停止してキューをクリアし、元の音声識別子を付けてこの受領イベントを送信します。 |
ping | なし | 接続確認。レスポンスは pong。 |
connection.close | request_id: string | 収集と再生を停止した後に送信し、同じ request_id を持つ connection.closed を待ちます。識別子は空ではない 128 バイト以下の値で、先頭または末尾の空白、改行、null 文字を含めることはできません。 |
サーバーイベント
イベント構造の例はレスポンス例を参照してください。
| type | payload フィールド | 説明 |
|---|---|---|
voice.state | state: string | connecting、ready、idle、interrupted。 |
voice.ready | config: object、provider: string、input_audio: object、output_audio: object、capabilities: object | 接続の準備が完了しました。有効な Conversation 設定と音声転送形式を返します。 |
voice.replaced | reason: string | 接続が置き換えられました。 |
transcript.delta | role: string、text: string。任意で item_id: string、response_id: string。 | ユーザー音声の認識テキスト更新、またはアシスタント字幕の差分。 |
transcript.final | 上記と同じ | 一時字幕を置き換える最終字幕。 |
audio.delta | audio: string | Base64 PCM16 音声。エンコードは voice.ready.payload.output_audio を参照してください。 |
audio.done | なし | 現在の音声セグメントの出力が完了しました。クライアント側での再生完了を意味するものではありません。 |
playback.interrupt | reason: string | 再生を停止し、キューをクリアします。 |
work.accepted | status: "accepted"、objective: string | タスクが受け付けられました。 |
work.running | status: "running" | タスクを実行中です。 |
work.progress | kind: string、detail: string。任意で title: string、is_error: boolean、event_id: string。 | タスクの進捗。payload の event_id は永続化された Forward イベント ID です。 |
work.milestone | announcement_id: string、milestone_type: string、summary: string | タスクのマイルストーン情報。 |
work.completed | status: "completed"、result: string。任意で event_id: string。 | タスクが完了しました。アナウンスの再生は継続している場合があります。payload の event_id は永続化された Forward イベント ID です。 |
work.failed | status: "failed"、error.code: string。任意で event_id: string。 | 接続状態とは独立して、タスクが失敗またはキャンセルされました。payload の event_id は永続化された Forward イベント ID です。 |
pong | なし | ping へのレスポンス。 |
connection.closed | request_id: string、outcome: string | 元の request_id を返す終了確認。outcome は no_active_response、no_content、saved、または saved_interrupted。 |
error | code: string、message: string。任意で retryable: boolean、retry_after_ms: integer。 | プロトコルまたはサービスのエラー。 |
WebSocket エラー
| Code | 接続を終了 | 発生条件 |
|---|---|---|
invalid_event、text_too_long | いいえ | イベントが無効か、テキストの上限を超えています。 |
voice_not_ready | いいえ | Realtime 接続の準備ができていません。 |
invalid_playback_receipt | いいえ | 再生受領イベントが無効です。 |
connection_closing | いいえ | 接続を終了中で、ビジネスイベントを受け付けません。 |
invalid_work_request、work_busy、work_unavailable、work_persistence_error、forward_request_failed、forward_cancel_failed、forward_protocol_error | いいえ | タスクリクエストまたは実行でエラーが発生しました。 |
provider_initialization_failed、voice_configuration_failed、context_restore_failed | はい | Realtime モデルの初期化、音声の確認、またはコンテキストの復元に失敗しました。 |
provider_unavailable、service_restarting | はい | サービスが利用できません。retry_after_ms がある場合は、その時間後に再接続してください。 |
event_persistence_failed | はい | イベントの保存に失敗し、最後の履歴イベントが欠落している可能性があります。 |
HTTP エラーレスポンス
レスポンスフィールド
| フィールド | 型 | 説明 |
|---|---|---|
| type | string | 常に error。 |
| request_id | string | リクエストトレース ID。 |
| error.type | string | invalid_request_error、authentication_error、permission_error、not_found_error、conflict_error、api_error などのエラーカテゴリ。 |
| error.code | string | 安定したビジネスエラーコード。 |
| error.message | string | エラーの説明。 |

