AI Readable Docs

Vox平台 API 接入文档

这是为 AI 抓取器与开发接入工具提供的静态文档出口。当前页面首屏直接包含完整正文,不依赖前端路由或浏览器执行 JavaScript。

Vox平台-API接入文档V1.0.4

1、修订记录

版本修订内容修订人修订时间
V1.0.1编写初稿李欢2026-03-19
V1.0.2完善接口规范李欢2026-03-26
V1.0.3外呼接口增加扩展字段,实现额外扩展功能李欢2026-05-11
V1.0.4外呼接口增加botType和agentProfile配置李欢2026-05-20

2、概述

2.1 接入流程

  1. 商家与泰迪熊移动签订相关合作授权协议。
  2. 商家通过统一平台注册企业账号,并提交资质认证。
  3. 商家联系泰迪熊审核账号资质,并分配相关权限。
  4. 泰迪熊提供企业账号appId和签名秘钥。

2.2 安全机制

2.2.1 通讯安全

  • 泰迪熊移动商家开放平台基于https协议搭建,并要求合作商家同样采用https协议
  • 泰迪熊移动商家开放平台通过IP白名单机制限制访问来源,非白名单无法访问服务。
  • 泰迪熊移动商家开放平台会根据访问商家检测访问量和访问频率,超出预定数值将自动发出预警,必要时会临时切断商家访问,为避免此情况发生,请在申请阶段如实告知预计访问量。

2.2.2 会话安全

  • 泰迪熊移动商家开放平台采用签名校验安全机制,通过接口信息和客户唯一secret生成签名。

2.2.3 生成签名方式

将参与生成签名的参数按顺序拼接字符串,按对应加密方式获得签名。

加密方式

hmac-sha256

参数
参数类型描述备注
methodString请求方式需转为大写,如:GET/PUT/POST/DELETE/OPTIONS/HEADER等HTTP协议中定义的method
pathString接口路径例:/vox/api/xx
uriParamsStringuri参数uri中"?"后的部分,不包括"?",例如:key1=value 1&key2 = value 2
appidString企业账号appId由泰迪熊分配
dateGMTString请求时间GMT格式的时间,必须与HTTP Header中的HMAC-DATE一致
secretString企业账号的密钥由泰迪熊分配
代码示例
public class SignatureHelper {
   private static String signatureHmacSHA256(String message, String secret) {
       try {
           Mac hasher = Mac.getInstance("HmacSHA256");
           hasher.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
           byte[] hash = hasher.doFinal(message.getBytes("UTF-8"));
           // to base64
           return DatatypeConverter.printBase64Binary(hash);
      } catch (NoSuchAlgorithmException e) {
 
      } catch (InvalidKeyException e) {
 
      }
       return null;
  }
 
   /**
    * @param method   HTTP Method,例如:GET/PUT/POST/DELETE/OPTIONS/HEADER等HTTP协议中定义的method,必须是大写。
    * @param path     接口路径,例如:/sm/api/statistic/event,必须以"/"开头。
    * @param uriParams uri中"?"后的部分,不包括"?",例如:key1=value 1&key2 = value 2,参数字符串要按照各参数名称的字符顺序进行排列。
    * @param appid     主账号的appid
    * @param dateGMT   GMT格式的时间,必须与HTTP Header中的HMAC-DATE一致
    * @param secret   主账号的密钥
    * @return 生成好的签名
    */
   public static String buildSignature(String method, String path, String uriParams, String appid, String dateGMT, String secret) {
       StringBuilder s = new StringBuilder();
       s.append(method.toUpperCase() + "\n");
       if (!path.startsWith("/")) {
           path = "/" + path;
      }
       s.append(path + "\n");
       if (uriParams == null) {
           uriParams = "";
      }
       s.append(sortParam(uriParams.split("&")) + "\n");
       s.append(appid + "\n");
       s.append(dateGMT + "\n");
       s.append("HMAC-APPID:" + appid + "\n");
       String message = s.toString();
       return buildSignature(message, secret);
  }
  
