系统集成文档

外部系统对接事半AI平台需要用到的全部接口——获取项目/数字员工信息、AI 外呼、AI 呼入、话术管理。通话结束后的话单回调请见 Webhook 参考。

目录

前置条件

对接前您需要确认:

  • API 地址https://api.halfcall.cn
  • SIP 地址115.190.223.167:5080(AI 呼入接入用)
  • 认证方式:所有请求在 Header 携带 Authorization: Bearer <api_key>,Key 在后台 API Key 管理 页创建
  • 数据格式:JSON,Content-Type: application/json
  • 权限隔离:每个 API Key 只能操作自己企业下的数据
  • SIP 白名单:走 AI 呼入前,业务方服务器出口IP需发送给管理员加入系统白名单,否则 SIP 请求会被拒绝
  • 话单回调:通话结束后系统主动推送话单,配置方式与签名规则见 Webhook 参考

下文示例中 sk_xxxcmk...(项目 ID)、bot_xxx(数字员工 ID)均为占位符,替换成您自己企业下的真实值。

一、获取基础信息

对接前,需先通过 API 获取 programId(项目 ID)和 botId(数字员工 ID),后续所有操作依赖这两个ID。

1.1 获取项目列表

GET /api/v1/external/programs

curl "https://api.halfcall.cn/api/v1/external/programs" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "total": 2,
    "list": [
      {
        "programId": "cmkhndatf000jdulm6ez8ojyf",
        "name": "事半AI客服",
        "runState": "PAUSED",
        "executionMode": "Stream"
      }
    ]
  }
}

响应字段说明:

字段说明
total企业下项目总数
programId项目唯一 ID,后续接口均需此值
name项目名称
runState运行状态:RUNNING=运行中,PAUSED=已暂停
executionMode执行模式:Stream=流式自动外呼,Batch=手动批次模式

1.2 获取项目下数字员工列表

GET /api/v1/external/programs/:programId/bots

curl "https://api.halfcall.cn/api/v1/external/programs/cmk.../bots" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "bots": [
      {
        "botId": "bot_xxx",
        "name": "小智",
        "stage": 1,
        "isEnabled": true,
        "hotInitStatus": "NONE"
      }
    ]
  }
}

响应字段说明:

字段说明
botId数字员工唯一 ID,AI 呼入时作为 X-BotId 传入,上传线索时指定 botId
name数字员工名称
stage轮次序号,一个项目可配置多个数字员工按轮次依次跟进
isEnabled是否启用,false 表示该数字员工已暂停
hotInitStatus话术配置状态:NONE=正常可用,PENDING=升级排队,UPGRADING=升级中,FAILED=升级失败

1.3 查询线路状态

GET /api/v1/external/programs/:programId/line-status

查询项目当前线路使用情况,可用于判断是否有空闲线路可发起外呼。

curl "https://api.halfcall.cn/api/v1/external/programs/cmk.../line-status" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "programId": "cmk...",
    "runState": "RUNNING",
    "maxConcurrency": 50,
    "currentConcurrency": 12,
    "idle": 38
  }
}

响应字段说明:

字段说明
runState项目运行状态:RUNNING / PAUSED
maxConcurrency最大并发线路数
currentConcurrency当前正在通话的线路数
idle空闲线路数(maxConcurrency - currentConcurrency

小程序集成建议:在发起外呼前先调用此接口,当 idle > 0runState = "RUNNING" 时再推送线索。

1.4 获取线路列表

GET /api/v1/external/trunks

获取当前企业可读取到的线路——包含本企业名下的线路,以及对本企业开放的共享线路(不区分项目)。

参数类型必填说明
statusstring-按线路状态筛选:Normal=可用,Band=已禁止,不传则不过滤
pagenumber-页码,默认 1
pageSizenumber-每页数量,默认 20,最大 100
curl "https://api.halfcall.cn/api/v1/external/trunks" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "total": 2,
    "page": 1,
    "pageSize": 20,
    "list": [
      {
        "trunkId": "trunk_xxx",
        "name": "北京-移动专线",
        "description": "示例线路",
        "status": "Normal",
        "trunkType": "SIP",
        "operators": "CMCC",
        "showPhoneType": "FixedLine",
        "outerCaller": "010xxxxxxx",
        "whitelistCity": "北京",
        "concurrency": 50,
        "callRate": 3000,
        "startTime": "2024-01-01T00:00:00.000Z",
        "endTime": "2024-12-31T23:59:59.000Z",
        "scope": "own"
      }
    ]
  }
}

