For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション
Theme

電話と SIP

SIP を使って電話を OpenAI に接続します。

使用する API を選択すると、接続手順とセッションイベントを確認できます。

SIP トランクを使うと、着信と発信の両方で電話を GPT-Live に接続できます。プロバイダーが OpenAI と通話音声をやり取りし、バックエンドがセッション設定、通話制御、ビジネスロジックを担当します。SIP シグナリングには TLS を使用します。GPT-Live で通話音声を扱うには SRTP が必要です。

  • 着信の処理:着信用の Webhook を受信してから、着信を受け付けるか拒否します。
  • 電話の発信:セッションを作成し、プロバイダー経由で電話番号に発信します。着信用の Webhook や着信を受け付けるリクエストは不要です。

バックエンドでセッションイベントを受信したりコマンドを送信したりするには、サイドバンド接続を使用します。サイドバンドは既存の会話に接続し、音声は SIP が伝送します。Webhook が重複して配信された場合や複数の接続で同じイベントを受信した場合にツールが二重に実行されないよう、各アクションを担当するハンドラーは 1 つにしてください。

着信の処理

SIP プロバイダーからの着信を OpenAI プロジェクトにルーティングします。バックエンドが Webhook を受信し、着信ごとに受け付けるかどうかを判断します。

電話番号とトランクの設定

Twilio などの SIP トランキングプロバイダーを使用して、電話番号を GPT-Live に接続します。プロバイダーから電話番号を購入したら、次の手順に従ってください。

  1. OpenAI の設定でプロジェクトを開きます。Webhooks で Webhook エンドポイントを作成し、live.transport.incoming を購読するように設定します。
  2. General でプロジェクト ID を確認します。ID は proj_ で始まります。Webhook を作成したプロジェクトの ID を使用してください。
  3. プロバイダーの SIP トランクの接続先を sip:$PROJECT_ID@sip.api.openai.com;transport=tls に設定します。欧州のデータレジデンシーを利用する場合は、代わりに sip:$PROJECT_ID@sip-eu.api.openai.com;transport=tls を使用してください。

この手順を使用する前に、プロジェクトで GPT-Live の SIP サポートが有効になっており、プロバイダーの SIP トランクのルーティング先がそのプロジェクトに設定されていることを確認してください。

着信通知の受信

OpenAI はプロジェクト宛ての着信を受けると、live.transport.incoming イベントを Webhook エンドポイントに送信します。Webhook の署名を検証して重複配信を除外してから、着信を受け付けるか拒否します。

Webhook には、SIP 通話であることを示す data.type: "sip" と、data.session_id が含まれます。Live のすべての通話操作で、このセッション ID をそのまま使用してください。data.sip_headers は信頼できない発信者メタデータとして扱い、認可の根拠には使用しないでください。

Webhook の本文の例を示します。

{
  "object": "event",
  "id": "evt_abc123",
  "type": "live.transport.incoming",
  "created_at": 1750287018,
  "data": {
    "type": "sip",
    "session_id": "live_123",
    "sip_headers": [
      { "name": "From", "value": "sip:+14155550123@sip.example.com" },
      { "name": "To", "value": "sip:+18005550100@sip.example.com" },
      { "name": "Call-ID", "value": "call-123@example.com" }
    ]
  }
}

created_at フィールドは秒単位の Unix タイムスタンプです。配信時のヘッダーには、重複を除外するための webhook-id、配信を試みた時刻を示す webhook-timestamp、署名の検証に使用する webhook-signature が含まれます。サーバー側のハンドラーの実装については、Webhook の署名検証の例を参照してください。

既存の連携では、非推奨の live.call.incoming イベントが引き続き配信される場合があります。このイベントには data.type がありません。移行中は新旧両方のイベント名を処理し、旧イベントの配信と再試行がすべて完了するまで、既存のサブスクリプションを維持してください。同じ応答待ちの着信について、Realtime の Webhook も配信されることがあります。両方の API から着信を受け付けないよう、受け付けまたは拒否の判断は 1 つのハンドラーに任せてください。

着信の受け付けと拒否

アプリケーションの認可ルールとルーティングルールを適用します。着信を受け付けるには、認証付きの POST /v1/live/sessions/{session_id}/accept リクエストを送信します。リクエストの最上位に session オブジェクトを指定します。

