Seedance Asset Library
The official-consistent Seedance access ships with its own asset library. Assets are isolated per account: you can only access your own groups and assets. Calls go through the unified asset entry (identical to the official control-plane call shape); every asset Action on this page is available. For video generation task endpoints see Seedance Official-Consistent Access.
Authentication
All endpoints on this page (asset Actions and face verification) accept either style:
- Bearer (default):
Authorization: Bearer $YOUR_API_KEY— the same platform token used for task endpoints;
Endpoints
- Asset / face verification RPC (unified entry, recommended):
POST $URL/?Action=<Action>&Version=2024-01-01— identical to the official control-plane call shape (Action on the domain root), routed automatically by token group
Asset groups
RPC requests may carry an optional ProjectName field (passed through to the upstream; must match account permissions; the default project is used when omitted).
| Action | Parameters |
|---|---|
CreateAssetGroup | Name* (≤64 chars), Description (≤300 chars), GroupType* (AIGC; LivenessFace groups come from face verification) |
GetAssetGroup | Id* |
ListAssetGroups | see "List parameters" below |
UpdateAssetGroup | Id*, Name, Description |
DeleteAssetGroup | Id* |
Assets
| Action | Parameters |
|---|---|
CreateAsset | GroupId* (your own group ID), URL* (publicly reachable), AssetType* (Image / Video / Audio), Name (≤64 chars, used for list search only), Moderation (moderation settings) |
GetAsset | Id* |
ListAssets | see "List parameters" below (Filter also supports Statuses: Processing / Active / Failed) |
UpdateAsset | Id, Name |
DeleteAsset | Id* |
CreateAsset is asynchronous: after the Id is returned, poll GetAsset until Status=Active before referencing the asset in tasks. GetAsset / ListAssets return Id, Name, URL (reference address, valid ~12 hours), AssetType, GroupId, Status, Error (Code / Message), CreateTime, UpdateTime.
List parameters (ListAssetGroups / ListAssets)
Filter is required (may be {}) and supports GroupIds, GroupType (AIGC / LivenessFace) and Name (fuzzy search).
Two pagination styles, pick either:
- Page style:
PageNumber(1-based) +PageSize(1–100); responses includeTotalCount; - Cursor style:
MaxResults(1–100); carry the returnedNextTokenwith identical query conditions to continue; when the response no longer containsNextToken, the iteration is done.
Sorting: SortBy (CreateTime / UpdateTime, default CreateTime), SortOrder (Asc / Desc, default Desc).
Asset format requirements
- Image: jpeg / png / webp / bmp / tiff / gif / heic / heif, width & height 300–6000 px, aspect ratio 0.4–2.5, <30MB each;
- Video: mp4 / mov, 480p–4K, duration 1.8–30.2 s, <200MB each;
- Audio: wav / mp3, duration 1.8–30.2 s, <15MB each.
Uploaded assets are re-hosted; an unreachable URL returns InvalidParameter.DownloadFailed.
Examples
# Create an asset group
curl "$URL/?Action=CreateAssetGroup&Version=2024-01-01" \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "Name": "my group", "GroupType": "AIGC" }'
# Upload an asset
curl "$URL/?Action=CreateAsset&Version=2024-01-01" \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "GroupId": "group-xxxx", "URL": "https://example.com/photo.jpg", "AssetType": "Image", "Name": "reference" }'
# Get asset (fresh reference URL)
curl "$URL/?Action=GetAsset&Version=2024-01-01" \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "Id": "asset-xxxx" }'Responses use the { "ResponseMetadata": {...}, "Result": {...} } envelope; errors appear in ResponseMetadata.Error (Code / Message).
Response examples
Create (CreateAssetGroup / CreateAsset):
{
"ResponseMetadata": {
"RequestId": "202610181426133025978808268d9d6buuMLLoX",
"Action": "CreateAssetGroup",
"Version": "2024-01-01",
"Service": "ark",
"Region": "cn-beijing"
},
"Result": { "Id": "group-20260101120000-xxxxx" }
}Query (GetAsset):
{
"ResponseMetadata": { "RequestId": "...", "Action": "GetAsset", "Version": "2024-01-01", "Service": "ark", "Region": "cn-beijing" },
"Result": {
"Id": "asset-20260101120000-xxxxx",
"Name": "reference",
"URL": "https://.../signed-url (valid ~12 hours)",
"AssetType": "Image",
"GroupId": "group-20260101120000-xxxxx",
"Status": "Active",
"CreateTime": "2026-01-01T12:00:00+08:00",
"UpdateTime": "2026-01-01T12:01:00+08:00"
}
}List (ListAssets; page style includes TotalCount, cursor style includes NextToken and omits TotalCount):
{
"ResponseMetadata": { "RequestId": "...", "Action": "ListAssets", "Version": "2024-01-01", "Service": "ark", "Region": "cn-beijing" },
"Result": {
"Items": [ { "Id": "asset-...", "Status": "Active", "AssetType": "Image", "GroupId": "group-..." } ],
"TotalCount": 12,
"PageNumber": 1,
"PageSize": 10
}
}Error:
{
"ResponseMetadata": {
"RequestId": "...",
"Error": { "Code": "InvalidParameter.DownloadFailed", "Message": "Failed to download media from the provided URL." }
}
}AK/SK Signature Access (optional)
Clients already using the Volcengine SDK or signing per the Volcano V4 scheme can access the asset library with zero code changes: point the SDK endpoint at this site and fill both AK and SK with your platform token.
SDK configuration
| Setting | Value |
|---|---|
| endpoint / base_url | $URL/sc (with http:// or https://, no trailing slash) |
| AK (Access Key) | your platform token (the full sk- value shown on the token page) |
| SK (Secret Key) | your platform token (the same value as the AK) |
| region | cn-beijing |
| service | ark |
For the Volcano Go SDK, set this site's address via WithEndpoint; the SDK handles request signing automatically.
Signing protocol
Identical to the Volcano V4 signing scheme. Clients implementing signing themselves must:
X-Date: UTC time inyyyyMMdd'T'HHmmss'Z'format, clock skew against the server no more than 5 minutes;X-Content-Sha256: lowercase-hex SHA-256 of the final raw request body bytes (for GET, hash the empty body), and it must be signed (do not re-serialize the body after signing);Authorization:
HMAC-SHA256 Credential={AK}/{yyyyMMdd}/cn-beijing/ark/request, SignedHeaders=content-type;host;x-content-sha256;x-date, Signature={hex}- Key derivation:
HMAC(SK, date) → HMAC(·, cn-beijing) → HMAC(·, ark) → HMAC(·, "request"), then sign the StringToSign; - The CanonicalRequest consists of the HTTP method, path, canonicalized query string (keys sorted, strict percent-encoding), canonicalized signed headers, the
SignedHeaderslist, and the request body hash.
Failed signature verification returns SignatureDoesNotMatch; excessive clock skew returns RequestTimeTooSkewed. After verification, token validity, account status and IP restrictions are enforced exactly as with Bearer.
Python manual signing
A generic standard-library signing function covering the asset RPC (GET/POST):
import hmac, hashlib, json, time
from urllib.request import Request, urlopen
KEY = "sk-..." # your platform token; AK = SK = the same value
HOST = "your-gateway-host"
def pct(s):
safe = set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~")
return "".join(c if c in safe else "".join("%%%02X" % b for b in c.encode()) for c in s)
def signed_request(method, path, query="", body_obj=None):
body = b"" if body_obj is None else json.dumps(body_obj).encode()
t = time.gmtime()
xdate = time.strftime("%Y%m%dT%H%M%SZ", t)
short = time.strftime("%Y%m%d", t)
payload_hash = hashlib.sha256(body).hexdigest()
sh = ["content-type", "host", "x-content-sha256", "x-date"]
ch = (f"content-type:application/json\nhost:{HOST}\n"
f"x-content-sha256:{payload_hash}\nx-date:{xdate}\n")
q = {}
for kv in query.split("&"):
if kv:
k, _, v = kv.partition("=")
q.setdefault(k, []).append(v)
cq = "&".join(f"{pct(k)}={pct(v)}" for k in sorted(q) for v in sorted(q[k]))
cr = "\n".join([method, path, cq, ch, ";".join(sh), payload_hash])
scope = f"{short}/cn-beijing/ark/request"
sts = "\n".join(["HMAC-SHA256", xdate, scope,
hashlib.sha256(cr.encode()).hexdigest()])
k = KEY.encode()
for e in (short, "cn-beijing", "ark", "request"):
k = hmac.new(k, e.encode(), hashlib.sha256).digest()
sig = hmac.new(k, sts.encode(), hashlib.sha256).hexdigest()
url = f"https://{HOST}{path}" + (f"?{query}" if query else "")
req = Request(url, data=body if method == "POST" else None, method=method,
headers={"Content-Type": "application/json", "X-Date": xdate,
"X-Content-Sha256": payload_hash, "Host": HOST,
"Authorization": f"HMAC-SHA256 Credential={KEY}/{scope}, "
f"SignedHeaders={';'.join(sh)}, Signature={sig}"})
return json.load(urlopen(req, timeout=30))
def rpc(action, body):
return signed_request("POST", "/", f"Action={action}&Version=2024-01-01", body)Asset group operations
# Create an asset group
r = rpc("CreateAssetGroup", {"Name": "my group", "GroupType": "AIGC"})
group_id = r["Result"]["Id"]
# Get / update
rpc("GetAssetGroup", {"Id": group_id})
rpc("UpdateAssetGroup", {"Id": group_id, "Description": "brand assets"})
# Delete
rpc("DeleteAssetGroup", {"Id": group_id})Asset operations
# Upload (asynchronous: poll to Active after the Id is returned)
r = rpc("CreateAsset", {
"GroupId": group_id,
"URL": "https://example.com/photo.jpg", # publicly reachable
"AssetType": "Image", # Image / Video / Audio
"Name": "reference",
})
asset_id = r["Result"]["Id"]
# Poll processing status
import time
while True:
r = rpc("GetAsset", {"Id": asset_id})["Result"]
if r["Status"] != "Processing":
break
time.sleep(3)
assert r["Status"] == "Active", r.get("Error")
asset_url = r["URL"] # reference URL (~12h validity) for task content
# Rename / delete
rpc("UpdateAsset", {"Id": asset_id, "Name": "new name"})
rpc("DeleteAsset", {"Id": asset_id})Listing and pagination
# Page style
r = rpc("ListAssets", {"Filter": {"GroupType": "AIGC"}, "PageNumber": 1, "PageSize": 10})
items, total = r["Result"]["Items"], r["Result"]["TotalCount"]
# Cursor style: start with MaxResults, carry NextToken until absent
token, all_items = None, []
while True:
body = {"Filter": {"GroupType": "AIGC"}, "MaxResults": 20}
if token:
body["NextToken"] = token
r = rpc("ListAssets", body)["Result"]
all_items += r["Items"]
token = r.get("NextToken")
if not token:
breakListAssetGroups works the same way (its Filter has no Statuses).
FAQ
Q: Asset upload fails with DownloadFailed / HeightTooSmall?
The asset URL must be publicly reachable (it is fetched and validated in real time), and the image width & height must be between 300 and 6000 px.
Q: Deleting an asset/group returns "retry later" (409)?
Assets that are still processing/under review, or currently referenced by a video task, cannot be deleted — the upstream refuses with a retry-later message, which the platform passes through as 409. Wait a moment and retry; a group must be emptied before it can be deleted.
Q: When can an asset be used for generation?
After CreateAsset returns the Id, the asset is processing; poll GetAsset until Status=Active before referencing its URL in task content.