响应字段说明:

字段说明
trunkId线路唯一 ID
status线路状态:Normal=可用,Band=已禁止
trunkType线路类型:FreeSwitch / SIP / PhoneNumber / AX
operators运营商:CMCC=移动,CUCC=联通,CTCC=电信
showPhoneType外显号码类型:FixedLine=固话,VirtualTrumpet=虚拟小号,RealnameMobile=实名手机
outerCaller外显主叫号码
whitelistCity限制城市
concurrency线路并发数
callRate每日拨打频次上限
scopeown=本企业名下线路,shared=对本企业开放的共享线路

1.5 获取音色列表

GET /api/v1/external/voices

获取当前企业可读取到的音色(TTS 模型)——包含全局共享音色,以及本企业专属克隆音色,用于配置数字员工时参考。

参数类型必填说明
statusstring-按状态筛选:active=使用中,disabled=已停用,不传则不过滤
pagenumber-页码,默认 1
pageSizenumber-每页数量,默认 20,最大 100
curl "https://api.halfcall.cn/api/v1/external/voices" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "total": 3,
    "page": 1,
    "pageSize": 20,
    "list": [
      {
        "voiceModelId": "model_xxx",
        "name": "佳音",
        "model": "speech-2.8-hd",
        "voice": "voice_id_xxx",
        "price": 0.01,
        "status": "active",
        "scope": "shared",
        "createdAt": "2024-01-01T00:00:00.000Z",
        "bots": [
          { "botId": "bot_xxx", "name": "小智" }
        ]
      }
    ]
  }
}

响应字段说明:

字段说明
voiceModelId音色对应的模型 ID,配置数字员工 TTS 时使用
name音色名称
model底层模型标识
voice底层音色标识(voice_id)
price计费单价(元)
statusactive=使用中,disabled=已停用
scopeown=本企业专属音色,shared=全局共享音色
bots当前使用该音色的本企业数字员工列表(botId + name

二、AI 外呼

线索排队与拨打机制说明(常见问题,建议先看一遍):

  • 同号覆盖:同一手机号在同一天内重复推送线索(无论批量上传还是 2.3 实时单条),会覆盖当天已有的线索记录并重新置为待拨状态——即使旧记录已经拨打完成,也会被重新拉回排队。如果同一天同一号码有多个独立通知都需要送达(比如同一人当天多场会议),目前无法在同一 programId 下同时保留多条待拨记录,请拆分到不同 programId 推送,或错开到不同自然日推送。
  • 暂停期间推送:项目处于 PAUSED 时推送的线索会正常入队(状态 WAITING),不会丢失,也无需重推;项目恢复 RUNNING 后会自动开始拨打这些线索。
  • 时段外排队:不在工作时段内推送的线索会保持排队,到下一个允许拨打时段自动补呼;目前没有过期时间(会一直排队到拨出或被撤销为止)。如果线索已经推送但临时不需要再拨了(比如会议被取消),可调用 2.8 撤销线索 撤回。
  • 未接通重拨:平台内置随访重拨策略(默认关闭,需联系管理员开启),重拨的退避间隔与最大次数由平台侧配置,暂不支持通过 API 查询或修改。开启后,重拨产生的每一通电话都会作为独立记录出现在 2.5/2.7 查询接口返回的 calls[] 里。建议提前和平台确认好重拨策略由哪边负责,避免和自建的重推逻辑重复打扰用户。

2.1 线索导入(批量上传)

步骤一:下载该数字员工的线索 Excel 模板

GET /api/v1/external/programs/:programId/leads/template

参数类型必填说明
botIdstring-指定数字员工,不传则用项目第一个启用的数字员工
curl -O -J "https://api.halfcall.cn/api/v1/external/programs/cmk.../leads/template?botId=bot_xxx" \
  -H "Authorization: Bearer sk_xxx"

返回 .xlsx 文件,第一行为表头(字段由数字员工话术配置决定),例如:

手机号码姓名公司名称

表头列名即为上传时的字段映射依据,请勿修改列名,否则上传会报字段不匹配错误。

步骤二:按模板填写数据后上传

POST /api/v1/external/programs/:programId/leads/upload

字段类型必填说明
fileFileExcel 或 CSV(.xls .xlsx .csv,最大 100MB)
botIdstring数字员工 ID,需与下载模板时一致
namestring-线索包名称,不传则用文件名
curl -X POST "https://api.halfcall.cn/api/v1/external/programs/cmk.../leads/upload" \
  -H "Authorization: Bearer sk_xxx" \
  -F "file=@/path/to/leads.xlsx" \
  -F "botId=bot_xxx" \
  -F "name=茅台外呼-第一批"
{
  "code": 0,
  "data": {
    "threadId": "thread_xxx",
    "name": "茅台外呼-第一批",
    "total": 980,
    "skipped": 20
  }
}

响应字段说明:

字段说明
threadId线索包唯一 ID,可用于后续查看该批次外呼进度
name线索包名称
total成功写入的线索数量
skipped因同一项目下手机号重复被跳过的数量

2.2 查询线索字段定义

GET /api/v1/external/programs/:programId/leads/fields

在推送线索之前先调用一次,拿到该数字员工 variables 需要传的准确字段 key(而不是 Excel 模板里看到的中文列名)。

参数类型必填说明
botIdstring-指定数字员工,不传则用项目 stage 最小的已启用数字员工(与下载模板默认逻辑一致)
curl "https://api.halfcall.cn/api/v1/external/programs/cmk.../leads/fields" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "programId": "cmk...",
    "botId": "bot_xxx",
    "fields": [
      { "key": "org_name", "name": "单位名称", "required": true },
      { "key": "contact_name", "name": "联络员姓名", "required": true },
      { "key": "meeting_title", "name": "会议主题", "required": true }
    ]
  }
}

key 就是 2.3 节 variables 里要用的字段名;name 只是给人看的中文标签,不要name 当 key 传(会被拒绝,见下方校验说明)。

2.3 线索导入(实时单条)

POST /api/v1/external/leads

适合用户实时触发场景(如刚填写表单),立即入队等待外呼。

字段类型必填说明
programIdstring项目 ID
phonestring手机号
botIdstring-指定数字员工(用于按其字段定义做校验),不传则用项目 stage 最小的已启用数字员工
variablesobject-自定义参数,key 必须是 2.2 节返回的 key(也兼容直接传 name,会自动转换,但不建议依赖这个兼容行为)
curl -X POST "https://api.halfcall.cn/api/v1/external/leads" \
  -H "Authorization: Bearer sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "programId": "cmkhndatf000jdulm6ez8ojyf",
    "phone": "13800138000",
    "variables": { "org_name": "示例公司", "contact_name": "张三" }
  }'
{
  "code": 0,
  "threadId": "detail_xxx",
  "phone": "13800138000",
  "message": "Lead has been queued for processing"
}

响应字段说明:

字段说明
threadId线索唯一 ID,可传入 GET /api/v1/external/leads?threadId= 查询后续通话结果
phone已入队的手机号
messageLead has been queued for processing=新线索已入队;Lead already exists, re-queued for calling=手机号已存在,重新入队