{
  "session": {
    "type": "live",
    "model": "gpt-live-1",
    "instructions": "You are answering an inbound support call.",
    "audio": { "output": { "voice": "marin" } },
    "delegation": { "type": "client" }
  }
}

通話を制御するリクエストは、信頼できるバックエンドから Authorization: Bearer $OPENAI_API_KEY を使用して送信してください。応答に使用する声と委任モードは、着信を受け付ける時点で選択します。音声形式は SIP がネゴシエーションするため、audio.format は省略してください。この例ではクライアントへの委任を選択しているため、委任された処理をバックエンドで実行する必要があります。クライアントと Responses の設定については、委任とツールを参照してください。

着信の受け付けに成功すると、セッションの初期化後に本文が空の 200 OK が返ります。着信を受け付けたものとして扱う前に、HTTP エラーを処理してください。

着信を拒否するには、POST /v1/live/sessions/{session_id}/reject を送信し、話し中なら { "status_code": 486 } のように SIP ステータスを指定します。ステータスには 300 以上 699 以下の整数を指定してください。受け付けと拒否のうち最初の判断が採用され、その後に競合するリクエストを送信すると decision_already_made が返ります。

バックエンドの接続

着信を受け付けたら、サイドバンド WebSocket を wss://api.openai.com/v1/live/sessions/{session_id}/attach に接続します。受け付けたセッションの ID と、同じプロジェクトの認証情報および接続ヘッダーを使用してください。session.start を再送信しないでください。

通話音声は SIP が伝送します。文字起こし、処理の委任、ツール、コマンド、折り返し配信される音声にはサイドバンドを使用します。複数の接続で同じイベントを受信する場合でも、副作用を伴う各処理の実行元は 1 つに決めてください。

接続後は、通話中の操作でキーパッドのトーンを送信したり、通話を転送したり終了したりできます。

電話の発信

セッションの作成を使用すると、SIP プロバイダー経由で電話番号に発信できます。プロバイダーが電話網への接続を担当し、GPT-Live が通話相手と会話します。

すべての組織が Live API を使って SIP で発信できます。Realtime API の通話作成エンドポイントでは SIP 発信はできません。

トランクの設定

TLS シグナリングと SDES-SRTP によるメディア伝送に対応したトランクを使用してください。発信する前に、プロバイダーの設定で SRTP を有効にします。

リクエストごとに次のトランク設定を指定してください。

フィールド 値
transport.destination +14155550123 のように E.164 形式で指定した発信先の電話番号。発信先に SIP URI は使用できません。
transport.trunk.provider_url sips:sip.example.com:5061 のようなプロバイダーのエンドポイント。デフォルトのポートは 5061 です。;transport=tcp は省略できます。
transport.trunk.auth.type digest を指定すると SIP Digest 認証を使用します。
transport.trunk.auth.username プロバイダーの SIP ユーザー名。
transport.trunk.auth.password プロバイダーの SIP パスワード。
transport.trunk.caller_number プロバイダーに送信する発信元の電話番号。E.164 形式で指定します。

プロバイダーのエンドポイントには、TLS シグナリング用の sips: を使用する必要があります。URL に認証情報、パス、URI ヘッダー、その他の URI パラメーターを含めないでください。ローカルホスト名や、プライベート IP アドレスまたはローカル IP アドレスの直接指定は拒否されます。OpenAI API キーと SIP 認証情報はサーバー上で保管してください。

セッションの作成

POST /v1/live/sessions にセッション設定と transport.type: "sip" を指定して送信します。応答に使用する声と委任モードはセッション作成時に選択してください。音声形式は SIP がネゴシエーションするため、audio.format は省略します。

この例では curl と jq を使用します。サーバーの環境変数に OPENAI_API_KEY、SIP_USERNAME、SIP_PASSWORD を設定し、例にあるプロバイダーのエンドポイントと電話番号を実際の値に置き換えてください。この例ではクライアントへの委任を選択しているため、バックエンドで委任された処理を実行する必要があります。

jq -n \
  --arg username "$SIP_USERNAME" \
  --arg password "$SIP_PASSWORD" \
  '{
    "session": {
      "model": "gpt-live-1",
      "instructions": "Help the user schedule an appointment.",
      "audio": { "output": { "voice": "marin" } },
      "delegation": { "type": "client" }
    },
    "transport": {
      "type": "sip",
      "destination": "+14155550123",
      "trunk": {
        "provider_url": "sips:sip.example.com:5061",
        "auth": {
          "type": "digest",
          "username": $username,
          "password": $password
        },
        "caller_number": "+14155550100"
      }
    }
  }' | curl https://api.openai.com/v1/live/sessions \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    --data-binary @-

