Lifecycle 状态回调接口
本文档描述了消息生命周期状态回调接口的数据结构和字段说明。系统会在消息状态发生变化时,通过 HTTP POST 方式将状态信息回调到客户配置的 URL。
回调方式
- 请求方法:
POST - Content-Type:
application/json - 成功响应: HTTP 200 或 204 状态码
- 失败重试: 如果客户未返回成功状态码,系统会自动进行重试
数据结构
1. 外层结构 (ReportLifecycles)
{
"total": 1,
"rows": [
{
// ReportLifecycle 对象数组
}
]
}
{
"total": 1,
"rows": [
{
// ReportLifecycle 对象数组
}
]
}
此代码块在浮窗中显示
| 字段名 | 类型 | 说明 | 是否必返 |
|---|---|---|---|
total |
int64 | 总记录数 | 是 |
rows |
array | 生命周期状态数据数组 | 是 |
2. ReportLifecycle 对象
rows 数组中的每个元素结构如下:
| 字段名 | 类型 | 说明 | 是否必返 |
|---|---|---|---|
message_id |
string | 消息 ID | 是 |
to |
string | 接收方号码 | 是 |
server |
string | 服务类型 | 是 |
channel |
string | 渠道类型 | 是 |
itime |
int64 | 回调时间戳(秒) | 是 |
custom_args |
map[string]any | 自定义参数(发送时传入的参数) | 否 |
status |
object | 状态详情对象 | 否 |
3. Status 对象
状态详细信息对象:
| 字段名 | 类型 | 说明 | 是否必返 |
|---|---|---|---|
message_status |
string | 消息状态,如: sent、sent_fail、delivered、delivered_fail、verified 等 |
是 |
status_data |
object | 状态数据对象,详见下方 | 是 |
billing |
object | 计费信息对象,详见下方 | 否 |
error_code |
int | 错误码,0 表示无错误 | 是 |
error_detail |
object | 错误详情对象,详见下方 | 否 |
kwai_extra |
object | 快手专用扩展信息,详见下方 | 否 |
注意:以下字段为内部统计使用,不会回调给客户:
- 内部统计分析字段analysis
4. StatusData 对象
状态相关的基础数据:
| 字段名 | 类型 | 说明 | 是否必返 |
|---|---|---|---|
msg_time |
int64 | 消息创建时间戳(秒) | 是 |
message_id |
string | 消息 ID | 是 |
current_send_channel |
string | 当前发送渠道名称 | 是 |
template_key |
string | 模板配置 Key | 是 |
business_id |
string | 业务 ID | 是 |
注意:以下字段为敏感信息或内部字段,已被过滤,不会回调给客户:
- 消息内容(敏感信息)message_content- 消息分片数(内部字段)parts- 消息类型(内部字段)msg_type- 协议类型(内部字段)protocol_type- 供应商 ID(敏感信息)supplier_ids
5. Billing 对象
计费信息(仅在有计费数据时返回):
| 字段名 | 类型 | 说明 | 是否必返 |
|---|---|---|---|
cost |
float64 | 费用金额(保留 4 位小数) | 是 |
currency |
string | 币种,固定为 "USD" | 是 |
注意:以下字段为内部计费字段,不会回调给客户:
- 内部计费字段(万分之一单位)cost10000- 发送方成本(万分之一单位)sender_cost10000
6. ErrorDetail 对象
错误详情(仅在发生错误时返回):
| 字段名 | 类型 | 说明 | 是否必返 |
|---|---|---|---|
message |
string | 错误消息描述 | 是 |
channel_code |
string | 渠道返回的原始错误码 | 是 |
channel_message |
string | 渠道返回的原始错误消息 | 是 |
7. KwaiExtra 对象
快手客户专用扩展信息(仅在送达状态且为快手客户时返回):
| 字段名 | 类型 | 说明 | 是否必返 |
|---|---|---|---|
delivered_time |
int64 | 送达时间戳(毫秒) | 是 |
parts |
int | 计费条数 | 是 |
duration |
int64 | 接听时长(秒),仅语音消息有此字段 | 否 |
消息状态说明
常见的消息状态值:
| 状态值 | 说明 |
|---|---|
sent |
已发送到渠道 |
sent_fail |
发送失败 |
delivered |
已送达到用户终端 |
delivered_fail |
送达失败 |
verified |
用户已验证(如 OTP 验证码被使用) |
回调示例
示例 1:消息成功送达
{
"total": 1,
"rows": [
{
"message_id": "123456789",
"to": "+8613800138000",
"server": "sms",
"channel": "sms",
"itime": 1701234567,
"custom_args": {
"order_id": "ORDER123",
"user_id": "USER456"
},
"status": {
"message_status": "delivered",
"status_data": {
"msg_time": 1701234560,
"message_id": "123456789",
"current_send_channel": "CHANNEL_A",
"template_key": "verify_code",
"business_id": "1001"
},
"billing": {
"cost": 0.005,
"currency": "USD"
},
"error_code": 0
}
}
]
}
{
"total": 1,
"rows": [
{
"message_id": "123456789",
"to": "+8613800138000",
"server": "sms",
"channel": "sms",
"itime": 1701234567,
"custom_args": {
"order_id": "ORDER123",
"user_id": "USER456"
},
"status": {
"message_status": "delivered",
"status_data": {
"msg_time": 1701234560,
"message_id": "123456789",
"current_send_channel": "CHANNEL_A",
"template_key": "verify_code",
"business_id": "1001"
},
"billing": {
"cost": 0.005,
"currency": "USD"
},
"error_code": 0
}
}
]
}
此代码块在浮窗中显示
示例 2:消息发送失败
{
"total": 1,
"rows": [
{
"message_id": "123456790",
"to": "+8613800138001",
"server": "sms",
"channel": "sms",
"itime": 1701234568,
"status": {
"message_status": "sent_fail",
"status_data": {
"msg_time": 1701234561,
"message_id": "123456790",
"current_send_channel": "CHANNEL_B",
"template_key": "verify_code",
"business_id": "1001"
},
"error_code": 4001,
"error_detail": {
"message": "Invalid phone number",
"channel_code": "INVALID_NUMBER",
"channel_message": "The phone number format is invalid"
}
}
}
]
}
{
"total": 1,
"rows": [
{
"message_id": "123456790",
"to": "+8613800138001",
"server": "sms",
"channel": "sms",
"itime": 1701234568,
"status": {
"message_status": "sent_fail",
"status_data": {
"msg_time": 1701234561,
"message_id": "123456790",
"current_send_channel": "CHANNEL_B",
"template_key": "verify_code",
"business_id": "1001"
},
"error_code": 4001,
"error_detail": {
"message": "Invalid phone number",
"channel_code": "INVALID_NUMBER",
"channel_message": "The phone number format is invalid"
}
}
}
]
}
此代码块在浮窗中显示
示例 3:消息送达失败(带计费信息)
{
"total": 1,
"rows": [
{
"message_id": "123456791",
"to": "+8613800138002",
"server": "sms",
"channel": "sms",
"itime": 1701234570,
"custom_args": {
"campaign": "new_year_promo"
},
"status": {
"message_status": "delivered_fail",
"status_data": {
"msg_time": 1701234562,
"message_id": "123456791",
"current_send_channel": "CHANNEL_C",
"template_key": "marketing",
"business_id": "1001"
},
"billing": {
"cost": 0.0045,
"currency": "USD"
},
"error_code": 5002,
"error_detail": {
"message": "Phone number unreachable",
"channel_code": "UNREACHABLE",
"channel_message": "Subscriber absent"
}
}
}
]
}
{
"total": 1,
"rows": [
{
"message_id": "123456791",
"to": "+8613800138002",
"server": "sms",
"channel": "sms",
"itime": 1701234570,
"custom_args": {
"campaign": "new_year_promo"
},
"status": {
"message_status": "delivered_fail",
"status_data": {
"msg_time": 1701234562,
"message_id": "123456791",
"current_send_channel": "CHANNEL_C",
"template_key": "marketing",
"business_id": "1001"
},
"billing": {
"cost": 0.0045,
"currency": "USD"
},
"error_code": 5002,
"error_detail": {
"message": "Phone number unreachable",
"channel_code": "UNREACHABLE",
"channel_message": "Subscriber absent"
}
}
}
]
}
此代码块在浮窗中显示
示例 4:快手客户语音消息送达
{
"total": 1,
"rows": [
{
"message_id": "123456792",
"to": "+8613800138003",
"server": "voice",
"channel": "voice",
"itime": 1701234575,
"status": {
"message_status": "delivered",
"status_data": {
"msg_time": 1701234565,
"message_id": "123456792",
"current_send_channel": "VOICE_CHANNEL_A",
"template_key": "voice_verify",
"business_id": "2001"
},
"billing": {
"cost": 0.012,
"currency": "USD"
},
"error_code": 0,
"kwai_extra": {
"delivered_time": 1701234575000,
"parts": 1,
"duration": 45
}
}
}
]
}
{
"total": 1,
"rows": [
{
"message_id": "123456792",
"to": "+8613800138003",
"server": "voice",
"channel": "voice",
"itime": 1701234575,
"status": {
"message_status": "delivered",
"status_data": {
"msg_time": 1701234565,
"message_id": "123456792",
"current_send_channel": "VOICE_CHANNEL_A",
"template_key": "voice_verify",
"business_id": "2001"
},
"billing": {
"cost": 0.012,
"currency": "USD"
},
"error_code": 0,
"kwai_extra": {
"delivered_time": 1701234575000,
"parts": 1,
"duration": 45
}
}
}
]
}
此代码块在浮窗中显示
注意事项
字段返回规则
- 所有标记为
omitempty的字段,在值为空或零值时不会出现在返回的 JSON 中 - 敏感信息和内部字段已在回调前被过滤或清空
- 所有标记为
安全性
- 消息内容(
message_content)不会回调给客户 - 供应商 ID(
supplier_ids)等敏感信息已被过滤 - 内部计费字段(
cost10000、sender_cost10000)不会回调
- 消息内容(
接收要求
- 客户的回调接口必须在5 秒内返回响应
- 必须返回 HTTP 200 或 204 状态码表示接收成功
- 如果返回其他状态码或超时,系统将进行自动重试
重试机制
- 回调失败后会自动进行重试
- 重试间隔逐步增加
- 重试期间数据会保存在 Redis 中
时间戳说明
itime:回调发生的时间戳,单位为秒msg_time:消息创建的时间戳,单位为秒delivered_time:快手专用字段,送达时间戳,单位为毫秒
自定义参数
custom_args字段会原样返回发送消息时传入的自定义参数- 如果发送时未传入自定义参数,此字段不会出现在回调数据中
错误码参考
常见错误码说明(具体错误码请参考错误码文档):
| 错误码 | 说明 |
|---|---|
| 0 | 无错误,操作成功 |
| 4001 | 号码格式错误 |
| 4002 | 号码不存在 |
| 5001 | 渠道拒绝 |
| 5002 | 用户不可达 |
| 6001 | 网络超时 |
更详细的错误码说明请参考单独的错误码文档。
更新日志
- 2024-01: 初始版本
- 添加了
kwai_extra字段支持快手客户 - 过滤敏感信息字段,增强安全性










