# 真人扫码活体流程

真人活体认证是开通"真人数字人"能力的前置步骤：终端用户扫码完成一次火山引擎的活体采集后，对应的 `AssetGroup` 会绑定到当前 API 调用方的用户下，后续视频生成接口就能通过 `asset://<groupId>` 引用这个真人。

整套流程只涉及火山引擎必要的两个请求接口，按顺序调用即可。

## 前置要求

调用以下接口需满足：

| 条件 | 来源 |
|---|---|
| 账号开通 **可信创作者（trusted_creator）** | 控制台提交申请 |
| 账号通过 **企业认证** | 控制台提交企业资料 |

以上由平台审核，一次性完成，无需在每次调用时重复处理。

## 步骤

### 1. 发起扫码会话

```bash
curl -X POST -H "Authorization: Bearer tr-xxx" \
  https://api.xrtoken.ai/v1/asset-groups/validate-session
```

```json
{
  "BytedToken": "eyJhbGci...",
  "RedirectURL": "https://openspeech.bytedance.com/ark/liveness?...",
  "QRCodeDataURL": "data:image/png;base64,iVBOR...",
  "ExpiresIn": 120
}
```

把 `QRCodeDataURL` 直接塞到 `<img src>`。用户手机扫码后跳转到火山 H5 完成活体采集。

### 2. 轮询结果

用上一步拿到的 `BytedToken`，建议 **每 5 秒** 轮询一次，直到终态或 120 秒超时：

```bash
curl -X POST -H "Authorization: Bearer tr-xxx" \
  -H "Content-Type: application/json" \
  -d '{"bytedToken":"eyJhbGci..."}' \
  https://api.xrtoken.ai/v1/asset-groups/validate-result
```

三种终态：

| 终态 | 响应体 |
|---|---|
| 成功 | 包含 `GroupId` + `status: "active"` |
| 失败 | 包含 `ResponseMetadata.Error` |
| 进行中 | 无 `GroupId`，继续轮询 |

一旦拿到 `GroupId`，该真人组已绑定到当前用户，后续 `POST /v1/videos/generations` 里就能 `asset://<GroupId>` 引用了。

一个 API key 服务多个最终用户时，创建会话和轮询都要带同一个 `external_user_id`。请求示例见 [素材库 · external_user_id](/docs/asset-library#external-user-id)。

## 常见错误

| 错误码 | 原因 | 处理 |
|---|---|---|
| 403 `tier_insufficient` | 未开通可信创作者 | 去控制台申请 |
| 403 `enterprise_required` | 未完成企业认证 | 补交企业资料 |
| 502 `upstream_error` | 火山侧临时故障 | 重试 |
