素材库 Assets API
素材库(Assets)API 用于创建、管理人像素材资产,供视频生成模型(如 Seedance)作为参考图使用。
版本说明
| 版本 | Base URL | 鉴权方式 | 说明 |
|---|---|---|---|
| 国内版 | https://open.volcengineapi.com | AK/SK 签名 | 火山引擎 Ark 素材库接口 |
| 海外版 | https://api.agentsflare.com/byteplus/_unstable/open | Bearer Token | Agentsflare 海外节点接口 |
国内版 API
基础信息
- Region:
cn-beijing - Service:
ark - Version:
2024-01-01 - 鉴权: 火山引擎 Access Key (AK/SK)
图像要求
上传素材资产时需满足以下条件:
| 项目 | 要求 |
|---|---|
| 格式 | jpeg、png、webp、bmp、tiff、gif、heic/heif |
| 宽高比 | 宽/高在 (0.4, 2.5) 范围内 |
| 宽高长度 | 单边在 (300, 6000) 像素范围内 |
| 大小 | 单张图片小于 30 MB |
| 内容合规 | 不得包含未授权商标、不得与自然人肖像雷同、不得违反法规 |
限流说明
| 接口 | 账号维度 QPS | 并发说明 |
|---|---|---|
| CreateAssetGroup | 30 | 同时处理中的创建任务不超过 30 个 |
| CreateAsset | 30 | 同上 |
| ListAssetGroups | 30 | — |
| ListAssets | 30 | — |
| GetAsset | 100 | — |
| GetAssetGroup | 100 | — |
| UpdateAsset | 30 | — |
| UpdateAssetGroup | 30 | — |
核心接口
CreateAssetGroup
创建素材资产组合(Asset Group),用于对同一项目或人物的素材进行统一管理。
POST /open/CreateAssetGroup
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| Name | 是 | string | 组合名称,上限 64 字符 |
| Description | 否 | string | 组合描述,上限 300 字符 |
| GroupType | 否 | string | 组合类型,可选 AIGC(虚拟人像) |
| ProjectName | 否 | string | 所属项目,默认 default |
返回参数
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | string | Asset Group 的 Id |
CreateAsset
向指定 Asset Group 内创建素材资产。
POST /open/CreateAsset
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| GroupId | 是 | string | 所属 Asset Group 的 Id |
| URL | 是 | string | 素材的公共可访问地址 |
| Name | 否 | string | 素材名称,上限 64 字符 |
| AssetType | 是 | string | 素材类型,目前仅支持 Image |
| ProjectName | 否 | string | 所属项目,默认 default |
返回参数
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | string | Asset 的 Id |
GetAsset
查询单个素材资产信息,可用于轮询素材预处理状态。
POST /open/GetAsset
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| Id | 是 | string | Asset 的 Id |
| ProjectName | 否 | string | 所属项目,默认 default |
返回参数
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | string | Asset 的 Id |
| Name | string | Asset 名称 |
| URL | string | 访问地址(有效期 12 小时) |
| AssetType | string | Image |
| GroupId | string | 所属 Group Id |
| Status | string | Active / Processing / Failed |
| Error | object | 错误信息(含 Code、Message) |
| CreateTime | string | 创建时间 |
| UpdateTime | string | 更新时间 |
| ProjectName | string | 所属项目 |
其他管理接口
| 接口 | 路径 | 说明 |
|---|---|---|
| ListAssetGroups | POST /open/ListAssetGroups | 查询素材组合列表,支持分页与筛选 |
| ListAssets | POST /open/ListAssets | 查询素材列表,支持按 GroupId、Status、Name 筛选 |
| GetAssetGroup | POST /open/GetAssetGroup | 查询单个素材组合信息 |
| UpdateAssetGroup | POST /open/UpdateAssetGroup | 更新素材组合(仅支持 Name、Description) |
| UpdateAsset | POST /open/UpdateAsset | 更新素材(仅支持 Name) |
代码示例(国内版)
以下示例演示创建素材组合 → 上传素材 → 轮询状态直至 Active 的完整链路。
bash
# 国内版使用 AK/SK 签名鉴权,建议通过以下 Python 脚本直接调用。
# 如需纯 curl,可先用 Python 生成带签名的请求头后再执行。
python3 << 'PYEOF'
import json, hmac, hashlib, datetime, urllib.request
AK = "<YOUR_AK>"
SK = "<YOUR_SK>"
REGION = "cn-beijing"
SERVICE = "ark"
HOST = "open.volcengineapi.com"
def sign_request(method, uri, body_dict):
body = json.dumps(body_dict, separators=(',', ':'), ensure_ascii=False)
now = datetime.datetime.utcnow()
x_date = now.strftime('%Y%m%dT%H%M%SZ')
date_stamp = now.strftime('%Y%m%d')
credential_scope = f"{date_stamp}/{REGION}/{SERVICE}/request"
body_hash = hashlib.sha256(body.encode('utf-8')).hexdigest()
canonical_headers = f"host:{HOST}\nx-date:{x_date}\n"
signed_headers = "host;x-date"
canonical_request = f"{method}\n{uri}\n\n{canonical_headers}\n{signed_headers}\n{body_hash}"
string_to_sign = f"HMAC-SHA256\n{x_date}\n{credential_scope}\n{hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()}"
k_date = hmac.new(f"VolcEngine{SK}".encode('utf-8'), date_stamp.encode('utf-8'), hashlib.sha256).digest()
k_region = hmac.new(k_date, REGION.encode('utf-8'), hashlib.sha256).digest()
k_service = hmac.new(k_region, SERVICE.encode('utf-8'), hashlib.sha256).digest()
k_signing = hmac.new(k_service, b"request", hashlib.sha256).digest()
signature = hmac.new(k_signing, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest()
auth = f"HMAC-SHA256 Credential={AK}/{credential_scope}, SignedHeaders={signed_headers}, Signature={signature}"
req = urllib.request.Request(
f"https://{HOST}{uri}",
data=body.encode('utf-8'),
headers={
"Content-Type": "application/json",
"X-Date": x_date,
"Host": HOST,
"Authorization": auth
},
method=method
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read().decode('utf-8'))
# 1. 创建素材组合
group_resp = sign_request("POST", "/open/CreateAssetGroup", {
"Name": "my-character-group",
"Description": "Character assets for Seedance",
"GroupType": "AIGC"
})
print("CreateAssetGroup:", json.dumps(group_resp, indent=2, ensure_ascii=False))
# 2. 创建素材资产(替换为实际 URL)
asset_resp = sign_request("POST", "/open/CreateAsset", {
"GroupId": group_resp.get("Result", {}).get("Id", ""),
"URL": "https://example.com/your-image.png",
"AssetType": "Image",
"Name": "character-01"
})
print("CreateAsset:", json.dumps(asset_resp, indent=2, ensure_ascii=False))
# 3. 轮询查询素材状态
asset_id = asset_resp.get("Result", {}).get("Id", "")
import time
for _ in range(40):
time.sleep(3)
get_resp = sign_request("POST", "/open/GetAsset", {"Id": asset_id})
status = get_resp.get("Result", {}).get("Status", "")
print(f"Status: {status}")
if status == "Active":
print("Asset is ready:", json.dumps(get_resp, indent=2, ensure_ascii=False))
break
elif status == "Failed":
print("Asset processing failed")
break
PYEOFpython
import json
import hmac
import hashlib
import datetime
import time
import urllib.request
AK = "<YOUR_AK>"
SK = "<YOUR_SK>"
REGION = "cn-beijing"
SERVICE = "ark"
HOST = "open.volcengineapi.com"
def sign_request(method: str, uri: str, body_dict: dict) -> dict:
body = json.dumps(body_dict, separators=(',', ':'), ensure_ascii=False)
now = datetime.datetime.utcnow()
x_date = now.strftime('%Y%m%dT%H%M%SZ')
date_stamp = now.strftime('%Y%m%d')
credential_scope = f"{date_stamp}/{REGION}/{SERVICE}/request"
body_hash = hashlib.sha256(body.encode('utf-8')).hexdigest()
canonical_headers = f"host:{HOST}\nx-date:{x_date}\n"
signed_headers = "host;x-date"
canonical_request = (
f"{method}\n{uri}\n\n{canonical_headers}\n"
f"{signed_headers}\n{body_hash}"
)
string_to_sign = (
f"HMAC-SHA256\n{x_date}\n{credential_scope}\n"
f"{hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()}"
)
k_date = hmac.new(
f"VolcEngine{SK}".encode('utf-8'),
date_stamp.encode('utf-8'), hashlib.sha256
).digest()
k_region = hmac.new(k_date, REGION.encode('utf-8'), hashlib.sha256).digest()
k_service = hmac.new(k_region, SERVICE.encode('utf-8'), hashlib.sha256).digest()
k_signing = hmac.new(k_service, b"request", hashlib.sha256).digest()
signature = hmac.new(
k_signing, string_to_sign.encode('utf-8'), hashlib.sha256
).hexdigest()
auth = (
f"HMAC-SHA256 Credential={AK}/{credential_scope}, "
f"SignedHeaders={signed_headers}, Signature={signature}"
)
req = urllib.request.Request(
f"https://{HOST}{uri}",
data=body.encode('utf-8'),
headers={
"Content-Type": "application/json",
"X-Date": x_date,
"Host": HOST,
"Authorization": auth,
},
method=method,
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read().decode('utf-8'))
def create_asset_group(name: str, description: str = "") -> str:
resp = sign_request("POST", "/open/CreateAssetGroup", {
"Name": name,
"Description": description,
"GroupType": "AIGC",
})
return resp.get("Result", {}).get("Id", "")
def create_asset(group_id: str, image_url: str, name: str = "") -> str:
resp = sign_request("POST", "/open/CreateAsset", {
"GroupId": group_id,
"URL": image_url,
"AssetType": "Image",
"Name": name,
})
return resp.get("Result", {}).get("Id", "")
def poll_asset_active(asset_id: str, timeout_sec: int = 120, interval_sec: int = 3) -> dict:
deadline = time.time() + timeout_sec
while time.time() < deadline:
resp = sign_request("POST", "/open/GetAsset", {"Id": asset_id})
status = resp.get("Result", {}).get("Status", "")
if status == "Active":
return resp
if status == "Failed":
raise RuntimeError(f"Asset processing failed: {resp}")
time.sleep(interval_sec)
raise TimeoutError("Polling asset status timed out")
if __name__ == "__main__":
# 1. 创建素材组合
group_id = create_asset_group("my-character-group", "For Seedance video gen")
print(f"GroupId: {group_id}")
# 2. 上传素材
asset_id = create_asset(
group_id,
"https://example.com/your-image.png",
"character-01"
)
print(f"AssetId: {asset_id}")
# 3. 轮询等待素材就绪
result = poll_asset_active(asset_id)
print("Asset ready:", json.dumps(result, indent=2, ensure_ascii=False))
# 4. 在视频生成 API 中使用
# 将素材 Id 按 Asset://<Asset_Id> 的格式拼接成 URL
asset_url = f"Asset://{asset_id}"
print(f"Use in video gen: {asset_url}")在视频生成中使用素材
当素材状态为 Active 后,将素材 Id 按 Asset://<Asset_Id> 格式拼接成 URL,在视频生成 API(如 Seedance 2.0)的请求中作为 image_url 传入:
json
{
"type": "image_url",
"image_url": {
"url": "Asset://Asset-2026********-*****"
},
"role": "reference_image"
}海外版 API
基础信息
- Base URL:
https://api.agentsflare.com/byteplus/_unstable/open - 鉴权:
Authorization: Bearer <API_KEY> - 内容类型:
application/json
CreateAsset
创建素材资产。
POST /byteplus/_unstable/open/CreateAsset
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| Name | 否 | string | 素材名称 |
| URL | 是 | string | 素材公共可访问地址 |
| AssetType | 是 | string | 素材类型,目前仅支持 Image |
返回参数
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | string | Asset 的 Id |
| base_resp.status_code | int | 0 表示成功 |
| base_resp.status_msg | string | 状态信息 |
GetAsset
查询素材资产信息。
POST /byteplus/_unstable/open/GetAsset
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
| Id | 是 | string | Asset 的 Id |
返回参数
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | string | Asset 的 Id |
| Status | string | Active / Processing / Failed |
| AssetType | string | Image |
| Name | string | 素材名称 |
| URL | string | 访问地址(有效期 12 小时) |
| CreateTime | string | 创建时间 |
| UpdateTime | string | 更新时间 |
| base_resp.status_code | int | 0 表示成功 |
| base_resp.status_msg | string | 状态信息 |
代码示例(海外版)
bash
# 创建素材
export API_KEY="your_api_key"
curl -X POST "https://api.agentsflare.com/byteplus/_unstable/open/CreateAsset" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"Name": "test asset",
"URL": "https://static.example.com/character.png",
"AssetType": "Image"
}'
# 查询素材状态
curl -X POST "https://api.agentsflare.com/byteplus/_unstable/open/GetAsset" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"Id": "asset-20260602115008-vvd9q"
}'python
import time
import requests
API_KEY = "your_api_key"
BASE_URL = "https://api.agentsflare.com/byteplus/_unstable/open"
HEADERS = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}",
}
def create_asset(name: str, image_url: str) -> str:
resp = requests.post(
f"{BASE_URL}/CreateAsset",
headers=HEADERS,
json={"Name": name, "URL": image_url, "AssetType": "Image"},
)
resp.raise_for_status()
data = resp.json()
if data.get("base_resp", {}).get("status_code") != 0:
raise RuntimeError(f"CreateAsset failed: {data}")
return data["Id"]
def get_asset(asset_id: str) -> dict:
resp = requests.post(
f"{BASE_URL}/GetAsset",
headers=HEADERS,
json={"Id": asset_id},
)
resp.raise_for_status()
return resp.json()
def poll_asset_active(asset_id: str, timeout_sec: int = 120, interval_sec: int = 3) -> dict:
deadline = time.time() + timeout_sec
while time.time() < deadline:
data = get_asset(asset_id)
status = data.get("Status", "")
print(f"Asset status: {status}")
if status == "Active":
return data
if status == "Failed":
raise RuntimeError(f"Asset processing failed: {data}")
time.sleep(interval_sec)
raise TimeoutError("Polling asset status timed out")
if __name__ == "__main__":
asset_id = create_asset("test asset", "https://static.example.com/character.png")
print(f"Created asset: {asset_id}")
result = poll_asset_active(asset_id)
print("Asset ready:", result)