字段校验variables 会按该数字员工的字段定义校验——传了未知字段、或缺了必填字段,都会直接返回 400 并在 msg 里说明具体字段,线索不会入队。校验通过前后的 key 均按 2.2 节的 key 处理(若传的是 name 会被自动转换)。

2.4 启动项目

线索上传后,需启动项目才会开始外呼。

POST /api/v1/external/programs/:programId/run-state

字段类型必填说明
actionstringstart=启动,pause=暂停
curl -X POST "https://api.halfcall.cn/api/v1/external/programs/cmk.../run-state" \
  -H "Authorization: Bearer sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{"action": "start"}'
{ "code": 0, "data": { "programId": "cmk...", "runState": "RUNNING" } }

响应字段说明:

字段说明
programId操作的项目 ID
runState变更后的运行状态:RUNNING=已启动,PAUSED=已暂停

2.5 查询线索通话结果

通话结束后,可主动查询线索的通话记录和意向分析结果。

GET /api/v1/external/leads

# 方式1:通过推送线索时返回的 threadId
curl "https://api.halfcall.cn/api/v1/external/leads?threadId=detail_xxx" \
  -H "Authorization: Bearer sk_xxx"

# 方式2:通过 programId + phone
curl "https://api.halfcall.cn/api/v1/external/leads?programId=cmk...&phone=13800138000" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "threadDetailId": "detail_xxx",
    "phone": "13800138000",
    "status": "COMPLETED",
    "stage": 1,
    "variables": { "name": "张三" },
    "createdAt": "2024-01-01T00:00:00.000Z",
    "updatedAt": "2024-01-01T00:01:30.000Z",
    "calls": [
      {
        "callId": "call_xxx",
        "reached": "REACHED",
        "duration": 120,
        "intention": "HIGH",
        "intentionRate": 85,
        "summary": "客户感兴趣,约好明天回电",
        "recordingUrl": "https://cdn.halfcall.cn/rec/xxx.mp3",
        "extractData": { "interested": true },
        "createdAt": "2024-01-01T00:01:00.000Z"
      }
    ]
  }
}

响应字段说明:

字段说明
threadDetailId线索唯一 ID
phone手机号
status线索状态:PENDING=待拨打,CALLING=拨打中,COMPLETED=已完成,INVALID=无效
stage当前所在轮次(对应数字员工的 stage)
variables推送线索时传入的自定义变量
calls该线索的所有通话记录,按时间倒序
calls[].reached接通状态,见下方枚举表
calls[].duration通话时长(秒)
calls[].intentionAI 判断意向,见下方枚举表
calls[].intentionRate意向评分(0-100)
calls[].summaryAI 生成的通话摘要
calls[].recordingUrl通话录音地址,有效期 7 天
calls[].extractDataAI 从对话中提取的结构化数据(由话术配置决定字段)

calls[].reached 枚举值(2026-08 更新,此前版本文档写的 REACHED/NO_ANSWER/BUSY/FAILED 已过时,请以下表为准;"平台展示"列是登录 Web 工作台查看通话记录时看到的中文文案,方便和客服对话时对齐口径):

平台展示含义是否接通
REACHED已接听通话进行中的中间态(尚未挂断)。通话结束后正常会落到下面三个终态之一,查询接口里较少见到停留在这个值上的记录
AGENT_END已接通-AI挂断接通后由 AI 挂断
SEAT_END已接通-坐席挂断接通后转人工,由坐席挂断
USER_END已接通-客户挂断接通后由用户(被叫)挂断
UNREACHED响铃-未接听已振铃,但用户未接听
CALL_REJECTED响铃-用户拒接用户主动拒接
EMPTY_PHONE未接通-空号空号
SHUTDOWN未接通-空号或关机号码关机或空号
UN_CONNECT未打通呼叫未能建立连接
INVALID未接通未归入以上任何具体原因的无效通话
CALLER_ABNORMAL未接通-主叫异常我方线路/主叫侧异常导致未接通
INIT / PREPARE / DIALED初始化 / 准备拨打 / 已拨打拨打中间态,还没有最终结果-

