API ассета реального человека
Клиент API не входит в YingTu, но изображённый человек обязан пройти подтверждение личности, согласие и liveness-проверку на официальной H5-странице.
Эндпоинт
Базовый URL
https://yingtu.aiPOST /api/seedance-assets/real-persons/verificationsGET /api/seedance-assets/real-persons/verifications/{verification_id}POST /api/seedance-assets/real-personsGET /api/seedance-assets/real-persons/{id}Аутентификация
Вход в YingTu или Google не требуется. Используйте ключ LaoZhang в заголовке Authorization: Bearer <LAOZHANG_API_KEY>.
| Заголовок | Обязательно | Описание |
|---|---|---|
Authorization | Да | Ключ LaoZhang с Bearer-аутентификацией. |
Content-Type | Только POST | Для операций создания используется application/json. |
Запрос
POST /api/seedance-assets/real-persons/verifications
| Поле | Обязательно | Описание |
|---|---|---|
callback_url | Да | HTTPS-адрес, открываемый после проверки. |
language | Нет | Язык H5: zh, en или zh-Hant. По умолчанию zh. |
GET /api/seedance-assets/real-persons/verifications/{verification_id}
| Поле | Обязательно | Описание |
|---|---|---|
verification_id | Да | Параметр пути из ответа создания проверки. |
POST /api/seedance-assets/real-persons
| Поле | Обязательно | Описание |
|---|---|---|
verification_id | Да | Статус verified, владелец — тот же API-ключ. |
image_url | Да | Публичный HTTPS-адрес чёткого фронтального изображения того же человека. |
name | Нет | Имя ассета, до 64 символов. |
Запрос создания
curl --request POST \
--url https://yingtu.ai/api/seedance-assets/real-persons/verifications \
--header "Authorization: Bearer $LAOZHANG_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"callback_url": "https://customer.example.com/seedance/verified",
"language": "en"
}'curl --request GET \
--url https://yingtu.ai/api/seedance-assets/real-persons/verifications/ver_eyJvcGFxdWUiOiJleGFtcGxlIn0 \
--header "Authorization: Bearer $LAOZHANG_API_KEY"curl --request POST \
--url https://yingtu.ai/api/seedance-assets/real-persons \
--header "Authorization: Bearer $LAOZHANG_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"verification_id": "ver_eyJvcGFxdWUiOiJleGFtcGxlIn0",
"image_url": "https://cdn.example.com/presenter.webp",
"name": "presenter-a"
}'Пример ответа
HTTP/1.1 201 Created
Content-Type: application/json
{
"request_id": "req_01JZEXAMPLE",
"verification_id": "ver_eyJvcGFxdWUiOiJleGFtcGxlIn0",
"status": "requires_user_action",
"verification_url": "https://official-h5.example/?...&lng=en",
"callback_url": "https://customer.example.com/seedance/verified",
"expires_at": "2026-07-29T05:30:00.000Z"
}{
"request_id": "req_01JZEXAMPLE",
"verification_id": "ver_eyJvcGFxdWUiOiJleGFtcGxlIn0",
"status": "pending",
"expires_at": "2026-07-29T05:30:00.000Z"
}{
"request_id": "req_01JZEXAMPLE",
"verification_id": "ver_eyJvcGFxdWUiOiJleGFtcGxlIn0",
"status": "verified",
"expires_at": "2026-07-29T05:30:00.000Z"
}{
"error": {
"code": "verification_pending",
"message": "The represented person has not completed verification.",
"request_id": "req_01JZEXAMPLE",
"retryable": true
}
}{
"error": {
"code": "verification_expired",
"message": "The verification session expired. Create a new session.",
"request_id": "req_01JZEXAMPLE",
"retryable": false
}
}{
"request_id": "req_01JZEXAMPLE",
"id": "ast_eyJvcGFxdWUiOiJleGFtcGxlIn0",
"object": "seedance.asset",
"kind": "real_person",
"name": "presenter-a",
"status": "Processing",
"uri": "asset://asset-20260729-example"
}Callback проверки
GET https://customer.example.com/seedance/verified
?verification_id=ver_eyJvcGFxdWUiOiJleGFtcGxlIn0
&result_code=10000result_code=10000 означает завершение официального H5-процесса. Для следующих GET и POST используйте verification_id из Location callback: pending при GET возвращает HTTP 200, ранний POST ассета — HTTP 409, истёкший ID — HTTP 410. BytedToken в callback не раскрывается.
Языки официальной страницы проверки
Официально указаны только lng=zh, lng=en и lng=zh-Hant; по умолчанию используется zh. API добавляет выбранный language в возвращаемую ссылку.
Рекомендуемое сопоставление: zh→zh, en→en, ru/ja/ko/es→en. Для традиционного китайского — zh-Hant. Русская, японская, корейская и испанская страницы официально не заявлены.
zh → lng=zh
en → lng=en
ru / ja / ko / es → lng=en
Traditional Chinese → lng=zh-HantПримеры кода
const headers = {
Authorization: `Bearer ${process.env.LAOZHANG_API_KEY}`,
"Content-Type": "application/json",
};
const begin = await fetch("https://yingtu.ai/api/seedance-assets/real-persons/verifications", {
method: "POST",
headers,
body: JSON.stringify({
callback_url: "https://customer.example.com/seedance/verified",
language: "en",
}),
});
if (!begin.ok) throw new Error(await begin.text());
const session = await begin.json();
const verificationUrl = session.verification_url;
// Deliver verificationUrl only to the represented person's authenticated UI.
// Do not log or persist this short-lived URL.
// After the represented person finishes the official H5 flow:
const callbackVerificationId =
"<verification_id received at your callback URL>";
const verified = await fetch(
`https://yingtu.ai/api/seedance-assets/real-persons/verifications/${callbackVerificationId}`,
{ headers: { Authorization: headers.Authorization } },
).then((response) => response.json());
if (verified.status === "verified") {
const asset = await fetch("https://yingtu.ai/api/seedance-assets/real-persons", {
method: "POST",
headers,
body: JSON.stringify({
verification_id: callbackVerificationId,
image_url: "https://cdn.example.com/presenter.webp",
name: "presenter-a",
}),
}).then((response) => response.json());
console.log(asset);
}import os
import requests
endpoint = "https://yingtu.ai/api/seedance-assets/real-persons"
verification_endpoint = f"{endpoint}/verifications"
headers = {"Authorization": f"Bearer {os.environ['LAOZHANG_API_KEY']}"}
session = requests.post(
verification_endpoint,
headers=headers,
json={
"callback_url": "https://customer.example.com/seedance/verified",
"language": "en",
},
timeout=30,
)
session.raise_for_status()
verification = session.json()
verification_url = verification["verification_url"]
# Deliver verification_url only to the represented person's authenticated UI.
# Do not log or persist this short-lived URL.
# Run this after the represented person completes the official H5 flow.
callback_verification_id = "<verification_id received at your callback URL>"
status = requests.get(
f"{verification_endpoint}/{callback_verification_id}",
headers=headers,
timeout=30,
)
status.raise_for_status()
if status.json()["status"] == "verified":
asset = requests.post(
endpoint,
headers=headers,
json={
"verification_id": callback_verification_id,
"image_url": "https://cdn.example.com/presenter.webp",
"name": "presenter-a",
},
timeout=60,
)
asset.raise_for_status()
print(asset.json())Проверка статуса ассета
curl --request GET \
--url https://yingtu.ai/api/seedance-assets/real-persons/ast_eyJvcGFxdWUiOiJleGFtcGxlIn0 \
--header "Authorization: Bearer $LAOZHANG_API_KEY"HTTP/1.1 200 OK
Content-Type: application/json
{
"request_id": "req_01JZEXAMPLE",
"id": "ast_eyJvcGFxdWUiOiJleGFtcGxlIn0",
"object": "seedance.asset",
"kind": "real_person",
"status": "Active",
"uri": "asset://asset-20260729-example",
"created_at": "2026-07-29T05:00:00Z",
"updated_at": "2026-07-29T05:01:00Z"
}{
"request_id": "req_01JZEXAMPLE",
"id": "ast_eyJvcGFxdWUiOiJleGFtcGxlIn0",
"object": "seedance.asset",
"kind": "real_person",
"status": "Failed",
"uri": "asset://asset-20260729-example",
"failure": {
"code": "InvalidImage",
"message": "The image did not pass upstream validation."
}
}Ошибки
| HTTP-статус | Код ошибки | Описание | Повтор |
|---|---|---|---|
| 400 | invalid_request | Недопустимое тело запроса, поле или значение. | Нет |
| 401 | invalid_api_key | API-ключ отсутствует, недействителен или отключён. | Нет |
| 403 | resource_not_owned | Проверка или ассет не принадлежит этому API-ключу либо публичный ID недействителен. | Нет |
| 403 | capability_unavailable | Для сервисного аккаунта не включены приватные портретные ассеты. | Нет |
| 409 | verification_pending | Возвращается только POST /real-persons при статусе pending; GET-проверка состояния возвращает HTTP 200 и status=pending. | Да |
| 410 | verification_expired | GET состояния проверки или POST /real-persons использовал verification_id старше 30 минут. | Нет |
| 413 | payload_too_large | JSON-запрос превышает 16 КБ. | Нет |
| 415 | unsupported_media_type | POST-запрос отправлен не как application/json. | Нет |
| 429 | rate_limit_exceeded | Достигнут лимит запросов для API-ключа. | Да |
| 500 | internal_error | Сервис не смог выполнить запрос. | Нет |
| 502 | upstream_error | Ошибка вышестоящего сервиса ассетов или проверки. | Да |
| 503 | authentication_unavailable | Проверка API-ключа временно недоступна. | Да |
| 503 | service_unavailable | Серверная конфигурация API ассетов временно недоступна. | Да |
{
"error": {
"code": "invalid_request",
"message": "image_url is required.",
"request_id": "req_01JZEXAMPLE",
"retryable": false
}
}Лимиты и трассировка
Для каждого API-ключа разрешено до 12 POST-запросов создания в час; GET-проверки не учитываются. Права провайдера могут добавлять лимиты. При ограничении возвращаются 429 и Retry-After.
Каждый ответ содержит request_id. Передавайте его поддержке, но не отправляйте полный API-ключ.
X-RateLimit-Limit: <limit>
X-RateLimit-Remaining: <remaining>
X-RateLimit-Reset: <unix-seconds>
Retry-After: <seconds>