  private static String sortParam(String[] params) {
        Arrays.sort(params);
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < params.length; i++) {
            builder.append(params[i]);
            if (i < params.length - 1) {
                builder.append("&");
            }
        }
        return builder.toString();
   }
 
   public static String buildSignature(String message, String secret) {
       return signatureHmacSHA256(message, secret);
  }
}
// 加密Demo
class SignatureHelperTest {
 
   @Test
   void buildSignature() {
       String appid = "demouser";
       String secret = "demosecret";
       
       String method = "POST";
       String path = "/sms/api/xx";
       String uriParams = "a=b&x=y";
 
       //此处生成的GMT格式时间在发起HTTP请求时会使用到
       SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
       sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
       String dateGMT = sdf.format(new Date());
       
       //获取签名
       String signature = SignatureHelper.buildSignature(method, path, uriParams, appid, dateGMT, secret);
       System.out.println(signature);
       
       //j+DiLfTZoYyviAjSXejL0RyAvPHa8z4YR72n2/YUD4I=
  }
}

2.3 域名信息

环境域名地址
生产环境https://vox.teddymobile.cn

2.4 术语解释

2.5 公共参数

  • HTTP请求头必须添加5个HMAC-xxx参数
参数名类型描述备注
HMAC-APPIDStringappId泰迪熊分配的appId。
HMAC-DATEString请求时间GMT格式的时间,必须与签名时生成的GMT时间保持一致。务必确保服务器时钟准确,时钟偏移过大会导致身份认证失败。
HMAC-SIGNATUREString签名例:j+DiLfTZoYyviAjSXejL0RyAvPHa8z4YR72n2/YUD4I=
HMAC-ALGORITHMString加密算法固定值 hmac-sha256
HMAC-SIGNED-HEADERSString签名头信息固定值 HMAC-APPID
  • 响应体
参数名类型是否必填描述备注
codeint状态码成功:0
msgString返回说明
dataObject具体业务数据
timelong响应时间时间戳

3、业务接口

3.1 发起外呼

发起一个 outbound call(外呼)请求。

接口地址/vox/v1/outbound

请求方法POST

请求参数

通话类bot请求示例:

{
  "appId": "d63dd1e9-3aa3-4f88-8d3e-2be7461dff56",
  "botid": "bot_10001",
  "callee": "131****1234",
  "requestId": "66016fe1fa414ca48596aad35c457106"
}

通知类bot请求示例:

{
  "appId": "d63dd1e9-3aa3-4f88-8d3e-2be7461dff56",
  "botid": "bot_10001",
  "callee": "131****1234",
  "requestId": "req_20260313144300001",
  "extra": "{\"notification\":{\"text\":\"您好,这是一条通知\",\"times\":2}}"
}

自定义bot请求示例:

{
  "appId": "d63dd1e9-3aa3-4f88-8d3e-2be7461dff56",
  "botid": "",
  "callee": "131****1234",
  "requestId": "66016fe1fa414ca48596aad35c457106",
  "botType": "custom",
  "extra": "{\"agent_profile\":{\"name\":\"小美\",\"gender\":\"女\",\"age\":25,\"role\":\"销售顾问\",\"communicationStyle\":[\"热情\",\"专业\",\"亲切\"],\"background\":\"春季新品推广活动\",\"goals\":\"了解客户购买意向,促成交易\",\"skills\":\"产品介绍、需求挖掘、促成交易\",\"workflow\":\"问候 -> 了解需求 -> 介绍产品 -> 处理异议 -> 促成合作\",\"constraint\":\"保持礼貌、尊重对方意愿、不强制推销\",\"openingPrompt\":\"您好,我是小美,春季新品推广活动的销售顾问\"}}"
}

请求字段说明

