上报使用情况(活动、屏幕时间、交易)
本指南介绍您的产品如何把使用数据发送给 k-ID,从而让可信成人在 Family Connect 中看到这些内容。进入同一个摄取模型的入口有三个:
/activity/push接收针对产品所声明活动类型的记录。/screentime/push接收已完成的屏幕时间使用片段。/transaction/push接收已完成的购买。
三者都是仅上报的,无需家长设置:您的产品上报发生了什么,k-ID 进行汇总,面向可信成人的界面读取该汇总。它们都不会触发任何实时管控。关于完整的屏幕时间功能、家长配置的限制、安静时段、休息提醒、会话状态机及其触发的事件,请参阅屏幕时间指南。关于交易可见性、购买审批以及支付即验证,请参阅交易指南。
开始之前
三个端点都会把您发送的内容归属到某个 k-ID 会话,因此您的产品需要从年龄门获得的 sessionId。请参阅会话。调用是服务器到服务器的,并按身份验证中的说明使用 API 密钥进行认证。
除会话之外,每条路径各有一个前提条件:
- 活动需要一个已声明的活动类型。每条记录都要指定您的产品在 Compliance Studio 中声明过的类型,而类型在推送到您的 API 密钥所服务的环境之前都是本地的。请参阅活动类型和测试与发布。
- 屏幕时间需要为产品启用屏幕时间功能。未启用时,
/screentime/push会返回FEATURE_DISABLED。 - 交易需要为产品启用交易功能。未启用时,
/transaction/push会返回FEATURE_DISABLED。
三个摄取端点
这三个端点共享同一个模型,仅在单个条目所携带的内容上有所不同。
/activity/push | /screentime/push | /transaction/push | |
|---|---|---|---|
| 接收 | 针对已声明活动类型的记录 | 已完成的屏幕时间使用片段 | 已完成的购买 |
| 批字段与上限 | records,最多 1000 | events,最多 100 | events,最多 100 |
| 每个条目携带 | id、type、value、timestamp、可选的 attributes | id、durationSeconds、timestamp | id、title、amount、currency、timestamp、status、可选的 description 和 url |
| 前提条件 | 已声明并推送的活动类型 | 已启用屏幕时间功能 | 已启用交易功能 |
| 实时事件 | 无 | 无(实时路径在屏幕时间指南中) | 无(实时路径在交易指南中) |
它们的共同点是整个摄取模型:每个条目都携带一个用于幂等的客户端生成 id 和一个最近七天以内的 timestamp,一个批次只覆盖一个会话,条目逐条校验并逐条接受或拒绝,落库的内容会进入可信成人看到的汇总,而不是触发任何东西。
推送活动记录
把一个会话的一批记录发送到 /activity/push。
type 是活动类型的键:在您创建该类型时由 k-ID 生成的标识符(UUID)。请从 Compliance Studio 中该活动类型的配置里复制它,而不要自行拼装。
请把 timestamp 换成活动实际发生的时间。上面的值仅供说明:超过七天的时间戳会被拒绝,因此直接复制示例会用到过期的值。
请求示例
POST /api/v1/activity/push
Content-Type: application/json
Authorization: Bearer your-api-key
{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"records": [
{
"id": "7c3e0c6e-9c2a-4f1e-bd2b-1f9a3c6d8e10",
"type": "2f9a1c84-6b3e-4d52-9f08-1a7c3e5d9b20",
"value": { "seconds": 1800 },
"timestamp": "2026-08-19T14:32:05Z",
"attributes": { "mode": "co_op" }
}
]
}
响应示例
{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"accepted": 1,
"rejected": 1,
"records": [
{ "id": "7c3e0c6e-9c2a-4f1e-bd2b-1f9a3c6d8e10", "status": "accepted" },
{ "id": "a4f2b8d1-3e7c-4a90-8b6f-2c5d9e0a1b34", "status": "rejected", "reason": "timestamp_too_old" }
]
}
200 响应并不意味着每条记录都已落库:请检查 rejected 和每条记录的 status,而不要只看 HTTP 状态码。
值的形状
每个活动类型都声明一个指标类型,记录的 value 对象必须只包含该指标类型的字段。混合字段的记录,例如 seconds 与 count 同时出现,即使各自都合法也会被拒绝。
| 指标类型 | value | 说明 |
|---|---|---|
duration | { "seconds": 1800 } | 整秒,且不小于 0 |
currency | { "amount": 999, "currency": "USD" } | amount 以最小单位表示且不小于 0。currency 是 ISO 4217 代码 |
count | { "count": 7 } | 不小于 0 |
gauge | { "number": 0.85 } | 任意双精度数 |
boolean | { "bool": true } |
货币代码会与 ISO 4217 比对,因此 GEMS 这类游戏内货币名称会被拒绝。请把虚拟货币的购买作为计数上报;如果您希望家长看到的是真实金额,则按真实货币金额上报。
属性
attributes 是可选的键/值元数据,用于您希望分项展示的维度,例如时间花在了产品的哪个模式上。每个类型都会声明它接受的属性键,规则很严格:
- 一条记录最多携带 20 个属性。
- 键最多 64 个字符,值最多 256 个字符。
- 类型未声明的键会被拒绝。没有声明任何属性键的类型不接受任何属性。
- 看起来像电子邮件地址、电话号码或支付卡号的值会被拒绝。
请发送您自己的系统可以解析的不透明标识符,而不是个人数据。
活动拒绝原因
| 原因 | 含义 |
|---|---|
invalid_id | id 不是 UUID |
unknown_type | 在您的 API 密钥所处模式提供的配置中,该 type 未为本产品声明 |
invalid_value | value 与类型的指标类型不匹配、为负数,或包含了多个指标类型的字段 |
timestamp_in_future | timestamp 晚于当前时间 |
timestamp_too_old | timestamp 超过七天 |
attributes_too_many | 属性超过 20 个 |
attribute_key_too_long | 属性键超过 64 个字符 |
attribute_value_too_long | 属性值超过 256 个字符 |
attribute_key_not_allowed | 该属性键未在此类型中声明 |
attribute_value_forbidden_content | 属性值看起来像电子邮件地址、电话号码或支付卡号 |
type_metric_type_unsupported | 该类型的指标类型不是此 API 版本能处理的 |
transient_error | 记录有效但未能存储。请重试 |
除 transient_error 之外的每个原因,都指向一条需要您的产品修改的记录。原样重发会得到同样的拒绝,因此请把它们写入日志,而不是放进重试队列。
推送屏幕时间使用量
/screentime/push 在事后上报已完成的使用片段,适用于缓冲片段的服务器或在关闭时上报总计的游戏引擎。每个被接受的片段会把它的 durationSeconds 加入孩子当天的屏幕时间总计,并显示在家长的 Family Connect 图表中,与活动记录是同一种形态的摄取。
它是仅上报的。它不会触发休息提醒、限制警告或达到限制事件,因为这些是在会话开始时安排的,无法在事后重建。如果您的产品需要这些实时信号,或其背后由家长配置的限制、安静时段和覆盖,那属于屏幕时间指南中的实时路径,而不是此端点。
请求示例
POST /api/v1/screentime/push
Content-Type: application/json
Authorization: Bearer your-api-key
{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"events": [
{
"id": "9d4e2f81-7a3b-4c56-8e90-1f2a3b4c5d6e",
"durationSeconds": 1800,
"timestamp": "2026-06-24T09:00:00Z"
}
]
}
响应示例
{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"accepted": 1,
"rejected": 1,
"events": [
{ "id": "9d4e2f81-7a3b-4c56-8e90-1f2a3b4c5d6e", "status": "accepted" },
{ "id": "c1b2a3d4-5e6f-4708-9a1b-2c3d4e5f6071", "status": "rejected", "reason": "invalid_input" }
]
}
与活动一样,请检查 rejected 和每个事件的 status,而不要只看 HTTP 状态码。
片段规则
每个事件都是一个已完成的片段,携带用于幂等的自身 id、使用片段开始时的 timestamp(UTC),以及它的 durationSeconds。
durationSeconds介于 1 秒到 24 小时之间。更长的跨度请拆分为多个片段。- 片段必须已经完成:
timestamp + durationSeconds不能落在将来。 timestamp必须在最近七天之内。- 在家长所配置时区中跨过午夜的片段会被拆分到两个日期,使每天的总计反映当天实际发生的使用。
- 每次调用最多 100 个片段。
屏幕时间拒绝原因
| 原因 | 含义 |
|---|---|
invalid_input | 片段违反了校验规则:错误的 id、超出 1 秒到 24 小时范围的 durationSeconds,或超出范围的 timestamp。原样重试会再次失败 |
internal_error | 一次性的存储失败。可以安全重试 |
推送交易
把一个会话的一批已完成购买发送到 /transaction/push。它是仅上报的,与另外两条推送一样:您上报的每笔购买都会被记录,并在 Family Connect 中呈现给已关联的家长,上报一笔购买绝不会拦截扣款。
产品必须启用交易功能;未启用时,/transaction/push 会返回 FEATURE_DISABLED。每笔被接受的购买还会作为货币指标事件进入活动,因此上报的购买会流经可信成人读取的同一个汇总。
每个条目携带该笔购买:一个 title、以货币最小单位表示的 amount、一个 currency、它完成时的 timestamp,以及取值为 successful 或 failed 的 status。关于完整的字段集、请求与响应的形状,以及逐个事件的状态,请参阅交易指南中的上报购买。
批级错误
某些情况会让整次调用失败,响应中携带的是 error 代码而不是逐条结果。请参阅错误处理。
| 错误 | 原因 |
|---|---|
NOT_FOUND | 本产品下没有该 sessionId 对应的会话 |
INVALID_INPUT | 会话已被撤销、批为空或超过其大小上限,或请求体无法解析 |
FEATURE_DISABLED | 调用了 /screentime/push 但未启用屏幕时间功能,或调用了 /transaction/push 但未启用交易功能 |
重试与幂等性
三个端点都在每个条目上接收一个客户端生成的 id,/activity/push 上是记录的 id,/screentime/push 上是片段的 id,/transaction/push 上是购买的 id,正是这个 id 让重试变得安全。推送一个 id 已被接受的条目会再次计为接受,并且不会重复存储,因此中途超时的一批可以原样重发。
只有当 id 稳定时这个性质才成立。请在使用发生时一次性生成 ID,并与待发送的条目一起保存。在发送时才生成的 id 会让每次重试都变成重复数据。
选择批处理策略
七天的时间戳窗口是上限,而不是目标。有两点促使您采用更小、更频繁的批:
- 可信成人只能看到已经送达的使用量,因此每天推送一次的产品只能给家长展示昨天的情况。
- 超过七天的条目会被直接拒绝。对活动而言,超出该时间窗的回填必须使用异步文件上传路径;屏幕时间片段没有这样的路径,因此请在窗口内上报。
在每个端点的大小上限(1000 条记录、100 个片段或 100 笔购买)之内,按会话把几分钟的游玩数据打成一批,就能避免这两个问题。
验证集成
/activity/send-test-digest 会用该会话最近七天的真实数据,生成并发送已关联成人收到的摘要邮件。摘要会反映该会话累积的屏幕时间、活动和购买,因此这是确认您推送的内容能变成家长可读内容的最快方式。
请求示例
POST /api/v1/activity/send-test-digest
Content-Type: application/json
Authorization: Bearer your-api-key
{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672"
}
响应示例
{
"sent": true
}
关于它有四点需要了解:
- 仅限测试模式。 使用生产 API 密钥会返回
NOT_FOUND错误。该端点永远不会给真实的已关联成人发送邮件。 - 会话需要有已关联的成人。
hasApproverEmail为 false 的会话会返回INVALID_INPUT。 sent: false表示成功。 它意味着最近一周没有可汇总的内容,因此没有发出邮件。- 覆盖最近七天。 窗口截至今天,因此您为该会话推送的数据也会包含在内。
可以传入可选的 locale(例如 ja)来预览邮件的某个语言版本。
集成检查清单
- 已在 Compliance Studio 中声明活动类型并把配置推送到您的 API 密钥所服务的环境,若推送屏幕时间则已启用屏幕时间功能,若推送交易则已启用交易功能。
- 条目 ID 在使用发生的位置生成,并与条目一起保存,以便重试时复用。
- 响应处理会读取
rejected和逐条reason,在拒绝率变化时告警,并且只重试一次性原因(活动为transient_error,屏幕时间和交易为internal_error)。 - 时间戳使用 UTC,推送频率远在七天窗口之内。
- 属性仅限已声明的键,且不包含个人数据。
- 已发送并阅读过一封测试摘要邮件。