Skip to content

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).

ActionParameters
CreateAssetGroupName* (≤64 chars), Description (≤300 chars), GroupType* (AIGC; LivenessFace groups come from face verification)
GetAssetGroupId*
ListAssetGroupssee "List parameters" below
UpdateAssetGroupId*, Name, Description
DeleteAssetGroupId*

Assets ​

ActionParameters
CreateAssetGroupId* (your own group ID), URL* (publicly reachable), AssetType* (Image / Video / Audio), Name (≤64 chars, used for list search only), Moderation (moderation settings)
GetAssetId*
ListAssetssee "List parameters" below (Filter also supports Statuses: Processing / Active / Failed)
UpdateAssetId, Name
DeleteAssetId*

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 include TotalCount;
  • Cursor style: MaxResults (1–100); carry the returned NextToken with identical query conditions to continue; when the response no longer contains NextToken, 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 ​

bash
# 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):

json
{
  "ResponseMetadata": {
    "RequestId": "202610181426133025978808268d9d6buuMLLoX",
    "Action": "CreateAssetGroup",
    "Version": "2024-01-01",
    "Service": "ark",
    "Region": "cn-beijing"
  },
  "Result": { "Id": "group-20260101120000-xxxxx" }
}

Query (GetAsset):

json
{
  "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):

json
{
  "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:

json
{
  "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 ​

SettingValue
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)
regioncn-beijing
serviceark

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 in yyyyMMdd'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 SignedHeaders list, 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):

python
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 ​

python
# 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 ​

python
# 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 ​

python
# 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:
        break

ListAssetGroups 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.

© 2026 API-RUN. All rights reserved.