智能外呼(AI 语音机器人)对接文档

文档版本:3.0 最后更新:2026-10-16

1. 文档概述

本文档面向对接方(客户),说明如何将贵方的 AI 机器人(ASR/TTS/对话引擎)接入智能外呼平台。

对接需要完成三件事:

事项 谁做 说明
开通账号 双方 开户时互相交换以下信息(见第 2 节)
实现事件回调接口 对接方 接收平台推送的呼叫进度、话单、按键等事件
实现 WebSocket 服务端 对接方 接收平台推来的客户语音,回传 TTS 语音与控制指令

系统由三个通道构成:

通道 方向 协议 用途
呼叫控制 对接方 → 平台 HTTP (REST, JSON) 发起呼叫、通话中控制
事件通知 平台 → 对接方 HTTP (POST, JSON) 回推呼叫进度、话单、按键
实时语音流 平台 ↔ 对接方 WebSocket 双向传输 PCM 语音(上行 ASR / 下行 TTS)

2. 接入前准备

开户时双方交换以下信息:

对接方提供给平台:

信息 说明
事件回调地址(HTTP URL) 平台向此地址 POST 推送事件(见第 5 节)
WebSocket 服务地址(URL) 平台每通呼叫接通后,主动连接此地址传输语音(见第 6 节)

平台提供给对接方:

信息 说明 用途
网关地址(基础 URL) 呼叫控制接口的访问地址 调接口
账号编号 accountNo 企业账号唯一标识 发起呼叫必填
鉴权密钥 apiKey Bearer Token 每次请求鉴权
机器人标识 robotId / robotType 机器人 / 话术标识 发起呼叫必填
透显号码 平台分配的落地主叫号码 发起呼叫的 caller
并发上限 该账号允许的最大同时通话数 超限会返回错误

3. 服务地址与鉴权

3.1 服务地址

基础 URL:<网关地址>/np/sandbox

网关地址由平台在开户时提供。

3.2 鉴权方式

所有请求,请求头须携带:

Authorization: Bearer <apiKey>
Content-Type: application/json

3.3 通用响应格式

{
  "clientMutationId": "客户端传入的标识(原样返回)",
  "code": 0,
  "msg": "描述信息"
}

4. 呼叫控制接口

4.1 发起呼叫

请求体:

{
  "action": "startcall",
  "caller": "057128167421",
  "callee": "15101613608",
  "isRecord": true,
  "exten": "",
  "requestId": "req4",
  "accountNo": "860000003",
  "robotId": "test",
  "robotType": "common",
  "clientMutationId": "004",
  "packageId": "11",
  "taskId": "0"
}

参数说明:

参数名 类型 必填 说明
action string 是 固定值 startcall
caller string 是 透显号码(平台分配的落地号码)
callee string 是 被拨打的客户号码
isRecord boolean 是 是否录音
exten string 是 分机号(总机转分机时使用,可传空字符串)
requestId string 是 对接方呼叫唯一标识,事件回推时原样带回
accountNo string 是 账号编号(平台分配)
robotId string 是 机器人 / 话术 ID(平台分配)
robotType string 是 机器人类型(平台分配)
clientMutationId string 是 对接方业务标识
packageId string 否 套餐 / 话术包 ID
taskId string 否 任务 ID

成功响应:

{
  "clientMutationId": "004",
  "code": 0,
  "msg": "bbd910fc-e5fd-11f0-a660-525400eaab18"
}

msg 返回通话唯一标识(uuid / call_id),后续通话中控制、事件关联、WebSocket 都以它为准。

4.2 通话中控制

请求体:

{
  "action": "hangup",
  "parameters": "",
  "clientMutationId": "004"
}

支持的 action:

action parameters 功能
hangup 忽略 主动挂断
pause_stream 忽略 暂停语音播放(冻结 TTS 队列,背景音不受影响)
resume_stream 忽略 从暂停点恢复播放
clean_stream 忽略 打断:清空未播完的音频
transfer 坐席端点 转人工(坐席分机号 / 端点,如 1001)

响应示例:

{ "clientMutationId": "004", "code": 0, "msg": "success" }

5. 事件回调(对接方实现)

平台通过 HTTP POST 将事件推送到对接方提供的回调地址,并追加查询参数 timestamp=<毫秒>。

5.1 通用结构

{
  "account_no": "860000003",
  "caller": "057128167421",
  "callee": "15101613608",
  "event_name": "firstStart",
  "event_time": 1767153838953,
  "call_id": "bbd910fc-e5fd-11f0-a660-525400eaab18",
  "request_id": "req4",
  "task_id": "0",
  "pay_load": ""
}

