外观
批量任务接口
创建任务
http
POST /open/v1/outbound-message-batches请求字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
batchRequestId | string | 是 | 调用方批次唯一标识,1—64 个字符 |
scenario | string | 是 | 与单次主动消息一致 |
language | string | 否 | 与单次主动消息一致 |
tone | string | 否 | 与单次主动消息一致 |
responseLength | string | 否 | 与单次主动消息一致 |
recipients | array | 是 | 2—100 项 |
recipients[].itemId | string | 是 | 批次内唯一,1—64 个字符 |
recipients[].externalUserId | string | 是 | 用户稳定标识,最长 128 个字符 |
recipients[].externalUserName | string | 否 | 用户昵称,最长 64 个字符 |
recipients[].externalUserMaskedId | string | 否 | 脱敏业务标识,最长 64 个字符 |
recipients[].conversationKey | string | 否 | 会话键,最长 128 个字符 |
recipients[].context | object | 否 | 该用户的独立上下文 |
同一批次内,itemId 必须唯一,externalUserId + conversationKey 组合也必须唯一。
请求示例:
json
{
"batchRequestId": "campaign_20260722_001",
"scenario": "reengagement",
"language": "zh-CN",
"tone": "warm",
"responseLength": "short",
"recipients": [
{
"itemId": "item_10001",
"externalUserId": "customer_10001",
"externalUserName": "王女士",
"conversationKey": "service_main",
"context": {
"facts": [{ "content": "用户曾关注家庭观影设备" }]
}
},
{
"itemId": "item_10002",
"externalUserId": "customer_10002",
"conversationKey": "service_main"
}
]
}创建成功返回 HTTP 202:
json
{
"code": 0,
"message": "OK",
"requestId": "req_create_01",
"batchId": "opbatch_66a5",
"batchRequestId": "campaign_20260722_001",
"status": "queued",
"total": 2,
"counts": {
"queued": 2,
"running": 0,
"succeeded": 0,
"failed": 0,
"skipped": 0,
"cancelled": 0
},
"createdAt": 1784736000000,
"updatedAt": 1784736000000
}重复提交相同 batchRequestId 会返回已有任务,不会创建第二份。每个 API Key 同时最多有 5 个活动任务;任务创建后用户如果又发送了新的被动消息,仍在排队的对应项目会自动跳过。
查询任务
http
GET /open/v1/outbound-message-batches/{batchId}任务状态:queued、running、completed、completed_with_errors、cancelling、cancelled、failed。
响应中的 counts 分别统计 queued、running、succeeded、failed、skipped、cancelled。
建议每 2—5 秒查询一次,进入终态后停止。查询响应与创建响应结构一致;任务结束时额外返回 completedAt,每次查询的 requestId 都会变化。
json
{
"code": 0,
"message": "OK",
"requestId": "req_query_02",
"batchId": "opbatch_66a5",
"batchRequestId": "campaign_20260722_001",
"status": "completed",
"total": 2,
"counts": {
"queued": 0,
"running": 0,
"succeeded": 1,
"failed": 0,
"skipped": 1,
"cancelled": 0
},
"createdAt": 1784736000000,
"updatedAt": 1784736009000,
"completedAt": 1784736009000
}查询任务明细
http
GET /open/v1/outbound-message-batches/{batchId}/items?status=failed&limit=50&cursor=xxx| 查询参数 | 必填 | 说明 |
|---|---|---|
status | 否 | 按项目状态筛选 |
limit | 否 | 1—100,默认 50 |
cursor | 否 | 上一页响应的 nextCursor |
单项状态:queued、running、succeeded、failed、skipped、cancelled。
每项会返回 itemId、messageId、status、attempt、retryable 及毫秒时间戳;成功项包含 replyType、replyText,失败项包含 errorCode、errorMessage。
将响应中的 nextCursor 原样传给下一次查询的 cursor;没有 nextCursor 表示已经到最后一页。成功项可以在整个批次完成前先行投递。
json
{
"code": 0,
"message": "OK",
"requestId": "req_items_03",
"batchId": "opbatch_66a5",
"items": [
{
"cursor": "cursor_1",
"itemId": "item_10001",
"messageId": "out_item_10001",
"externalUserName": "王女士",
"conversationKey": "service_main",
"status": "succeeded",
"attempt": 1,
"replyType": "text",
"replyText": "上次聊到家庭观影设备,你更关注画质还是使用便捷性?",
"retryable": false,
"createdAt": 1784736000000,
"updatedAt": 1784736005000,
"finishedAt": 1784736005000
}
],
"nextCursor": "cursor_1"
}单项状态含义:
| 状态 | 说明 |
|---|---|
queued | 等待处理 |
running | 正在生成 |
succeeded | 已成功生成,可读取 replyText |
failed | 最终失败,可读取 errorCode、errorMessage 和 retryable |
skipped | 不满足业务触达条件,不应强制发送 |
cancelled | 因取消任务而未执行 |
取消任务
http
POST /open/v1/outbound-message-batches/{batchId}/cancel取消只影响尚未完成的项目,已成功、失败或跳过的结果会保留。取消是异步过程,先进入 cancelling,最终进入 cancelled 或其他终态。
取消操作是幂等的。已经处于 running 的项目可能自然完成,排队项目会变为 cancelled。取消接口返回取消请求受理时的任务状态和计数快照,之后继续查询任务直到进入终态。
json
{
"code": 0,
"message": "OK",
"requestId": "req_cancel_04",
"batchId": "opbatch_66a5",
"batchRequestId": "campaign_20260722_001",
"status": "cancelling",
"total": 2,
"counts": {
"queued": 1,
"running": 1,
"succeeded": 0,
"failed": 0,
"skipped": 0,
"cancelled": 0
},
"createdAt": 1784736000000,
"updatedAt": 1784736003000
}