Speech to Speech API

SIP 电话呼叫

SIP 允许你将 PSTN、contact center 或 PBX 呼叫路由到 Speech to Speech API session。

1. 注册电话号码

创建 Direct SIP 电话号码,并包含用于接收 incoming-call event 的 webhook 详情。对于客户自有号码,请使用 origin: "byo_trunk"。不支持通过 API 配置 xAI 电话号码。xAI 会在 response 中返回 webhook signing secret。

请选择一种 SIP 身份验证方式。

注册电话号码后,response 会包含 signing secret。请安全存储;xAI 只会返回一次。

配置 carrier 或 PBX,将呼叫路由到:

如果提供 allowed_addresses,请确保列表包含 provider 的 SIP signaling CIDR 范围。如果提供 SIP digest credential,请在 carrier 中配置相同的 username 和 password;创建后 xAI 不会再返回 password。

2. 处理 incoming-call webhook

当呼叫者拨打该号码时,xAI 会向 webhook URL 发送签名的 realtime.call.incoming webhook。使用注册电话号码后返回的 signing secret 验证 webhook-idwebhook-timestampwebhook-signature header,然后从 payload 中读取 data.call_id

Webhook 结构如下:

JSON

{
  "object": "event",
  "id": "evt_123",
  "type": "realtime.call.incoming",
  "created_at": 1750000000,
  "data": {
    "call_id": "00000000-0000-0000-0000-000000000000",
    "sip_headers": [
      { "name": "From", "value": "+14155550100" },
      { "name": "To", "value": "+18005550199" }
    ],
    "metadata": {}
  }
}

3. 通过 WebSocket 加入呼叫

使用 xAI API key 打开 wss://api.x.ai/v1/realtime?call_id={call_id}。然后发送 session.update,为该呼叫配置 voice agent;当 agent 应开始说话时,再发送 response.create

连接后,WebSocket 的行为与其他 Speech to Speech API session 相同。SIP 呼叫者的音频会桥接到 session,assistant 音频则会播放给呼叫者。

import asyncio
import json
import os
import websockets

async def handle_sip_call(call_id: str):
    async with websockets.connect(
        f"wss://api.x.ai/v1/realtime?call_id={call_id}",
        additional_headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"},
    ) as ws:
        await ws.send(json.dumps({
            "type": "session.update",
            "session": {
                "voice": "eve",
                "instructions": "You are a helpful phone support agent.",
                "turn_detection": {"type": "server_vad"},
            },
        }))
        await ws.send(json.dumps({"type": "response.create"}))

        async for msg in ws:
            event = json.loads(msg)
            print(event["type"])

asyncio.run(handle_sip_call("00000000-0000-0000-0000-000000000000"))

呼叫控制

使用 refer 将呼叫者转接到另一个 PSTN 或 SIP 目标:

Bash

curl -X POST "https://api.x.ai/v1/realtime/calls/$CALL_ID/refer" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_uri": "sip:agent@example.com"}'

使用 hangup,在应用需要结束呼叫时使用:

Bash

curl -X POST "https://api.x.ai/v1/realtime/calls/$CALL_ID/hangup" \
  -H "Authorization: Bearer $XAI_API_KEY"

DTMF 电话按键

通过 SIP 使用 Speech to Speech API 时,电话按键(DTMF tone)会自动进入 buffer,并作为文本输入 flush 到 model。Client 会收到 input_audio_buffer.dtmf_event_received event,作为每次按键的 audit trail。

Flush 触发条件

出现以下任一情况时,buffer 中的数字会提交给 model:

  • 用户按下 #(提交键)

  • 最后一次按键后空闲 2.5 秒

  • 用户开始说话(抢占数字 buffer)

Audit event

每次按键都会报告给 client WebSocket:

JSON

{
  "type": "input_audio_buffer.dtmf_event_received",
  "event": "5",
  "received_at": 1730000000
}

电话 provider

在每个 provider 中,目标都是已注册号码对应的 xAI SIP URI:

{number} 替换为 Direct SIP 电话号码。如果注册号码时配置了 allowed_addresses,请包含 provider 的 SIP signaling CIDR 范围。

Twilio

  1. 在 Twilio Console 中,前往 VoiceElastic SIP Trunking 并创建 trunk。

  2. 打开 trunk 的 Origination 设置,并添加该 origination URI:sip:{number}@sip.voice.x.ai;transport=tls

  3. 为 trunk 分配 Twilio 电话号码,或购买新号码并附加到 trunk。

  4. 如果应用在 session 中途转接呼叫,请在 trunk 上启用 call transfer。

Telnyx

  1. 在 Telnyx Portal 中,前往 Voice SuiteSIP Trunking 并创建 FQDN SIP Connection。

  2. Authentication and Routing 中,将 sip.voice.x.ai 添加为 primary FQDN,port 为 5060,record type 为 A

  3. Inbound settings 中,将目标号码格式设置为 E.164

  4. 至少启用一种受支持的 codec:G.711 μ-law、G.711 A-law 或 G.722。

  5. 为 SIP Connection 分配电话号码。

Plivo

  1. 在 Plivo Console 中,前往 SIP Trunking 并创建 SIP trunk。

  2. 选择 Inbound,然后使用 FQDN sip.voice.x.ai

  3. 将现有电话号码链接到 trunk,或购买新号码并附加到 trunk。

使用你自己的 SIP Provider

  1. 在 carrier、contact center 或 PBX 中创建 outbound route 或 SIP trunk。

  2. 将目标设置为 sip:{number}@sip.voice.x.ai;transport=tls