실제 인물 에셋 API
API 호출자는 YingTu에 로그인하지 않지만 실제 인물 본인은 공식 H5에서 신원, 동의 및 라이브니스 인증을 완료해야 합니다.
엔드포인트
Base 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 API Key를 Authorization: Bearer <LAOZHANG_API_KEY>로 전송합니다.
| 헤더 | 필수 | 설명 |
|---|---|---|
Authorization | 가능 | Bearer 인증으로 전송하는 LaoZhang API Key. |
Content-Type | POST만 | 생성 작업은 application/json을 사용합니다. |
요청
POST /api/seedance-assets/real-persons/verifications
| 필드 | 필수 | 설명 |
|---|---|---|
callback_url | 필수 | 인증 완료 후 열리는 HTTPS URL. |
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 Key 소유여야 합니다. |
image_url | 필수 | 동일 인물의 선명한 정면 이미지를 가리키는 공개 HTTPS URL. |
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"
}인증 콜백
GET https://customer.example.com/seedance/verified
?verification_id=ver_eyJvcGFxdWUiOiJleGFtcGxlIn0
&result_code=10000result_code=10000은 공식 H5 흐름 완료를 의미합니다. 이후 GET과 POST에는 callback Location의 verification_id를 사용하세요. pending GET은 HTTP 200, 이른 에셋 POST는 HTTP 409, 만료된 ID는 HTTP 410입니다. 콜백은 BytedToken을 노출하지 않습니다.
공식 인증 페이지 언어
공식 문서에는 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 Key가 없거나 유효하지 않거나 비활성화되었습니다. | 불가 |
| 403 | resource_not_owned | 인증 또는 에셋이 현재 API Key 소유가 아니거나 공개 ID가 잘못되었습니다. | 불가 |
| 403 | capability_unavailable | 서비스 계정에 비공개 인물 에셋 권한이 활성화되지 않았습니다. | 불가 |
| 409 | verification_pending | 인증이 pending일 때 POST /real-persons에서만 반환됩니다. GET 상태 조회는 HTTP 200과 status=pending을 반환합니다. | 가능 |
| 410 | verification_expired | GET 인증 상태 또는 POST /real-persons 요청에서 30분 유효 기간이 지난 verification_id를 사용했습니다. | 불가 |
| 413 | payload_too_large | JSON 요청 본문이 16KB를 초과했습니다. | 불가 |
| 415 | unsupported_media_type | POST 요청의 Content-Type이 application/json이 아닙니다. | 불가 |
| 429 | rate_limit_exceeded | 현재 API Key의 호출 한도에 도달했습니다. | 가능 |
| 500 | internal_error | 서비스가 요청을 완료하지 못했습니다. | 불가 |
| 502 | upstream_error | 업스트림 에셋 또는 인증 서비스 오류입니다. | 가능 |
| 503 | authentication_unavailable | API Key 검증 서비스를 일시적으로 사용할 수 없습니다. | 가능 |
| 503 | service_unavailable | 에셋 API의 서버 설정을 일시적으로 사용할 수 없습니다. | 가능 |
{
"error": {
"code": "invalid_request",
"message": "image_url is required.",
"request_id": "req_01JZEXAMPLE",
"retryable": false
}
}요청 제한 및 추적
API Key당 생성 POST 요청은 시간당 최대 12회이며 GET 상태 조회는 계산하지 않습니다. 업스트림 권한에 따른 추가 제한이 있을 수 있습니다. 제한 시 429와 Retry-After를 반환합니다.
모든 성공 및 오류 응답에는 request_id가 포함됩니다. 지원 문의 시 이 값을 제공하고 전체 API Key는 보내지 마세요.
X-RateLimit-Limit: <limit>
X-RateLimit-Remaining: <remaining>
X-RateLimit-Reset: <unix-seconds>
Retry-After: <seconds>