Seedance 素材库与真人认证
curl --request POST \
--url 'https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01' \
--header 'Authorization: <authorization>'import requests
url = "https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01"
headers = {"Authorization": "<authorization>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: '<authorization>'}};
fetch('https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body视频系列
Seedance 素材库与真人认证
Seedance 素材管理(Assets)与真人形象认证接口
POST
{llmApiOrigin}
/
seedance
/
api
/
v3
/
assets?Action=CreateAssetGroup&Version=2024-01-01
Seedance 素材库与真人认证
curl --request POST \
--url 'https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01' \
--header 'Authorization: <authorization>'import requests
url = "https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01"
headers = {"Authorization": "<authorization>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: '<authorization>'}};
fetch('https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/{{llmApiOrigin}}/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body简介
在 Seedance 视频生成中,涉及真人形象或需要复用素材的场景,要求先建立素材库并完成真人认证。shengmoai 提供与火山方舟素材管理 API 对齐的入口:POST /seedance/api/v3/assets?Action=<Action>&Version=2024-01-01
- 请求体使用方舟风格 PascalCase 字段;
- 由你的 API Key 鉴权,不感知渠道/供应商差异;
- 素材接口支持**素材库(AssetGroup)、素材(Asset)、真人形象认证(VisualValidateSession)**三类能力。
支持的动作
| Action | 说明 | 主要请求字段 |
|---|---|---|
CreateAssetGroup | 创建素材库 | Name、GroupType、Description |
GetAssetGroup | 查询素材库 | Id |
UpdateAssetGroup | 更新素材库名称 | Id、Name |
CreateAsset | 上传素材(URL 入库) | GroupId、URL、AssetType、Name |
ListAssets | 分页查询素材 | Filter、PageNumber、PageSize |
GetAsset | 查询单个素材 | Id |
UpdateAsset | 更新素材名称 | Id、Name |
DeleteAsset | 删除素材 | Id |
CreateVisualValidateSession | 创建真人认证会话 | CallbackURL |
GetVisualValidateResult | 换取认证结果素材库 | BytedToken |
Version 固定为 2024-01-01(默认值)。未知 Action 返回 UnsupportedAction。
认证
string
必填
Bearer Token,如
Bearer sk-xxxAuthorization: Bearer <API_KEY> 请求头,素材归属、OEM 隔离和权限都以该 Key 为准。
响应与错误
成功响应使用方舟格式,字段ResponseMetadata + Result:
{
"ResponseMetadata": {
"Action": "CreateAssetGroup",
"RequestId": "a1b2c3-d4e5-...",
"Version": "2024-01-01"
},
"Result": {
"Id": "grp-xxxx",
"Name": "我的素材库",
"GroupType": "image"
}
}
ResponseMetadata.Error 中返回(Code/Message),不要只根据 HTTP 状态判断成功——上游业务失败有时返回 HTTP 200:
{
"ResponseMetadata": {
"Action": "CreateAsset",
"Error": {
"Code": "InvalidParameter",
"Message": "AssetType must be Image, Video, or Audio"
}
}
}
MissingParameter、InvalidVersion、InvalidParameter、UnsupportedAction、RequestEntityTooLarge、InternalError。
素材库与素材
创建素材库
curl -X POST "https://api.shengmoai.com/seedance/api/v3/assets?Action=CreateAssetGroup&Version=2024-01-01" \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-d '{
"Name": "我的真人素材",
"GroupType": "image"
}'
上传素材(URL 入库)
图片、视频、音频素材通过 URL 入库(要求可被服务端访问的 http/https 绝对地址):curl -X POST "https://api.shengmoai.com/seedance/api/v3/assets?Action=CreateAsset&Version=2024-01-01" \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-d '{
"GroupId": "grp-xxxx",
"URL": "https://example.com/assets/me.png",
"AssetType": "image",
"Name": "我的形象照"
}'
AssetType支持image、video、audio(大小写均可);- 首期素材通过公有网络 URL 入库,暂不支持 multipart 直传;
- 素材状态异步处理,可能为
pending/active/failed——只有active的素材才能被生成任务引用; - 用
ListAssets查看状态,或GetAsset查询单个素材。
列出与查询素材
curl -X POST "https://api.shengmoai.com/seedance/api/v3/assets?Action=ListAssets&Version=2024-01-01" \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-d '{
"Filter": { "Statuses": ["active"] },
"PageNumber": 1,
"PageSize": 20
}'
Filter 支持:GroupIds[]、Statuses[]、GroupType、Name。Result.Items[] 中每个元素包含 Id、GroupId、AssetType、Status、URL、CreateTime 等字段。
更新与删除
UpdateAsset 与 DeleteAsset 使用素材 Id 归属校验后才调用上游;删除成功后素材不再可被任务引用。
引用素材生成视频(asset://)
素材库的素材经 asset:// 协议在 Seedance 任务中使用——内容数组里的 image_url / video_url / audio_url 的 url 传 asset://<素材ID> 即可,服务端会把 URI 原样透传给上游,不会改写或下载:
{
"model": "doubao-seedance-2-0-260128",
"content": [
{ "type": "text", "text": "让我的形象在镜头前挥手" },
{
"type": "image_url",
"role": "reference_image",
"image_url": { "url": "asset://6grp-image-xxx" }
}
]
}
- 只能在文本/图片/视频/音频的
url使用asset://;同一个任务引用的全部素材必须属于同一个渠道且对当前 API Key 可见; - 素材必须是
active状态,未激活、已删除或不属于该用户的素材会报错; - 其它渠道的素材 URI,或未知的
asset://ID,都会被拒绝。
真人认证(Visual Validate)
使用真人图片生成必须实名认证:流程是「创建会话 → 用户在 H5 完成验证 → 服务端回调通知你 → 换取结果」。1. 创建认证会话
curl -X POST "https://api.shengmoai.com/seedance/api/v3/assets?Action=CreateVisualValidateSession&Version=2024-01-01" \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-d '{
"CallbackURL": "https://your-domain.com/hook"
}'
CallbackURL必须是 HTTPS 绝对地址(会做 SSRF 防护),并且需要幂等——服务端可能重试交付回调;- 成功返回
Result.H5Link(真人认证 H5 页面,约 120 秒有效)与Result.BytedToken(会话凭证):
{
"ResponseMetadata": { "Action": "CreateVisualValidateSession" },
"Result": {
"H5Link": "https://auth.example.com/h5?...",
"BytedToken": "byt_xxxxxxxx"
}
}
2. 用户在 H5 页面完成认证
把H5Link 交给用户打开,按页面提示完成人脸验证。
3. 你的回调地址收到结果
认证完成(或失败)后,服务端会把结果以 GET 查询参数发送到你提供的CallbackURL:
<CallbackURL>?bytedToken=...&resultCode=10000&algorithmBaseRespCode=0&reqMeasureInfoValue=1&verify_type=real_time
resultCode=10000表示成功;其他值表示业务失败;- 收到回调不代表认证已完成,只是通知你「可以换取结果了」。
4. 换取认证结果素材库
带上你拿到的BytedToken 调 GetVisualValidateResult——成功后会创建(或返回)一个真人形象素材库(GroupId):
curl -X POST "https://api.shengmoai.com/seedance/api/v3/assets?Action=GetVisualValidateResult&Version=2024-01-01" \
-H "Authorization: Bearer sk-xxx" \
-H "Content-Type: application/json" \
-d '{ "BytedToken": "byt-xxxx" }'
{
"Result": {
"GroupId": "6grp-identity-xxx",
"Name": "realperson",
"GroupType": "identity"
}
}
CreateAsset(URL 入库)上传到这个 GroupId 素材库,之后即可在视频任务里用 asset://<素材Id> 引用它。
常见问题
- 超时:
H5Link/BytedToken约 120 秒失效,用户未在时限内完成认证则报错,需要重新 CreateVisualValidateSession;服务端会话保留 30 分钟用于回调重试,但前端还是以 120 秒为基准引导用户。 - 幂等:重复成功回调不会重复创建素材库;你可重复使用同一个
task/BydtedToken领取结果(成功领取后会删除会话)。 - 不允许:把
CallbackURL设为不放行域名,或非 https。
错误与调试
| 场景 | 现象 |
|---|---|
缺少 Action | MissingParameter: Action is required |
Version 不匹配 | InvalidVersion |
| 未知 Action | UnsupportedAction |
GroupId 不属于当前用户 | InvalidParameter / 归属错误 |
Type 不是 Image/Video/Audio | InvalidParameter |
asset:// 引用不存在的素材 | 提交失败(如 asset xxx is not available) |
| 引用未激活素材 | asset xxx is not active |
| 素材属不同渠道/厂商 | asset references must use the same channel |
相关页面
Seedance 官方接口
视频生成任务、查询与下载
视频生成总览
异步流程与入口选择
