语音转语音 API
SIP 电话呼叫
SIP 允许您将 PSTN、呼叫中心或 PBX 呼叫路由到语音转语音 API 会话中。
1. 注册电话号码
创建直接 SIP 电话号码,并包含应接收来电事件 webhook 的详细信息。对于客户拥有的号码,请使用 origin: "byo_trunk"。不支持通过 API 预配 xAI 电话号码。xAI 会在响应中返回 webhook 签名密钥。
选择一种 SIP 认证方法。
注册电话号码后,响应将包含签名密钥。请安全存储它;xAI 只返回一次。
配置您的运营商或 PBX 以将呼叫路由到:
如果您提供 allowed_addresses,请确保列表包含您提供商的 SIP 信令 CIDR 范围。如果您提供 SIP 摘要凭据,请使用相同的用户名和密码配置您的运营商;xAI 创建后永不返回密码。
2. 处理来电 webhook
当呼叫者拨打该号码时,xAI 会向 webhook URL 发送一个签名的 realtime.call.incoming webhook。使用注册电话号码后返回的签名密钥验证 webhook-id、webhook-timestamp 和 webhook-signature 标头,然后从负载中读取 data.call_id。
webhook 的结构如下:
{
"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 密钥打开 wss://api.x.ai/v1/realtime?call_id={call_id}。然后发送 session.update 以为此呼叫配置语音代理,当代理应开始说话时,再发送 response.create。
连接后,WebSocket 的行为与其他任何语音转语音 API 会话相同。SIP 呼叫者的音频被桥接到会话中,而助手的音频则播放给呼叫者。
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"))import WebSocket from "ws";
const callId = "00000000-0000-0000-0000-000000000000";
const ws = new WebSocket(`wss://api.x.ai/v1/realtime?call_id=${callId}`, {
headers: { Authorization: `Bearer ${process.env.XAI_API_KEY}` },
});
ws.on("open", () => {
ws.send(JSON.stringify({
type: "session.update",
session: {
voice: "eve",
instructions: "You are a helpful phone support agent.",
turn_detection: { type: "server_vad" },
},
}));
ws.send(JSON.stringify({ type: "response.create" }));
});
ws.on("message", data => {
const event = JSON.parse(data.toString());
console.log(event.type);
});呼叫控制
使用 refer 将呼叫者转移到另一个 PSTN 或 SIP 目的地:
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:
curl -X POST "https://api.x.ai/v1/realtime/calls/$CALL_ID/hangup" \
-H "Authorization: Bearer $XAI_API_KEY"DTMF 电话按键
通过 SIP 使用语音转语音 API 时,电话按键(DTMF 音调)会自动缓冲并作为文本输入刷新到模型。客户端会收到 input_audio_buffer.dtmf_event_received 事件,作为每次按键的审计跟踪。
刷新触发条件
当发生以下任何情况时,缓冲的数字会提交给模型:
- 用户按下
#(提交键) - 最后一次按键后有 2.5 秒的空闲时间
- 用户开始说话(抢占数字缓冲区)
审计事件
每次按键都会报告到客户端 WebSocket:
{
"type": "input_audio_buffer.dtmf_event_received",
"event": "5",
"received_at": 1730000000
}NOTE
DTMF 仅在 SIP 会话上可用 — 不会在直接 WebSocket 连接上发出。
电话服务提供商
在每个提供商中,目标都是您注册号码的 xAI SIP URI:
将 {number} 替换为您的直接 SIP 电话号码。如果注册号码时配置了 allowed_addresses,请包含您提供商的 SIP 信令 CIDR 范围。
Twilio
- 在 Twilio 控制台中,转到 Voice → Elastic SIP Trunking 并创建一个中继。
- 打开中继的 Origination 设置,并添加此起始 URI:
sip:{number}@sip.voice.x.ai;transport=tls。 - 将 Twilio 电话号码分配给中继,或购买新号码并附加。
- 如果您的应用程序在会话中途转移呼叫,请在中继上启用呼叫转移。
Telnyx
- 在 Telnyx 门户中,转到 Voice Suite → SIP Trunking 并创建一个 FQDN SIP 连接。
- 在 Authentication and Routing 中,将
sip.voice.x.ai添加为主要 FQDN,端口为5060,记录类型为A。 - 在 Inbound settings 中,将目标号码格式设置为 E.164。
- 启用至少一个支持的编解码器:G.711 μ-law、G.711 A-law 或 G.722。
- 为 SIP 连接分配一个电话号码。
Plivo
- 在 Plivo 控制台中,转到 SIP Trunking 并创建一个 SIP 中继。
- 选择 Inbound,然后使用 FQDN
sip.voice.x.ai创建一个新 URI。 - 将现有电话号码链接到中继,或购买新号码并附加。
自带 SIP 提供商
- 在您的运营商、呼叫中心或 PBX 中,创建出站路由或 SIP 中继。
- 将目标设置为
sip:{number}@sip.voice.x.ai;transport=tls。