字段类型必填说明示例
appIdstring身份标识d63dd1e9-3aa3-4f88-8d3e-2be7461dff56
botidstring机器人 ID(平台侧生成),当botType为"custom"时非必填10001
calleestring被叫号码(用户手机号)13800138000
requestIdstring请求 ID(由调用方生成,用于幂等性保证)66016fe1fa414ca48596aad35c457106
botTypestringBot 类型,当前仅支持 "custom"(自定义Bot)custom
extraJSONString扩展功能字段
extra.voiceTypestringTTS音色类型编码。<br/>可选值及适用场景:<br/>• 0 - 知愈(女):情绪安抚、心理陪伴、售后回访、不知道选什么<br/>• 1 - 安辰(男):给长辈/老人做的任何语音内容<br/>• 2 - 景珩(男):商务沟通、企业合作、科普讲解类内容<br/>• 3 - 知言(女):发通知、公告、正式播报类内容<br/>• 4 - 星苒(女):日常闲聊、陪伴、电商带货、生活服务类内容0
extra.agent_profileObject自定义Bot配置,当botType为"custom"时必填
extra.agent_profile.namestringBot名称小美
extra.agent_profile.genderstringBot性别
extra.agent_profile.ageintBot年龄25
extra.agent_profile.rolestringBot角色定位销售顾问
extra.agent_profile.communicationStylearray沟通风格列表["热情", "专业", "亲切"]
extra.agent_profile.backgroundstring业务背景春季新品推广活动
extra.agent_profile.goalsstringBot目标了解客户购买意向,促成交易
extra.agent_profile.skillsstringBot技能产品介绍、需求挖掘、促成交易
extra.agent_profile.workflowstring工作流程问候 -> 了解需求 -> 介绍产品 -> 处理异议 -> 促成合作
extra.agent_profile.constraintstring约束条件保持礼貌、尊重对方意愿、不强制推销
extra.agent_profile.openingPromptstring开场白您好,我是小美,春季新品推广活动的销售顾问
extra.notificationObject通知类bot相关的额外配置内容
extra.notification.textstring通知内容,extra.notification不为空时必填您好,这是一条通知
extra.notification.timesint播放次数,默认为播放1次2

响应示例

{
  "code": 0,
  "msg": "success",
  "data": {
    "requestId": "66016fe1fa414ca48596aad35c457106",
    "status": "accepted"
  }
}

响应字段说明

字段类型说明
codeint响应码,0 表示成功
msgstring响应消息
data.requestIdstring请求 ID,与请求中的 requestId 一致
data.statusstring任务状态:accepted(已成功接收) \failed(失败)

HTTP 状态码

  • 202 Accepted - 请求已被接受处理

4、Webhook 回调

4.1 SSE 协议方式实现

Vox通过 HTTP POST + SSE(Server-Sent Events)流式交互协议与第三方开发者系统进行实时双向通信。

4.1.1 协议概述

  • 方向:Vox 作为 HTTP Client 主动发起请求,第三方系统作为 HTTP Server 提供 API
  • 传输方式:单次 HTTP POST 请求,第三方返回 text/event-stream 持续流式响应
  • 会话连续性:通过 conversation_uuid 维护,而非长连接
  • 适用场景:需要流式输出、支持打断的多轮对话场景

4.1.2 接口地址

由第三方开发者自行提供 HTTPS 端点地址,在创建机器人时配置。

4.1.3 请求方法

POST

4.1.4 请求头

参数名类型必填说明
Content-TypeStringapplication/json
AcceptStringtext/event-stream

4.1.5 请求体

{
    "turn": 6,
    "calltype": "inbound",
    "callee": "18600013645",
    "caller": "+8652780515543",
    "callid": "4e0c4ecf-1ad6-42c3-b343-e1eb90ee18c6",
    "requestid": "1ad64ecf-b343-42c3-1ad6-e1eb90eeb343",
    "message": "好,请问你是哪里的人?"
}

字段说明