セッションの初期化が完了すると、リクエストに対して 200 OK が返ります。

{
  "session": { "id": "live_123" },
  "transport": { "type": "sip" }
}

このレスポンスは、相手が電話に出たことを示すものではありません。SDP やトランクの認証情報も含まれません。session.id はそのまま保持し、サイドバンド接続と通話制御に使用してください。発信時には、着信用の Webhook や着信を受け付けるリクエストは不要です。

通話の監視と終了

OpenAI API キーを使用して、バックエンドを wss://api.openai.com/v1/live/sessions/{session_id}/attach に接続します。session.start を再送信しないでください。サイドバンド接続では会話イベント、委任された処理、通話の進行状況を受信し、音声は SIP が伝送します。

イベント 意味
transport.ringing プロバイダーが呼び出し中であること、またはアーリーメディアの開始を通知しました。
transport.answered 相手が電話に応答し、メディア接続が確立しました。
transport.failed セッションの初期化後に通話の確立に失敗しました。error.code と error.message を確認してください。

通話の進行状況を示す各イベントには event_id と session_id が含まれます。セッションを作成したら、すぐにサイドバンドに接続してください。再配信の対象は直前の 3 秒間のイベントのみです。接続が遅れると、それ以前の進行状況を取りこぼす可能性があります。再配信されるイベントの ID は元のイベントと同じです。event_id で重複を除外してください。

接続後は、通話中の操作でキーパッドのトーンを送信したり、通話を転送したり終了したりできます。session.closed と最終的な使用量を受け取るまで、サイドバンドを開いたままにしてください。詳細は使用量と正常終了を参照してください。

制限とエラーへの対応

呼び出し時間の上限は 3 分、接続後の通話時間の上限は 2 時間です。これらの上限はセッション作成リクエストでは変更できません。

セッション設定が無効な場合は、作成リクエストに対してエラーが返ります。トランスポートの確立に失敗すると 502 が返ることがあり、初期化がタイムアウトすると 504 が返ります。作成に成功した後は、transport.failed を監視して、非同期で発生する接続エラーを検出してください。

通話中の操作

以下の操作は、着信と発信のどちらの SIP 通話にも使用できます。

キーパッドイベントの送受信

発信者がキーを押すと、サイドバンドは transport.dtmf.received を受信します。SIP トランクに DTMF トーンを送るには、サイドバンド WebSocket 経由で transport.dtmf.send クライアントイベントを送信します。トーンの送信に成功すると、サイドバンドは transport.dtmf.sent を受信します。

event_id を指定すると、通知にはその値が client_event_id として含まれます。失敗した場合は、error イベントに error.client_event_id が含まれます。

通話の転送と終了

通話を転送するには、POST /v1/live/sessions/{session_id}/refer を送信し、{ "target_uri": "sip:agent@example.com" } のように転送先を指定します。通話を終了するには、リクエスト本文を付けずに POST /v1/live/sessions/{session_id}/hangup を送信します。どちらも成功すると、本文が空の 200 OK が返ります。

転送先は SIP の Refer-To ヘッダーに設定されます。tel:+14155550123 のような電話 URI または sip:agent@example.com のような SIP URI を指定できます。その後の転送処理はプロバイダーが担当します。

session.closed で最終的な使用量を受け取るまで、サイドバンドを開いたままにしてください。使用量の報告と終了理由については、使用量と正常終了を参照してください。

SIP のネットワーク要件

GPT-Live の SIP 通話では、シグナリングとメディアに別々のネットワーク経路を使用します。両方のトラフィックを許可するようにネットワークを設定してください。

  • SIP シグナリング: sip.api.openai.com と sip-eu.api.openai.com は、GeoIP に基づいてルーティングされるエンドポイントです。DNS が返すアドレスのポート 5061 宛ての送信 TCP/TLS トラフィックを許可してください。
  • SRTP メディア: API は、ネゴシエーションで合意した SDP 内で、メディア用の IP アドレスと UDP ポートを別途指定します。以下の CIDR 範囲との間で、UDP 経由の SRTP トラフィックを双方向に許可してください。
    • 13.79.45.80/28
    • 23.98.140.64/28
    • 40.67.149.176/28
    • 40.83.204.240/28

GPT-Live の次のステップ