事件 API

向 NU 流式发送播放、互动和收入信号。验证通过的收入事件进入结算。需要 events:write。

端点

方法路径成功用途
POST/events200发送单个事件
POST/events/batch207发送最多 500 个事件并返回逐项结果

事件类型

仅接受以下 event_type 值。未知类型返回 validation_failed。

event_type含义必填字段结算
IMPRESSION作品或海报曝光—否
TITLE_VIEW打开作品详情title_id否
EPISODE_STARTED开始播放title_id, episode_id否
PLAYBACK_PROGRESS心跳或四分位进度episode_id, completion_rate否
EPISODE_COMPLETED播放完成episode_id, completion_rate否
EPISODE_UNLOCKED授予付费解锁episode_id仅指标
PAYMENT_COMPLETED收入title_id, revenue_amount, currency是
REFUND退款或冲销title_id, revenue_amount, currency是(负数)
SUBSCRIPTION_RENEWAL经常性收入title_id, revenue_amount, currency是
AD_IMPRESSION广告或互动信号—否
OTHER非标准—否

结算资格由摄取管道根据类型推导,绝不由合作伙伴提供的标志决定。

必填字段与验证

每个事件都需要 event_id 和 event_type。occurred_at 可选,默认为服务器接收时间。特定类型字段见上表。

  • event_id 在每个组织内唯一并提供幂等性。重复事件不执行操作,返回 409 duplicate_event_id,不会重复计数。
  • completion_rate 必须位于 [0, 1] 范围内。
  • 收入类型需要 title_id、revenue_amount 和 ISO 4217 currency,否则返回 validation_failed。收入必须归属于作品以便核对。
  • occurred_at 不能是未来时间。未来偏移事件会以 failed 拒绝,并返回 occurred_at_in_future。超过 24 小时的事件仍会接受,但标记为 payload.late = true。
  • viewer_id_hash 必须为哈希标识符,且不得包含原始 PII;否则返回 validation_failed。
  • 发送 title_id、episode_id 和 playback_session_id 时,它们必须在密钥环境中可见并属于您的组织。引用失败会返回 validation_failed,详情可能为 unknown_title_for_environment、unknown_episode_for_environment、playback_session_mismatch、license_not_active 或 episode_not_licensed。

字段限制

字符串字段有长度限制;超出时返回 validation_failed:

字段类型约束
event_idstring1–200 个字符(必填)
event_typestring1–64 个字符(必填)
title_idstring最多 64 个字符
episode_idstring最多 64 个字符
playback_session_idstring最多 64 个字符
viewer_id_hashstring最多 128 个字符;仅哈希
countrystring最多 8 个字符
currencystring最多 8 个字符
devicestring最多 64 个字符
completion_ratenumber0–1
payloadobject自由格式 JSON,序列化后最多 4 KB

payload 是用于合作伙伴元数据的可选自由格式 JSON 对象。序列化大小不得超过 4,096 字节(4 KB),否则返回 validation_failed 和 值无效。。

发送单个事件

curl -X POST "https://signal-partners.newunivers.ai/v1/events" \
  -H "Authorization: Bearer nsp_live_xxx" \
  -H "X-NU-Partner-Id: org_acme" \
  -H "Accept-Language: zh-CN" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id": "evt_acme_0001",
    "event_type": "PAYMENT_COMPLETED",
    "title_id": "ttl_abc",
    "episode_id": "ep_001",
    "viewer_id_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "country": "KR",
    "device": "web",
    "revenue_amount": 3.99,
    "currency": "USD",
    "occurred_at": "2026-06-24T00:00:00Z"
  }'
{ "data": { "event_id": "evt_acme_0001", "status": "validated", "received_at": "2026-06-24T00:00:05.123Z" } }

单个事件摄取成功时返回 HTTP 200、status: "validated" 和 ISO-8601 received_at 时间戳。

重复

再次发送相同 event_id 会返回:

{
  "error": {
    "code": "duplicate_event_id",
    "message": "此事件 ID 已被接受。",
    "request_id": "req_..."
  }
}

验证错误

{
  "error": {
    "code": "validation_failed",
    "message": "请求验证失败。",
    "request_id": "req_...",
    "details": [
      {
        "field": "currency",
        "issue": "required",
        "message": "缺少必填值。"
      }
    ]
  }
}

批量事件

每次请求最多发送 500 个事件。每项独立验证;响应为 HTTP 207 并含逐项结果,因此即使部分失败,请求本身也可成功。

curl -X POST "https://signal-partners.newunivers.ai/v1/events/batch" \
  -H "Authorization: Bearer nsp_live_xxx" \
  -H "X-NU-Partner-Id: org_acme" \
  -H "Accept-Language: zh-CN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      { "event_id": "evt_1", "event_type": "EPISODE_STARTED", "title_id": "ttl_abc", "episode_id": "ep_001", "occurred_at": "2026-06-24T00:00:00Z" },
      { "event_id": "evt_1", "event_type": "EPISODE_STARTED", "title_id": "ttl_abc", "episode_id": "ep_001", "occurred_at": "2026-06-24T00:00:01Z" },
      { "event_id": "evt_3", "event_type": "PAYMENT_COMPLETED", "occurred_at": "2026-06-24T00:00:02Z" }
    ]
  }'
{
  "data": {
    "received": 3,
    "accepted": 1,
    "duplicated": 1,
    "failed": 1,
    "results": [
      { "event_id": "evt_1", "status": "accepted" },
      { "event_id": "evt_1", "status": "duplicated" },
      { "event_id": "evt_3", "status": "failed" }
    ]
  }
}

received 是提交数量(1–500)。每项的 status 必须是 accepted | duplicated | failed 之一。条目不包含 error_code 字段。

幂等性

服务端按 event_id 去重,使重试安全。重试时复用同一 event_id,并针对真实事件而非每次 HTTP 尝试生成它。在响应和请求日志中检查摄取状态。接受的事件存为 VALIDATED;重复 ID 成为 duplicated 空操作。收入事件进入 结算。