字段类型必填说明示例
messageString用户输入文本(电话接通后第一次请求为"")"我想了解套餐"
callidString通话的唯一id标识
requestidString本次请求的唯一id标识
callerString主叫号码
calleeString被叫号码
calltypeStringinbound-呼入 outbound-呼出
turnint通话轮次,接通后第一次为1

4.1.6 SSE 响应协议

Media Type: text/event-stream

响应块类型

1. 文本流块(持续返回文本片段)

data: {"id":"1ad64ecf-b343-42c3-1ad6-e1eb90eeb343",
"created":1678901234,"message":"你好"}

继续:

data: {"id":"1ad64ecf-b343-42c3-1ad6-e1eb90eeb343",
"created":1678901234,"message":",我愿意倾听你。"}

2. 完成标记(必须发送)

data: [DONE]

响应字段说明

字段类型必填说明
idString消息唯一标识,与请求体中requestid一致,原样返回
createdLong消息创建时间戳
messageString非空文本片段,Vox 按到达顺序拼接并切句
actionJSON扩展功能字段,例:{"cmd": "hangup"}表示需要主动挂断

4.1.7 交互流程

1. 通话开始(call.started)

Vox -> 第三方:POST /developer-api
Request:
{
    "turn": 1,
    "calltype": "inbound",
    "callee": "18600013645",
    "caller": "+8652780515543",
    "callid": "4e0c4ecf-1ad6-42c3-b343-e1eb90ee18c6",
    "requestid": "1ad64ecf-b343-42c3-1ad6-e1eb90eeb343",
    "message": ""
}

第三方 -> Vox: SSE Stream
data: {"id":"1ad64ecf-b343-42c3-1ad6-e1eb90eeb343",
"created":1678901234,"message":"您好"}
data: {"id":"1ad64ecf-b343-42c3-1ad6-e1eb90eeb343",
"created":1678901234,"message":",我愿意倾听你。"}
data: [DONE]

2. 用户说话(asr.transcript)

Vox -> 第三方:POST /developer-api
Request:
{
    "turn": 2,
    "calltype": "inbound",
    "callee": "18600013645",
    "caller": "+8652780515543",
    "callid": "4e0c4ecf-1ad6-42c3-b343-e1eb90ee18c6",
    "requestid": "550e8400-e29b-41d4-a716-446655440000",
    "message": "我想办理宽带业务"
}

第三方 -> Vox: SSE Stream
data: {"id":"550e8400-e29b-41d4-a716-446655440000",
"created":1678901234,"message":"好的"}
data: {"id":"550e8400-e29b-41d4-a716-446655440000",
"created":1678901234,"message":",请问您需要办理哪种宽带套餐?"}
data: [DONE]

3. 用户打断(barge-in)

当用户打断时:

  1. Vox 主动关闭当前 SSE 流
  2. 标记旧 response 为废弃
  3. 基于新 transcript 发起下一轮 HTTP + SSE 请求

4.1.8 错误处理

HTTP 状态码含义Vox 处理方式
401认证失败结束通话或播放兜底文案
400请求参数错误记录协议错误并结束通话
429限流记录并播放兜底文案
500第三方内部错误记录并播放兜底文案

SSE 中断处理

  • 首包前中断:视为本轮失败
  • 中途文本流中断且未收到 [DONE]:只播放已切出的内容,结束当前轮

4.1.9 特殊说明

  1. 打断语义:第三方无需提供 cancel API,Vox 通过关闭当前 SSE 连接完成打断
  2. 会话管理:Vox 不维护电话级长连接,每轮对话独立发起 HTTP 请求
  3. 文本切句:Vox 负责对接收到的文本流进行切句和 TTS 播放

5、附录

5.1通用状态码

http状态码含义备注
401未知用户,身份认证未通过需联系泰迪熊配置开放平台用户信息
403无接口访问权限,鉴权未通过需联系泰迪熊开通接口权限