判断"是否接通"建议用 reached in [REACHED, AGENT_END, SEAT_END, USER_END],或者用 duration > 0 兜底。

如果您同时登录了平台 Web 工作台查看通话记录,会看到"已接通"/"未接通"两个汇总筛选项——"已接通"就是上表"是否接通=是"的四个值汇总;"未接通"是除这四个值之外的全部其余状态(含 INIT/PREPARE/DIALED 这类还没结果的中间态),比 API 语境里习惯理解的"未接通"范围更宽,两边对数据时注意口径差异。

calls[].intention 枚举值NONE=未分析或不适用,REACHED=已接通但尚未分类,HIGH=高意向,HESITATE=犹豫,LOW_DIFFICULTY/HIGH_DIFFICULTY=意向分类(原文档 LOW 已废弃,这两个新值的具体业务含义正在和研发确认,暂按字面理解,后续版本会补充准确释义),UNKNOW=未知。

通话刚挂断时 intention 可能短暂返回 UNKNOW(AI 需要基于转写文本做后置分析,有几秒延迟),过几秒重查即可拿到最终结果。

2.6 拨打配置(可选)

GET /api/v1/external/programs/:programId/dialing-config — 查询当前配置

PUT /api/v1/external/programs/:programId/dialing-config — 修改配置(字段均可选,只传需要修改的)

curl -X PUT "https://api.halfcall.cn/api/v1/external/programs/cmk.../dialing-config" \
  -H "Authorization: Bearer sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "maxConcurrency": 30,
    "workTimeConfig": {
      "callTimeSlots": [
        { "id": "slot-1", "start": 540, "end": 1080, "days": [1,2,3,4,5] }
      ]
    }
  }'
{
  "code": 0,
  "data": {
    "programId": "cmk...",
    "runState": "RUNNING",
    "maxConcurrency": 30,
    "priorityStrategy": "LIFO",
    "workTimeConfig": {
      "callTimeSlots": [
        { "id": "slot-1", "start": 540, "end": 1080, "days": [1,2,3,4,5] }
      ]
    },
    "blockStartTime": null,
    "blockEndTime": null
  }
}

字段说明:

字段说明
maxConcurrency最大并发通话数(1-500)
priorityStrategy线索拨打顺序:LIFO=后上传先拨(默认),FIFO=先上传先拨
workTimeConfig.callTimeSlots[].start/end允许拨打的时间段,单位分钟(540=09:00,1080=18:00)
workTimeConfig.callTimeSlots[].days允许拨打的星期:1=周一,7=周日
blockStartTime / blockEndTime绝对禁呼时段(分钟数),优先级高于 callTimeSlots

2.7 批量查询线索

GET /api/v1/external/leads/batch

相比 2.5(每次只能查一条),本接口支持一次查询多条线索,或者按项目 + 日期批量拉取当天的拨打记录,适合替代逐条轮询、批量核对"哪些线索还没接通"。

参数类型必填说明
threadIdsstring与 programId 二选一逗号分隔的线索 ID 列表,最多 100 个
programIdstring与 threadIds 二选一项目 ID,配合 date 按天拉取该项目下所有线索
datestring-日期(YYYY-MM-DD),仅支持按单日过滤,暂不支持起止时间范围
pagenumber-页码,默认 1
pageSizenumber-每页数量,默认 20,最大 100
# 方式1:按线索 ID 列表批量查询
curl "https://api.halfcall.cn/api/v1/external/leads/batch?threadIds=detail_1,detail_2,detail_3" \
  -H "Authorization: Bearer sk_xxx"

