数据开放
收藏
我的收藏变更记录
时间 | 更新内容 |
2024.07.24 | 创建文档 |
2024.09.22 |
|
可靠性协议
消息类型 | 时效性保证 | 时序性保证 | 重复性保证 | 可靠性保证 | 备注 |
评论消息 | 秒级别 | 不保证绝对时序,但是时间段内相对时序基本是有保证的 | 可能会重复,需要开发者根据消息id做重复判断 | 不保证可靠性,会有数据丢失的情况 | |
礼物消息 | 秒级别 | 不保证绝对时序,但是时间段内相对时序基本是有保证的 | 可能会重复,需要开发者根据消息id做重复判断 | 尽力而为地保证可靠性,提供有限的丢失消息回查接口供开发者回查 | |
点赞消息 | 秒级别 | 不保证绝对时序,但是时间段内相对时序基本是有保证的 | 可能会重复,需要开发者根据消息id做重复判断 | 不保证可靠性,会有数据丢失的情况 | |
粉丝团消息 | 秒级别 | 不保证绝对时序,但是时间段内相对时序基本是有保证的 | 可能会重复,需要开发者根据消息id做重复判断 | 尽力而为地保证可靠性,提供有限的丢失消息回查接口供开发者回查 | |
接入流程
- •抖音平台将「一定周期内直播间数据推送给开发服务器的行为抽象为“数据推送任务”」,数据推送任务由(直播间id, 小玩法id, 直播间消息类型)三者唯一确定,在小玩法被挂载的过程中,允许开发者自主多次启动和停止推送任务。
- •抖音平台提供启动任务/停止任务/查询任务状态/回查丢失数据的接口给开发者接入,接口支持幂等调用,开发者只需要关注以下几条逻辑链路:B: 启动直播间数据推送任务:注意,只有直播间中正在被挂载的小玩法才允许开发者启动数据推送任务。主播取消挂载小玩法或者关播后,抖音平台会自动停止数据推送C: 主动回查推送失败的数据:注意,当前只有礼物数据、粉丝团数据支持回查,而且有缓存数量和时间限制。一般平台支持缓存前10w条数据,缓存一天,支持一天内过来分页查询D: 停止直播间数据推送任务E:查询直播间数据推送任务状态。
API 接口
获取 access_token
该接口用于获取开放能力接口的调用凭证 access_token。
access_token 有效期为 2 小时,需要定期刷新。
启动任务
注意:不同类型的数据需要启动不同的任务单独监听,比如礼物数据单独启动一个,评论数据单独启动一个
启动直播间数据推送,启动成功后,直播间数据才会同步推送给开发者服务器
频率限制:单个 app_id 调用上限为 10 次/秒。
请求地址
POST https://webcast.bytedance.com/api/live_data/task/start
请求参数
- •请求Headers
字段 | 数据类型 | 必填 | 说明 |
access-token | string | 是 | 通过接口获取的access_token |
content-type | string | 是 | 必须包含 application/json |
- •请求Body
字段 | 数据类型 | 必填 | 说明 |
roomid | string | 是 | 直播间id |
appid | string | 是 | 小玩法id |
msg_type | string | 是 | 直播间消息类型,需要前置申请开通了对应类型直播间数据能力才可以调用。 1. 评论:live_comment 2. 礼物:live_gift 3. 点赞:live_like 4. 粉丝团:live_fansclub |
返回值
字段 | 数据类型 | 说明 |
err_no | int | 请求错误码,0表示成功,非0表示失败 |
err_msg | string | 非0错误码时,携带额外的错误提示信息 |
logid | string | 请求链路id, 用于出问题时提供给开平具体定位 |
data | struct | 请求成功时的返回数据 { "task_id": "123456" // 任务id, string, 每次启动任务都会返回一个任务id } |
返回数据示例
- •请求
curl -X POST "https://webcast.bytedance.com/api/live_data/task/start" -d '{"roomid":"123456","appid":"tt1234567cac","msg_type":"live_comment"}' -H "access-token:your_token" -H "content-type:application/json"
- •返回
{ "err_no": 0, "err_msg": "ok", "logid": "20220927122238291", "data": { "task_id": "763535353" } }
- •错误码说明
错误名称 | 错误码 | 错误原因 |
Required Parameters Are Absent | 40023 | 缺少必要的请求参数 |
Invalid Access Token | 40022 | 无效的AccessToken |
Service Unavailable | 10001 | 服务内部错误,调用下游服务失败 |
PushTaskCanNotStart | 5003019 | 推送任务不符合开启的限制条件 |
停止任务
停止直播间数据推送成功后,抖音平台会等停止前产生的存量数据推送完成,然后停止推送新数据
频率限制:单个 app_id 调用上限为 10 次/秒。
请求地址
POST https://webcast.bytedance.com/api/live_data/task/stop
请求参数
- •请求Headers
字段 | 数据类型 | 必填 | 说明 |
access-token | string | 是 | 通过接口获取的access_token |
content-type | string | 是 | 必须包含 application/json |
- •请求Body
字段 | 数据类型 | 必填 | 说明 |
roomid | string | 是 | 直播间id |
appid | string | 是 | 小玩法id |
msg_type | string | 是 | 直播间消息类型,需要前置申请开通了对应类型直播间数据能力才可以调用。 1. 评论:live_comment 2. 礼物:live_gift 3. 点赞:live_like 4. 粉丝 团:live_fansclub |
返回值
字段 | 数据类型 | 说明 |
err_no | int | 请求错误码,0表示成功,非0表示失败 |
err_msg | string | 非0错误码时,携带额外的错误提示信息 |
logid | string | 请求链路id, 用于出问题时提供给开平具体定位 |
data | struct | 请求成功时的返回数据 {} |
返回数据示例
- •请求
curl -X POST "https://webcast.bytedance.com/api/live_data/task/stop" -d '{"roomid":"123456","appid":"tt1234567cac","msg_type":"live_comment"}' -H "access-token:your_token" -H "content-type:application/json"
- •返回
{ "err_no": 0, "err_msg": "ok", "logid": "20220927122238291", "data": {} }
- •错误码说明
错误名称 | 错误码 | 错误原因 |
Required Parameters Are Absent | 40023 | 缺少必要的请求参数 |
Invalid Access Token | 40022 | 无效的AccessToken |
Service Unavailable | 10001 | 服务内部逻辑错误 |
查询任务状态
抖音开放平台提供接口给开发者查询推送任务状态,只有响应“运行中”状态任务才是正常运行,响应:
- •不存在:任务已经被删除,可能是因为主播取消挂载/已关播
- •未启动:任务还未被启动,需要开发者调用启动任务接口
频率限制:单个 app_id 调用上限为 10 次/秒。
请求地址
GET https://webcast.bytedance.com/api/live_data/task/get
请求参数
- •请求Headers
字段 | 数据类型 | 必填 | 说明 |
access-token | string | 是 | 通过接口获取的access_token |
content-type | string | 是 | 必须包含 application/json |
- •请求Query
字段 | 数据类型 | 必填 | 说明 |
roomid | string | 是 | 直播间id |
appid | string | 是 | 小玩法id |
msg_type | string | 是 | 直播间消息类型,需要前置申请开通了对应类型直播间数据能力才可以调用。 1. 评论:live_comment 2. 礼物:live_gift 3. 点赞:live_like 4. 粉丝团:live_fansclub |
返回值
字段 | 数据类型 | 说明 |
err_no | int | 请求错误码,0表示成功,非0表示失败 |
err_msg | string | 非0错误码时,携带额外的错误提示信息 |
logid | string | 请求链路id, 用于出问题时提供给开平具体定位 |
data | struct | 请求成功时的返回数据 { "status": 1, // int, 取值:1 任务不存在 2任务未启动 3任务运行中 } |
返回数据示例
- •请求
curl -X GET "https://webcast.bytedance.com/api/live_data/task/get?roomid="123456"&appid=tt1234567cac&msg_type=live_comment" -H "access-token:your_token" -H "content-type:application/json"
- •返回
{ "err_no": 0, "err_msg": "ok", "logid": "20220927122238291", "data": { "status": 1 } }
- •错误码说明
错误名称 | 错误码 | 错误原因 |
Required Parameters Are Absent | 40023 | 缺少必要的请求参数 |
Invalid Access Token | 40022 | 无效的AccessToken |
Service Unavailable | 10001 | 服务内部逻辑错误 |
分页查询推送失败数据(仅支持礼物、粉丝团数据)
注意:补偿数据的查询没有 ack 机制,需要开发者自行维护补偿状态,比如当前补偿到第几页了,下次该读取第几页
开发者可以定时请求 api 分页查询推送失败的数据,如果返回空则代表全部推送成功
频率限制:单个 app_id 调用上限为 10 次/秒。
请求地址
GET https://webcast.bytedance.com/api/live_data/task/fail_data/get
请求参数
- •请求Headers
字段 | 数据类型 | 必填 | 说明 |
access-token | string | 是 | 通过接口获取的access_token |
content-type | string | 是 | 必须包含 application/json |
- •请求Query
字段 | 数据类型 | 必填 | 说明 |
roomid | string | 是 | 直播间id |
appid | string | 是 | 小玩法id |
msg_type | string | 是 | 直播间消息类型,需要前置申请开通了对应类型直播间数据能力才可以调用。 1. 礼物:live_gift 2. 粉丝团:live_fansclub |
page_num | int | 是 | 页码:注意,需要从1开始 |
page_size | int | 是 | 每页数据条数, 最大不超过100 |
返回值
字段 | 数据类型 | 说明 |
err_no | int | 请求错误码,0表示成功,非0表示失败 |
err_msg | string | 非0错误码时,携带额外的错误提示信息 |
logid | string | 请求链路id, 用于出问题时提供给开平具体定位 |
data | struct | 请求成功时的返回数据 { "page_num": 1, // 数据对应的页码 "total_count": 10, // 总数据条数,注意不是页数,也不是当前页的数据条数 "data_list": [ // 当页的数据列表 { "roomid": "12345", // string类型 ,消息的房间id "msg_type": "live_gift", // string类型,表示消息类型 "payload": "[...]" // string类型, 对应推送协议中的payload字符串,需要unmarshal } ] } |
返回数据示例
- •请求
curl -X GET "https://webcast.bytedance.com/api/live_data/task/fail_data/get?roomid=123456&appid=tt1234567cac&msg_type=live_comment&page_num=1&page_size=10" -H "access-token:your_token" -H "content-type:application/json"
- •返回
{ "err_no": 0, "err_msg": "ok", "logid": "20220927122238291", "data": { "page_num": 1, "total_count": 100, "data_list": [ // 当页的数据列表 { "roomid": "12345", // string类型,消息的房间id "msg_type": "live_gift", // string类型,表示消息类型 "payload": "[...]" // string类型, 对应推送协议中的payload字符串,需要unmarshal } ] } }
- •错误码说明
错误名称 | 错误码 | 错误原因 |
Required Parameters Are Absent | 40023 | 缺少必要的请求参数 |
Invalid Access Token | 40022 | 无效的AccessToken |
Request params error | 10011 | 请求的分页查询参数不合法 |
获取粉丝团信息
直播挂载小玩法后,开发者可以批量查询用户粉丝团信息。调用获取用户粉丝团信息接口的条件:
- •已开通“获取粉丝团互动数据能力”, 详情见前置工作
- •查询粉丝粉丝团数量不能超过10个,且必须开启了粉丝团推送任务
频率限制:单个 app_id 调用上限为 10 次/秒。
请求地址
GET:https://webcast.bytedance.com/api/live_data/fans_club/get_info
请求参数
- •请求Headers
字段 | 数据类型 | 必填 | 说明 |
access-token | string | 是 | 通过接口获取的access_token |
content-type | string | 是 | 必须包含 application/json |
- •请求Query
字段 | 数据类型 | 必填 | 说明 |
roomid | string | 是 | 直播间ID |
anchor_openid | string | 是 | 主播OpenID |
user_openids | string | 是 | 需要获取粉丝团信息的用户openID集合,单次最多获取10个用户的信息 (openid之间逗号分隔) |
返回值
字段 | 数据类型 | 说明 |
err_no | int | 请求错误码,0表示成功,非0表示失败 |
err_msg | string | 非0错误码时,携带额外的错误 提示信息 |
data | struct | 每个用户的粉丝团数据,包括粉丝团等级分层、加团时间,若某个openID未加团,则该 openID对应返回空数据 |
log_id | string | 日志ID |
返回数据示例
- •请求
curl --location 'https://webcast.bytedance.com/api/live_data/fans_club/get_info?roomid=7238876224917949240&anchor_openid=anchorOpenID&user_openids=user_a,user_b' \ --header 'access-token: 08011218463250582b503255787863733134566c7153426d32773d3d' \ --header 'Content-Type: application/json' \
- •返回
{ "data": { "fans_club_Info": { "user_a": { "level_layer": 1, "participate_time": 1685432708 }, "user_b": {} } }, "err_msg": "", "err_no": 0, "logid": "202305301607286362259A1CEFF06192D" }
- •错误码说明
错误名称 | 错误码 | 错误原因 |
0 | "" | 成功 |
10001 | Service Unavailable | 内部错误,可以尝试重新请求 |
40022 | Invalid Access Token | 无效的AccessToken |
10004 | Data does not exists | 直播间未挂载玩法 |
5003019 | 当前直播间未启粉丝团推送任务动,无法查询粉丝团信息 | 直播间挂载了弹幕玩法,但是未启动推送任务 |
4005014 | 参数缺失 | 必要参数未携带或为空 |
4001015 | 单次查询用户粉丝团数据超过10个 | 单次查询用户粉丝团数据超过10个 |
主播openID与accessToken对应的玩法不匹配 | 主播openID与accessToken对应的玩法不匹配 | |
当前主播ID并非直播间开播主播 | 当前主播ID并非直播间开播主播 |
粉丝团等级分层
- •粉丝团等级分层:包括低、中、高、极高四种层级
- ◦若等级小于1,level_layer返回0
- ◦若等级大于等于1且小于4,level_layer则返回1
- ◦若等级大于等于4且小于7,level_layer则返回2
- ◦若等级大于等于7且小于10,level_layer则返回3
- ◦若等级大于等于10且小于等于粉丝团最大等级,level_layer则返回4
层级 | 对应level_layer值 |
低 | 1 |
中 | 2 |
高 | 3 |
极高 | 4 |
tips:(帮助开发者更好感知粉丝团等级,来帮助玩法设计)用户若想升到 4 级,仅看播至少需要 10 天,看播+送灯牌礼物结合至少需要 4 天用户若想升到 7 级,仅看播至少需要 32 天,看播+送灯牌礼物结合至少需要 11 天用户若想升到 10 级,仅看播至少需要 95 天,看播+送灯牌礼物结合至少需要 20 天
数据推送
推送协议
当前属于快速验证收益阶段,暂不支持长连接接入。后续平台会看业务发展情况,推动技术升级
在高热直播间场景下,为了抖音平台数据推送服务的稳定运行,平台做如下数据推送限制:
- 1.默认数据推送QPS限制为100,直播间数据量越大,数据丢失可能性越大
- 2.数据推送给开发者服务端,如果推送请求响应超过 2秒 (礼物数据是3s)或者返回【非2XX】状态码,平台认为推送失败,连续10次推送失败会触发推送的熔断,平台会直接丢弃数据若干秒再尝试推送
!!!开发者请务必校验数据签名,验证数据来源的合法性,否则存在被伪造数据攻击的危险,需自行担责
- •推送方式:http回调
- •推送参数:
Method | POST | ||
参数形式 | 参数名 | 类型 | 说明 |
Header | x-nonce-str | string | 签名用的随机字符串 |
x-timestamp | int64 | 发送消息的毫秒级时间戳 | |
x-signature | string | 请求签名,业务方接收后需要计算和校验签名,防伪造和篡改 | |
x-roomid | string | 房间id | |
x-msg-type | string | 消息类型 live_comment: 直 播间评论 live_gift: 直播间送礼 live_like: 直播间点赞 | |
content-type | string | 固定值:application/json | |
body | ~ | string | 具体类型消息payload对象的json序列化字符串 |
go 示例:
/** 比如: header := map[string]string{ "x-nonce-str": "123456", "x-timestamp": "456789", "x-roomid": "268", "x-msg-type": "live_gift", } bodyStr := "abc123你好" secret := "123abc" rawData为:x-msg-type=live_gift&x-nonce-str=123456&x-roomid=268&x-timestamp=456789abc123你好123abc signature为:PDcKhdlsrKEJif6uMKD2dw== */ func signature(header map[string]string, bodyStr, secret string) string { keyList := make([]string, 0, 4) for key, _ := range header { keyList = append(keyList, key) } sort.Slice(keyList, func(i, j int) bool { return keyList[i] < keyList[j] }) kvList := make([]string, 0, 4) for _, key := range keyList { kvList = append(kvList, key+"="+header[key]) } urlParams := strings.Join(kvList, "&") rawData := urlParams + bodyStr + secret md5Result := md5.Sum([]byte(rawData)) return base64.StdEncoding.EncodeToString(md5Result[:]) }
java 示例:
import java.security.MessageDigest; import java.util.*; /** * @jdk >= 1.8 * @param header = { "x-nonce-str": "123456", "x-timestamp": "456789", "x-roomid": "268", "x-msg-type": "live_gift", * } * @param bodyStr = "abc123你好" * @param secret = "123abc" * @return PDcKhdlsrKEJif6uMKD2dw== */ public static String signature(Map<String, String> header, String bodyStr, String secret) throws Exception { List<String> keyList = new ArrayList<>(4); header.forEach((key, val) -> keyList.add(key)); Collections.sort(keyList, String::compareTo); List<String> kvList = new ArrayList<>(4); for (String key : keyList) { kvList.add(key + "=" + header.get(key)); } String urlParams = String.join("&", kvList); String rawData = urlParams + bodyStr + secret; MessageDigest md = MessageDigest.getInstance("MD5"); md.update(rawData.getBytes()); return Base64.getEncoder().encodeToString(md.digest()); }
js 示例:抖音小玩法校验数据签名-js
- •开发者对回调的响应:响应2XX就平台会认为是成功的ack
如果开放平台推送请求收到的应答不符合规范或超时未收到,开放平台会认为推送失败且不会继续推送。http 应答码为 2XX 才会当作正常响应,推送成功率会影响后续推送的频率。
评论数据-payload
[ { msg_id: "123456781", // string类型id sec_openid: "xxxx", // 评论用户的加密openid, 当前其实没有加密 content: "xxxx", // 评论内容 avatar_url: "xxx", // 评论用户头像 nickname: "xxxx", // 评论用户昵称(不加密) timestamp: 1649068964, // 评论毫秒级时间戳 }, ];
礼物数据-payload
开发者请务必校验礼物数据中test字段,如果 test字段为 true ,代表推送的是测试数据,应在数据统计场景进行过滤(如榜单场景),否则存在数据统计异常的风险,需自行担责。
测试数据生产来源说明:1)开放平台控制台的自查工具模拟发送的测试数据;2)版本发布时,因平台审核玩法交互表现等,模拟发送的测试数据;
[ { msg_id: "123456782", // string类型id sec_openid: "xxxx", // 用户的加密openid,当前其实没有加密 sec_gift_id: "xxxx", // 加密的礼物id gift_num: 123, // 送出的礼物数量 gift_value: 10000, // 礼物总价值,单位分 avatar_url: "xxx", // 用户头像 nickname: "xxxx", // 用户昵称(不加密) timestamp: 1649068964, // 礼物毫秒级时间戳 test: true, // 如果是抖音平台的测试数据,则会下发该字段且值为 true。测试工具下发的送礼数据属于调试模式,不会有该字段 audience_sec_open_id:"xxx" // 被送礼的嘉宾openid,当前没有加密 }, ];
点赞数据-payload
[ { msg_id: "123456783", // string类型id sec_openid: "xxxx", // 点赞用户的加密openid,当前其实没有加密 like_num: 123, // 点赞数量,上游2s合并一次数据 avatar_url: "xxx", // 点赞用户头像 nickname: "xxxx", // 点赞用户昵称(不加密) timestamp: 1649068964, // 点赞毫秒级时间戳 }, ];
粉丝团数据-payload
[ { msg_id: "123456789", sec_openid: "xxxx", // 粉丝团用户的openid avatar_url: "xxx", // 用户头像 nickname: "xxxx", // 用户昵称(不加密) timestamp: 1649068964, // 毫秒级时间戳 fansclub_reason_type: 2, // 粉丝团消息类型:1-升级,2-加团 fansclub_level: 1, // 用户粉丝团等级,加团消息下默认传1 }, ];
FAQ
自查手册
其他问题