字段说明:

字段 说明
account_no 账号编号
caller 透显号码
callee 客户号码
event_name 事件名
event_time 事件发生时间(毫秒 Unix 时间戳,整数)
call_id 通话唯一标识(= 发起呼叫返回的 uuid)
request_id 发起呼叫时对接方传入的唯一标识
task_id 任务 ID
pay_load 有效载荷(仅 cdr 事件为话单数组,其余为空)

回调请求会携带 Authorization 头,值由平台在开户时约定,供对接方校验请求来源。

5.2 事件类型

event_name 触发时机 pay_load
firstStart 呼叫开始 空
firstAnswer 客户接听 空
cdr 通话结束,产生话单 话单数组
dtmf 采集到按键 按键串

5.3 cdr 事件(话单)

{
  "event_name": "cdr",
  "call_id": "bbd910fc-e5fd-11f0-a660-525400eaab18",
  "pay_load": [
    {
      "caller": "057128167421",
      "callee": "15101613608",
      "call_id": "bbd910fc-e5fd-11f0-a660-525400eaab18",
      "call_type": "81",
      "out_call_type": "asyn_outcall_robot",
      "start_time": 1767153838953,
      "answer_time": 1767153844421,
      "end_time": 1767154090690,
      "is_record": 1,
      "record_file": "860000003-20261016-bbd910fc-e5fd-11f0-a660-525400eaab18-15101613608.mp3",
      "packet_id": "11",
      "task_id": "0",
      "request_id": "req4"
    }
  ]
}

话单字段说明:

字段 说明
call_id 通话唯一标识
caller / callee 透显号码 / 客户号码
call_type 呼叫类型:81 客户侧(外呼主链路),82 坐席侧(转人工产生的第二条话单)
out_call_type 固定 asyn_outcall_robot
start_time / answer_time / end_time 开始 / 应答 / 结束时间(毫秒)
is_record 是否录音,1 表示录音
record_file 录音文件名(.mp3)
packet_id 套餐 / 话术包 ID
task_id 任务 ID
request_id 发起呼叫时对接方传入的标识

6. 实时语音流(对接方实现 WebSocket 服务端)

6.1 连接方式

平台作为 WebSocket 客户端,在每通呼叫接通后,主动连接到对接方提供的 WebSocket 服务地址,并追加查询参数:

<WsUrl>?uuid=<call_id>&callId=<call_id>&accountNo=<accountNo>&robotId=<robotId>
        &robotType=<robotType>&callerName=<caller>&callerNumber=<caller>
        &callee=<callee>&packageId=<packageId>&taskId=<taskId>
        &requestId=<requestId>&clientMutationId=<urlencoded>

6.2 数据传输格式

音频统一为 8kHz / 16bit / 单声道 PCM(slin),每帧 320 字节 = 20ms。

打包节奏(平台 → 对接方的 audio 帧):平台将连续 2 帧合并为一个包发送,即 每 40ms 打包一次、每次 640 字节 PCM(base64 后放入 data 字段)。若通话中超过 200ms 无语音,平台会发送静音包保活。

平台 → 对接方(文本 JSON 帧):

type 载荷 说明
audio data 为 base64 编码的 PCM 客户侧上行语音
dtmf data 为按键字符 客户按键
tts_end data 为空 一段 TTS 播放结束
{ "type": "audio", "data": "base64 编码的音频数据" }

对接方 → 平台:

形态 说明
二进制帧 合成好的 TTS 语音(8k/16bit/mono PCM)
文本控制 JSON 通话控制指令

控制指令文本帧:

{ "type": "hangup" }         // 挂机
{ "type": "pause_stream" }   // 暂停播放
{ "type": "resume_stream" }  // 恢复播放
{ "type": "clean_stream" }   // 打断 / 清空

7. 错误码说明

code 含义
0 成功
-1 并发超限(发起呼叫)/ 操作失败(通话中控制)
-2 服务不可用(发起呼叫)/ 未知 action(通话中控制)
-3 鉴权失败(apiKey 不匹配)
-4 缺少 callee(发起呼叫)
-5 被叫号码命中平台黑名单

8. 注意事项

  1. 音频格式必须为 8kHz / 16bit / 单声道 PCM。
  2. 通话唯一标识 uuid 从发起呼叫成功响应的 msg 字段获取,贯穿通话中控制、事件回推、WebSocket。
  3. 所有时间戳均为毫秒 Unix 时间戳(整数)。
  4. 所有请求需带 Authorization: Bearer <apiKey> 头。
  5. WebSocket 地址与事件回调地址需保持稳定可访问,否则会影响通话语音与事件推送。