# 方式2:按项目 + 日期拉取当天的线索
curl "https://api.halfcall.cn/api/v1/external/leads/batch?programId=cmk...&date=2026-08-20" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "total": 128,
    "page": 1,
    "pageSize": 20,
    "list": [
      {
        "threadDetailId": "detail_xxx",
        "phone": "13800138000",
        "programId": "cmk...",
        "status": "COMPLETED",
        "stage": 1,
        "createdAt": "2026-08-20T09:00:00.000Z",
        "updatedAt": "2026-08-20T09:03:00.000Z",
        "latestCall": {
          "callId": "call_xxx",
          "reached": "USER_END",
          "duration": 120,
          "intention": "HIGH",
          "intentionRate": 85,
          "summary": "客户感兴趣,约好明天回电",
          "createdAt": "2026-08-20T09:01:00.000Z"
        }
      }
    ]
  }
}

响应字段说明:

字段说明
total符合条件的线索总数
list[].status线索状态,同 2.5 的 status
list[].latestCall该线索最近一次通话的摘要(只有最新一次,不含完整通话历史;需要某条线索的完整 calls[] 请用 2.5 按 threadId 单条查询)

目前该接口没有额外的调用频率限制,但仍建议按需拉取(比如按 date 增量轮询),避免一次性拉取过大范围的数据。

2.8 撤销线索

POST /api/v1/external/leads/cancel

撤销尚未拨打(排队中)的线索,适合"线索已经推送,但情况有变不需要再打了"的场景(比如会议被取消)。只能撤销当前仍处于排队中的线索;已经开始拨打或已完成的线索不受影响,也不会报错。

字段类型必填说明
threadDetailIdstring二选一撤销单条线索(即 2.1/2.3 返回的线索 ID)
programIdstring二选一撤销该项目下当前全部排队中的线索(用于批量清空队列)
# 撤销单条线索
curl -X POST "https://api.halfcall.cn/api/v1/external/leads/cancel" \
  -H "Authorization: Bearer sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "threadDetailId": "detail_xxx" }'

# 撤销某项目下全部排队中的线索
curl -X POST "https://api.halfcall.cn/api/v1/external/leads/cancel" \
  -H "Authorization: Bearer sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "programId": "cmk..." }'
{ "code": 0, "data": { "cancelled": 1 } }

响应字段说明:

字段说明
cancelled实际被撤销的线索数量

注意事项

  • threadDetailIdprogramId 只能二选一。
  • threadDetailId 撤销时,如果该线索已经开始拨打或已结束(不再是排队中),接口会返回 409 并说明当前状态,不会误撤正在进行或已完成的通话。
  • programId 撤销时,只影响调用瞬间仍处于排队中的线索;如果撤销请求发出的同时某条线索恰好被自动拨号器拾取开始拨打,那一条会被跳过(不计入 cancelled)。
  • 撤销后的线索不会再出现在自动拨号队列里,但历史记录仍可通过 2.5/2.7 查询到(status 会变化)。

三、AI 呼入接入

3.1 参数说明

AI 呼入支持通过 SIP Header 传入自定义参数,系统接收后在提示词中替换对应变量,实现个性化呼入体验。参数需提前在平台配置好字段定义,以下为示例(实际字段以平台配置为准):

参数 KEY参数名称说明是否必须
user_phone用户手机号用户手机号
variable3用户的姓名用户的姓名
variable10用户欠费的金额用户欠费的金额
variable2余额50需充值金额余额50需充值金额
variable4余额一百需充值金额余额一百需充值金额
variable9用户欠费的手机号用户欠费的手机号

3.2 SIP Header 说明

