真人活体认证
真人活体认证用于把需要绑定特定真人身份的私域素材放入受限素材组。它是素材组级认证流程,不是普通文件上传,也不会在认证完成时自动创建 asset_xxx。
流程概览
- 使用
POST /v1/visual-validate-sessions创建一次性认证会话。 - 在最终用户设备上打开返回的
h5_link,完成真人活体操作。 - 使用
POST /v1/visual-validate-results轮询会话状态,直到返回completed。 - 保存完成结果中的
group_id。认证组可能暂时没有任何素材,这是正常状态。 - 使用该
group_id调用POST /v1/assets/uploads上传需要绑定的图片、视频或音频;上传成功后才会得到 MoonApiX 的asset_id和Asset://asset_xxx。 - 在支持该素材的生成请求中显式传入
Asset://asset_xxx,并按目标模型查询素材准备状态。
认证会话有效期为 30 分钟。h5_link 是一次性、短期链接,只应交给最终用户打开,不要写入日志、公开页面或长期业务数据。
1. 创建认证会话
POST /v1/visual-validate-sessionscurl https://moonapix.com/v1/visual-validate-sessions \
-H "Authorization: Bearer <MOONAPIX_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0-sz",
"callback_url": "https://client.example.com/visual-validate/callback"
}'请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | 当前 API Key 已获授权且存在可用于活体认证的可用路由的目标模型;否则创建会话会返回 503。 |
callback_url | string | 是 | HTTPS 回调地址。该地址会作为认证回调参数传递;客户端仍必须轮询结果接口。 |
响应示例
{
"object": "visual_validate_session",
"session_id": "vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd",
"h5_link": "https://example.com/one-time-link",
"expires_at": 1710001800
}客户端只需要保存创建响应里的 session_id 和 expires_at,并把 h5_link 交给最终用户。轮询时必须原样传回该 session_id;不要在服务端日志中打印完整链接。
2. 打开 H5 完成认证
在用户设备的浏览器或 WebView 中打开 h5_link。用户完成页面要求的活体动作后,回到业务系统继续查询结果。链接过期、重复使用或会话超过 30 分钟时,应重新创建会话;不要复用旧链接。
3. 查询认证结果
POST /v1/visual-validate-resultscurl https://moonapix.com/v1/visual-validate-results \
-H "Authorization: Bearer <MOONAPIX_API_KEY>" \
-H "Content-Type: application/json" \
-d '{"session_id":"vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd"}'处理中:
{
"object": "visual_validate_result",
"session_id": "vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd",
"status": "pending"
}认证完成:
{
"object": "visual_validate_result",
"session_id": "vvs_0123456789abcdefghijklmnopqrstuvwxyzabcd",
"status": "completed",
"group_id": "group_xxx",
"upstream": {
"group_id": "group-official-example"
}
}完成结果是一个 MoonApiX group_id,不是 asset_id。认证会先建立一个私有素材组;该组初始可以为空,因此用 GET /v1/assets?group_id=group_xxx 查到 total=0 并不表示认证失败。对同一个已完成会话重复查询会返回相同的 group_id。
完成结果可同时返回 upstream.group_id,表示该认证组的火山官方组 ID。上传、查询和生成继续使用顶层 MoonApiX group_id / asset_id。需要用官方组 ID 找回自己的 MoonApiX 组时,调用素材 ID 解析,传会话对应的同一个公开 model。pending 状态不返回素材组,请继续等待最终用户完成认证。
会话只属于创建它的 API 用户。会话不存在、过期或由其他用户查询时返回 404。认证路由不可用时返回 409,认证服务暂时不可用时会返回服务错误。
4. 上传认证组内素材
认证完成后,使用返回的 group_id 上传实际要使用的媒体。上传请求必须带目标模型;purpose 和 role 建议明确写成生成请求中的素材角色。
curl https://moonapix.com/v1/assets/uploads \
-H "Authorization: Bearer <MOONAPIX_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0-sz",
"mode": "asset",
"type": "image",
"purpose": "reference_image",
"role": "reference_image",
"group_id": "group_xxx",
"url": "https://example.com/your-reference.png"
}'上传成功后响应会包含类似以下公共身份:
asset_id = asset_xxx
asset_ref = Asset://asset_xxx
group_id = group_xxx认证组只接受属于当前用户且符合目标模型能力的素材。上传时只能使用本接口返回的 group_id;页面或其他接口中的标识不能代替它。
5. 在生成请求中使用
先查询目标模型的素材详情,确认 asset.status=ready,并且 preparation.status 为 ready 或 not_required、preparation.generation_ready=true。然后在生成请求中显式传入 Asset://asset_xxx:
{
"model": "seedance-2.0-sz",
"prompt": "让 @person 自然转身,保持身份和服装一致。",
"references": [
{
"media_type": "image",
"role": "reference_image",
"url": "Asset://asset_xxx",
"alias": "person"
}
],
"duration": 5,
"size": "720p",
"aspect_ratio": "16:9"
}普通图片、视频和音频不需要真人活体认证,直接使用普通素材上传即可。活体认证也不代表任何内容都能生成;目标模型的能力限制和内容安全审核仍然适用。
常见错误
| HTTP 状态 | code | 说明 |
|---|---|---|
400 | invalid_json / model_required / invalid_callback_url | 创建会话时,请求体、模型或回调地址不符合要求;查询接口的无效 JSON 也返回此状态。 |
403 | model_access_denied | 当前 API Key 没有目标模型权限。 |
404 | session_not_found | 查询时缺少或使用了格式错误、未知、过期或属于其他用户的 session_id。 |
409 | session_route_unavailable | 查询结果时,会话绑定的认证路由或凭证已经不可用。 |
500 | session_creation_failed / result_persist_failed | 创建会话或保存认证结果时,服务端无法生成或持久化必要状态。 |
502 | — | 认证服务未能完成会话创建或结果查询。 |
503 | session_store_unavailable / visual_validation_unavailable | 会话存储暂时不可用,或当前模型没有可用的活体认证路由。 |