Skip to main content
Seedance 2.0 uses two auth schemes and two endpoints:
  • Asset management (create group / upload / query / delete): Volcengine-native APIs signed with AK/SK, called directly against open.volcengineapi.com. APIYI does not proxy this part.
  • Video generation (including asset:// references): through the APIYI gateway with Bearer sk-... (the token must have the SeeDance2 group enabled).
Verified result: once you ingest assets with the AK/SK provided by APIYI, the private asset:// works directly with your APIYI sk- token for video generation — because APIYI’s SeeDance2 channel runs on the same underlying Volcengine account. For model selection, pricing, and resolution tables see the Seedance 2.0 Overview; for the generation endpoint see Video Generation API.

Why an asset library

Seedance 2.0 has built-in anti-Deepfake / anti-infringement filtering and does not accept reference images containing real human faces directly. To keep a character’s face and clothing consistent across generated videos, you first ingest a virtual avatar as a trusted asset, get an asset:// ID, and reference it during video generation.
  • Asset Group: manages multiple images of the same virtual character.
  • Asset: a single image / video / audio file; usable only after it is preprocessed to Active.

1. Prerequisites

  1. AK/SK: from the Volcengine console under Access Control (IAM); AK looks like AKLT....
  2. Asset permission: attach a custom policy to the IAM user owning the AK/SK, otherwise you get 403 AccessDenied:
    {"Statement":[{"Effect":"Allow","Action":["ark:*Asset*"],"Resource":["*"]}]}
    
  3. Sign the authorization letter once: creating your first group requires signing an authorization letter in the console (My → Virtual Avatars).
  4. ProjectName: the asset’s project must match the video-generation token’s project (most asset APIs require an explicit ProjectName, otherwise they default to the default project).

2. Volcengine AK/SK signing (Python)

Use the SK directly as a UTF-8 string for key derivation — do not base64-decode it (base64 yields SignatureDoesNotMatch, verified).
import hashlib, hmac, json
from datetime import datetime, timezone
from urllib.parse import quote
import requests

AK, SK = "your_AK", "your_SK"
HOST, SERVICE, REGION, VERSION = "open.volcengineapi.com", "ark", "cn-beijing", "2024-01-01"

def _h(s): return hashlib.sha256(s.encode()).hexdigest()
def _hmac(k, s): return hmac.new(k, s.encode(), hashlib.sha256).digest()

def call(action, body):
    body_str = json.dumps(body)
    x_date = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
    short, bh = x_date[:8], _h(body_str)
    q = "&".join(f"{quote(k,safe='-_.~')}={quote(v,safe='-_.~')}"
                 for k, v in sorted({"Action": action, "Version": VERSION}.items()))
    signed = "content-type;host;x-content-sha256;x-date"
    canon = "\n".join(["POST", "/", q,
        f"content-type:application/json\nhost:{HOST}\nx-content-sha256:{bh}\nx-date:{x_date}",
        "", signed, bh])
    scope = f"{short}/{REGION}/{SERVICE}/request"
    sts = "\n".join(["HMAC-SHA256", x_date, scope, _h(canon)])
    ks = _hmac(_hmac(_hmac(_hmac(SK.encode(), short), REGION), SERVICE), "request")
    sig = hmac.new(ks, sts.encode(), hashlib.sha256).hexdigest()
    headers = {"Host": HOST, "Content-Type": "application/json", "X-Date": x_date,
        "X-Content-Sha256": bh,
        "Authorization": f"HMAC-SHA256 Credential={AK}/{scope}, SignedHeaders={signed}, Signature={sig}"}
    r = requests.post(f"https://{HOST}/?{q}", headers=headers, data=body_str, timeout=60)
    return r.status_code, r.json()
You can also use the official SDK for automatic signing: pip install volcengine-python-sdk. The snippet above is a self-contained requests version for easy porting into your backend.

3. Virtual-avatar ingest flow

import time
PROJECT = "your_ProjectName"

# 1. Create group
_, g = call("CreateAssetGroup", {"Name": "my_figure", "GroupType": "AIGC", "ProjectName": PROJECT})
gid = g["Result"]["Id"]

# 2. Upload asset (async, no SLA)
_, a = call("CreateAsset", {"GroupId": gid, "URL": "https://your-image-url.jpg",
                            "AssetType": "Image", "ProjectName": PROJECT})
aid = a["Result"]["Id"]

# 3. Poll until Active
while True:
    _, info = call("GetAsset", {"Id": aid, "ProjectName": PROJECT})
    st = info.get("Result", info).get("Status")
    if st == "Active": break
    if st == "Failed": raise RuntimeError("ingest failed")
    time.sleep(10)

print("ready:", f"asset://{aid}")
Image requirements: jpeg / png / webp / bmp / tiff / gif / heic; aspect ratio (w/h) 0.4–2.5; side length 300–6000px; under 30 MB each. Avatar best practice: put a full-body frontal shot and a neutral frontal face close-up of the same person into one group to greatly improve character consistency. Preprocessing is usually fast (about 13 seconds to Active for a single image in our test).

4. Generate video with asset:// (via APIYI)

Put asset://<AssetId> into the content array with role set to reference_image. In the prompt, refer to it as “Image 1” — do not write the Asset ID directly in the prompt.
import requests
url = "https://api.apiyi.com/seedance/api/v3/contents/generations/tasks"
headers = {"Authorization": "Bearer sk-your-SeeDance2-token",
           "Content-Type": "application/json", "Accept-Encoding": "identity"}
body = {
    "model": "doubao-seedance-2-0-260128",
    "content": [
        {"type": "text", "text": "Image 1's character smiles to camera, slow push-in, natural light"},
        {"type": "image_url", "image_url": {"url": f"asset://{aid}"}, "role": "reference_image"},
    ],
    "ratio": "16:9", "duration": 5, "resolution": "720p",
}
task = requests.post(url, headers=headers, json=body).json()
# Poll GET {url}/{task['id']} until status=succeeded, then read content.video_url
The asset must be created under the Volcengine account behind the APIYI SeeDance2 channel (i.e. ingested with the AK/SK provided by APIYI). Referencing an asset:// that does not belong to that account returns 400 The specified asset ... is not found.

5. Search & management

ActionAPIKey params
List groupsListAssetGroupsFilter.GroupType=AIGC, ProjectName, PageNumber/PageSize
List assetsListAssetsFilter.GroupIds, Filter.Statuses, ProjectName
Get oneGetAssetId, ProjectName
Delete asset / groupDeleteAsset / DeleteAssetGroupId, ProjectName
Always pass ProjectName: ListAssets / ListAssetGroups default to the default project and return 0 items without it; DeleteAssetGroup returns 404 without it.
Rate limits (account-level): GetAsset 100 QPS; CreateAsset per the advanced creation entitlement package; most others 10 QPS.

6. Real faces (real-person avatars)

Real faces are not a parameter of the asset API — they go through a separate, console-only real-person verification flow that cannot be done via API:
1

Create a real-person asset group

In the experience center: My → Real-Person Avatars → Manage Assets → Create Asset Group.
2

Confirm authorization

Confirm the authorizing subject and purpose, and agree to the face-data processing rules.
3

Real-person verification

The person being filmed completes face verification — once per asset group; adding more looks for the same actor later requires no re-verification.
4

Automatic binding

On completion, the account automatically gains usage rights to that portrait (whoever authorizes is the one who can use it), with a dedicated asset group created.
Compliance: Volcengine requires that real-person video generation involve people who are verified or legally authorized in advance; real-person verification locks portrait-rights ownership at the source.
Product guidance: automate virtual-avatar uploads via the API on this page; for real faces, guide users to complete verification in the Volcengine console, then store the returned asset ID in your system before calling generation. Confirm with the APIYI team / Volcengine whether real-person asset IDs use the same asset:// reference format, whether they share the same entitlement package, and whether an additional portrait authorization document is required.

7. Common errors

SymptomCauseFix
401 SignatureDoesNotMatchsigning error (SK base64-decoded / clock skew / canonical mismatch)use SK as raw UTF-8; check the canonical request
403 AccessDenied: ark:*IAM user lacks asset permissionattach policy ark:*Asset* and bind it to the user
Create group failsauthorization letter not signedcreate a group manually in the console to trigger signing
List returns 0 / delete group 404ProjectName not passedalways include ProjectName
Generation 400 asset not foundasset not under the gateway’s Volcengine account / wrong IDingest with APIYI’s AK/SK; verify the Asset ID
Volcengine official references (copy into your browser): private asset library guide volcengine.com/docs/82379/2333565, asset API reference volcengine.com/docs/82379/2333601, real-person asset onboarding volcengine.com/docs/82379/2315856.