Header必填说明
sip_h_X-BotIdAI 数字员工唯一标识(即 1.2 中获取的 botId
sip_h_X-Call-Params呼入参数,JSON 对象经 Base64 编码后的字符串
sip_h_X-Call-ID本次呼入的唯一标识,全局唯一;通话结束后可凭此 ID 通过回调或查询接口获取结果
origination_uuid发起方 UUID,由贵方外呼系统生成

3.3 参数编码

将所有参数组成 JSON 对象,整体做 Base64 编码后放入 sip_h_X-Call-Params

function encodeCallParams(params) {
  return Buffer.from(JSON.stringify(params)).toString('base64')
}

const encoded = encodeCallParams({
  user_phone: "18888888888",
  variable3: "张三",
  variable10: "150.00",
  variable2: "200.00",
  variable4: "250.00",
  variable9: "18811111111",
})
// eyJ1c2VyX3Bob25lIjoiMTg4ODg4ODg4ODgiLCJ2YXJpYWJsZTMiOiLlvKDkuIkiLCJ2YXJpYWJsZTEwIjoiMTUwLjAwIiwidmFyaWFibGUyIjoiMjAwLjAwIiwidmFyaWFibGU0IjoiMjUwLjAwIiwidmFyaWFibGU5IjoiMTg4MTExMTExMTEifQ==

3.4 FreeSWITCH 转发示例

originate {
  ignore_early_media=true,
  origination_uuid=001
} user/1001 &bridge({
  sip_h_X-BotId=85488662,
  sip_h_X-Call-Params=eyJ1c2VyX3Bob25lIjoiMTg4ODg4ODg4ODgiLCJ2YXJpYWJsZTMiOiLlvKDkuIkiLCJ2YXJpYWJsZTEwIjoiMTUwLjAwIiwidmFyaWFibGUyIjoiMjAwLjAwIiwidmFyaWFibGU0IjoiMjUwLjAwIiwidmFyaWFibGU5IjoiMTg4MTExMTExMTEifQ==,
  sip_h_X-Call-ID=callid_20250720_083123,
  ignore_early_media=false,
  origination_uuid=001
} sofia/external/sip:85488662@115.190.223.167:5080)

sip_h_X-Call-ID 建议格式:callid_{yyyyMMdd}_{HHmmss}_{随机串},通话结束后可凭此 ID 通过回调接收或主动查询结果。

话单回调:通话结束后系统会主动向业务服务器推送话单(含通话记录、意向结果、对话日志),推送地址/签名规则/请求体等说明见 Webhook 参考

四、话术管理(可选)

如需通过 API 动态更新数字员工的话术内容,可使用以下接口。

4.1 读取当前话术

GET /api/v1/external/bots/:botId/script

curl "https://api.halfcall.cn/api/v1/external/bots/bot_xxx/script" \
  -H "Authorization: Bearer sk_xxx"
{
  "code": 0,
  "data": {
    "botId": "bot_xxx",
    "botName": "小智",
    "scriptId": "script_xxx",
    "scriptName": "茅台外呼话术",
    "scriptVersion": 5,
    "hotInitStatus": "NONE",
    "prompt": "你是一名茅台集团的销售代表..."
  }
}

响应字段说明:

字段说明
scriptVersion话术版本号,每次更新自动 +1,可用于判断是否有变更
hotInitStatusAI 配置状态:NONE=正常可用,PENDING=等待重新初始化,UPGRADING=初始化中,FAILED=初始化失败
prompt话术原始提示词,即数字员工对话策略的源头文本

4.2 更新话术

PUT /api/v1/external/bots/:botId/script

curl -X PUT "https://api.halfcall.cn/api/v1/external/bots/bot_xxx/script" \
  -H "Authorization: Bearer sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "你是一名茅台集团的销售代表..." }'
{ "code": 0, "msg": "success", "data": { "botId": "bot_xxx", "scriptId": "script_xxx" } }

注意: 话术更新后不会立即生效,需在平台手动触发"重新初始化"(hotInitStatus 变为 PENDING),AI 重新生成配置后新话术才会被使用。

错误码

codeHTTP 状态码说明
0200/201/202成功
-1400请求参数错误(如字段缺失、格式不符)
-1401API Key 无效、已撤销或已过期
-1403无权访问该资源(不属于当前企业)
-1404资源不存在
-1500服务器内部错误