# 印度 SIP 中继 API 配置指南:三步创建 Trunk、映射 DID、配置 IP 白名单
对于向印度市场提供 AI 语音代理或呼叫中心服务的企业而言,SIP 中继的 API 配置是接入印度电话网的第一步。印度电信监管局(TRAI)对 SIP 中继有严格的合规要求——**SIP 信令和 RTP 媒体流都必须锚定在印度境内**,且外资企业必须通过持有 UL-VNO 牌照的本地服务商(如 Exotel、Plivo)进行接入。
本文以开发者视角,提供 Exotel 和 Plivo 两大主流平台的 SIP中继 API 配置指南,涵盖**创建 Trunk、映射 DID、配置 IP 白名单**三个核心步骤。
在调用任何 API 之前,你需要:
| 准备项 | 说明 | 来源 |
| :--- | :--- | :--- |
| **API Key + API Token** | 用于 HTTP Basic Auth 认证 | 服务商控制台 |
| **Account SID** | 账户唯一标识 | 服务商控制台 |
| **KYC 验证** | 印度号码租用前必须完成 | Exotel/Plivo 账户经理 |
| **印度本地号码(DID)** | 需从服务商购买 | 服务商控制台 |
Exotel 的 API 基地址为 `https://api.in.exotel.com`(印度区域),所有端点以 `/v2/accounts/{account_sid}` 为前缀。Plivo 的 API 基地址为 `https://www.lanlansms.com/v1/Account/{auth_id}/Zentrunk/`。
SIP Trunk 是连接你的语音系统与运营商网络的逻辑通道。Exotel 和 Plivo 的 API 结构有所不同,但核心逻辑一致。
### Exotel:创建 Trunk
```bash
curl -s -X POST "https://${API_KEY}:${API_TOKEN}@api.in.exotel.com/v2/accounts/${ACCOUNT_SID}/trunks" \
-H "Content-Type: application/json" \
-d '{
"trunk_name": "my_trunk_name",
"nso_code": "ANY-ANY",
"domain_name": "'"${ACCOUNT_SID}"'.pstn.exotel.com"
}'
```
`trunk_name` 限 **16 个字符**,仅支持字母数字和下划线。创建成功后,响应中会返回 `trunk_sid`,**务必保存**——后续所有配置都需要用到它。
### Plivo:创建 Trunk
Plivo 的 Trunk 创建分为**出站(Outbound)** 和**入站(Inbound)** 两个方向,需要分别创建。出站 Trunk 还需要先配置认证方式(Credentials 或 IP ACL)。
**出站 Trunk 示例**:
```bash
curl -i --user AUTH_ID:AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{
"name": "elevenlabs-outbound",
"trunk_direction": "outbound",
"credential_uuid": "f19c4773-4ae6-4b75-92ea-9cf3ea4227d6"
}' \
https://api.plivo.com/v1/Account/{auth_id}/Zentrunk/Trunk/
```
创建后,通过 `GET /Zentrunk/Trunk/{trunk_id}/` 获取 `trunk_domain`(如 `21784177241578.zt.plivo.com`),这就是你的 AI 平台需要指向的 SIP 地址。
**入站 Trunk** 的配置逻辑相反:你需要先创建 **Origination URI**(指向你的 AI 平台端点),再创建入站 Trunk,最后将号码关联到 Trunk。
DID(直接拨入号码)是印度本地电话号码,需要与 Trunk 关联后才能正常收发来电。
### Exotel:映射号码
```bash
curl -s -X POST "https://${API_KEY}:${API_TOKEN}@api.in.exotel.com/v2/accounts/${ACCOUNT_SID}/trunks/${TRUNK_SID}/phone-numbers" \
-H "Content-Type: application/json" \
-d '{"phone_number": "+91XXXXXXXXXX"}'
```
响应中会返回一个数字 ID,需要保存用于后续操作。
### Plivo:关联号码到入站 Trunk
Plivo 的号码关联操作在控制台完成:**Phone Numbers → 选择号码 → 设置 Application Type 为 Zentrunk → 选择对应的入站 Trunk**。API 层面,号码仅能关联到**入站 Trunk**——出站 Trunk 不会出现在号码配置的下拉菜单中。
**关键区别**:Exotel 的号码映射通过 API 完成,Plivo 主要通过控制台操作。两者都要求号码与 Trunk 的关联是 **1:1 或 1:N** 的关系。
IP 白名单是出站 SIP 呼叫的安全机制,确保只有你授权的服务器 IP 能够通过 Trunk 发起呼叫。
### 核心规则
IP ACL 的配置遵循**优先级(Precedence)** 机制:**数值越小,优先级越高**。标准做法是:
1. **创建高优先级规则**:允许你的服务器 IP(如 `10.35.66.187/32`)访问 SIP 端口(5060/5070)
2. **创建低优先级规则**:拒绝所有其他流量(`DENYALL_UNTRUST`,优先级设为 65015)
这样,只有白名单中的 IP 能够通过,其余全部被阻断。
### Exotel:配置 IP 白名单
```bash
curl -s -X POST "https://${API_KEY}:${API_TOKEN}@
-H "Content-Type: application/json" \
-d '{
"ip": "44.248.146.11",
"mask": 32
}'
```
- `ip`:你的服务器公网 IP(必须是有效 IPv4 地址)
- `mask`:子网掩码,默认 **32**(单个 IP)。如需白名单整个网段,可使用 24 或 16
**重要限制**:Exotel 控制台目前**仅支持白名单 1 个 IP 范围**。如需白名单多个 IP,需联系 `hello@exotel.com`。
### Plivo:配置 IP ACL
Plivo 的 IP ACL 创建是独立步骤,然后再将 ACL 关联到 Trunk:
```bash
# 创建 IP ACL
curl -i --user AUTH_ID:AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{
"name": "livekit-servers",
"ip_addresses": ["52.1.2.3", "52.1.2.4"]
}' \
https://api.plivo.com/v1/Account/{auth_id}/Zentrunk/IPAccessControlList/
```
创建后返回 `ipacl_uuid`,在创建出站 Trunk 时作为参数传入。
### 替代方案:SIP Digest 认证
对于使用 **Voice AI 云平台**(如 ElevenLabs、LiveKit)的企业,IP 白名单存在一个根本性问题:**云平台没有静态出口 IP**,它们的 IP 地址会动态变化。
Exotel 为此推出了 **SIP Digest 认证**,无需 IP 白名单即可完成认证:
```bash
curl -s -X POST "https://${API_KEY}:${API_TOKEN}@api.in.exotel.com/v2/accounts/${ACCOUNT_SID}/trunks/${TRUNK_SID}/credentials" \
-H "Content-Type: application/json" \
-d '{
"user_name": "SIP_USER",
"password": "SIP_PASS",
"friendly_name": "voice_ai_platform"
}'
```
将 `user_name`、`password` 和你的 Exotel SIP 域名提供给 Voice AI 平台即可。Exotel SIP 边缘地址为:**TCP:`in.voip.exotel.com:5070`**,**TLS:`in.voip.exotel.com:443`**。
| 步骤 | Exotel | Plivo | 关键参数 |
| :--- | :--- | :--- | :--- |
| **① 创建 Trunk** | `POST /trunks` | `POST /Zentrunk/Trunk/` | `trunk_sid` / `trunk_id` + `trunk_domain` |
| **② 映射 DID** | `POST /trunks/{sid}/phone-numbers` | 控制台:号码 → Zentrunk | 印度号码(+91) |
| **③ IP 白名单** | `POST /trunks/{sid}/whitelisted-ips` | `POST /Zentrunk/IPAccessControlList/` | 服务器公网 IP + mask/32 |
| **④ 入站路由** | `POST /trunks/{sid}/destination-uris` | `POST /Zentrunk/OriginationURI/` | 你的 AI 平台 SIP 端点 |
**两个关键提醒**:
1. **印度合规前置条件**:在配置任何 Trunk 之前,必须完成 **KYC 验证**。印度号码仅对完成 KYC 的企业开放租用。
2. **媒体锚定要求**:如果你使用的是 LiveKit 或 ElevenLabs 等平台,必须确保平台**在印度区域终止 SIP 和媒体流**。否则通话会返回挂断代码 **4590**(媒体锚定违规)。