Skip to main content
Doubao Seedance 2.0 lets you ingest assets (image/video/audio) and reference them in generation with asset://<asset_id>, instead of passing a public URL every time. The gateway mirrors the official Volcengine asset API 1:1 (/doubao/?Action=...).

Overview

The Seedance 2.0 asset library has two kinds:
  • Virtual avatar / generic assets: assets you own and may use commercially. Create group -> upload -> poll -> use.
  • Real-person assets: require real-person verification (H5 liveness check) first, then upload that person’s assets. Volcengine forbids uploading reference images containing real faces directly, so real-person material must go through this flow.
End-to-end flow:
Account binding (important): asset_id is bound to a Volcengine account. An asset can only be referenced by generation under the same account that created it. The gateway records an asset->channel mapping automatically, so generation requests referencing asset:// are hard-pinned back to the channel that created the asset; you do not need to specify it manually.

Prerequisites (admin setup)

  1. In the VolcEngine (Doubao) channel’s “Advanced Settings”, fill in Asset Library Access Key (AK) and Secret Key (SK).
    • Video generation still uses the channel’s ark- API Key (Bearer); the two are independent.
    • The AK/SK MUST belong to the same Volcengine account as that ark- key, otherwise referencing asset:// during generation returns “asset not found”.
    • If the channel key itself is in ak\|sk format, you can leave AK/SK blank and the gateway will reuse it.
  2. (Recommended) Set the Asset Library Project (ProjectName) in the channel’s advanced settings. ProjectName is a Volcengine IAM project (resource scope) that the AK/SK must be authorized on. When set, the gateway force-overrides the ProjectName in the user’s request body so the channel controls it — end users then do not need to (and should not) pass ProjectName themselves, which avoids AccessDenied from a wrong value and guarantees create-group / upload / query all use the same project. Leave blank to pass through the user’s value (Volcengine default: default).
  3. Add the sentinel model doubao-asset to the channel’s model list (used to route asset-management requests to this channel).
  4. Asset-management calls are free (not billed).
Common error AccessDenied: User is not authorized to perform: ark:CreateAsset on resource: trn:iam::<account>:project/<project> is a Volcengine IAM permission issue (not a gateway issue): the AK/SK (usually a sub-account) lacks ark:CreateAsset permission on that project. Fix: use the main-account AK/SK, or grant the sub-account the Ark asset permissions scoped to that project in Volcengine Access Control; and prefer setting the channel’s “Asset Library Project” to control ProjectName centrally.

Authentication

All requests use the gateway token:
Unified asset endpoint (mirrors the official API): POST /doubao/?Action=<Action>&Version=2024-01-01
Besides mirroring the official /doubao/?Action=..., the gateway offers a unified simplified interface that reuses the platform’s common POST /v1/task/submit entry and {model, input} style, hiding Volcengine’s Action / GroupId / ProjectName / signing complexity. Recommended for most use cases.
  • Single entry POST /v1/task/submit, model is always doubao-asset, and input.action selects the operation.
  • Synchronous: asset operations are fast and return the result (asset_id, etc.) immediately, no polling.
  • Auto-managed asset group: when upload omits group_id, the gateway auto-creates and reuses a per-user asset group; it lands in the same group as the native /doubao interface, so assets uploaded either way are mutually referenceable.
  • Unified response: { "code": 0, "message": "ok", "data": {...} } (code != 0 means error).

Supported actions

action values: upload (needs url+asset_type, optional name/group_id), query (needs asset_id), list (lists your own assets), delete (needs asset_id), create_validate_session / get_validate_result (real-person verification, see below). A successful upload returns:
Once processed (query returns Status: "Active"), reference it in video generation via asset://<asset_id>.
Isolation + interop: each user’s assets go into their own dedicated group, isolated from others; for a given user, assets created via the simplified interface and the native /doubao interface share the same group and are mutually referenceable.

Real-person verification (simplified)

Real-person verification requires the actor to complete a liveness face scan on their phone, which happens between “actor browser ↔ Volcengine” and cannot be proxied by the gateway — you still provide a callback_url to receive Volcengine’s redirect after the scan. The simplified interface only unifies the entry and field names:
With the verified group_id, call upload and pass group_id explicitly to upload the real-person asset into that group.

Using it in Playground

Admins configure playground_mode=task and the following task_input_schema (JSON Schema) on the doubao-asset model to render a dynamic form in Playground:

Native mirror interface

Below are the 1:1 mirrors of Volcengine’s official low-level endpoints (/doubao/?Action=...). If you already use the simplified interface above, you usually don’t need these directly; they are for cases that require precise GroupId control or integrating with Volcengine’s official SDK.

Virtual avatar / generic asset flow

Step 1: Create an asset group

Response:

Step 2: Upload an asset

Upload one asset per request. AssetType can be Image / Video / Audio; URL must be publicly reachable.
Response:

Step 3: Poll asset status

Upload is processed asynchronously; poll until Status becomes Active before using it (Failed means processing failed).
Response:

Other management endpoints

ListAssetGroups / ListAssets / GetAssetGroup / UpdateAssetGroup / UpdateAsset / DeleteAsset / DeleteAssetGroup all work the same way: POST /doubao/?Action=<Action>&Version=2024-01-01 with the corresponding JSON body.

Real-person asset flow

Real-person assets require real-person verification (H5 liveness check) first.

Step 1: Create a verification session

The response contains H5Link (the actor opens it to verify) and BytedToken (valid 120s, single-use):
After the actor completes the liveness check on mobile, Volcengine redirects back to your CallbackURL with resultCode (10000 means success) and related params.

Step 2: Exchange BytedToken for GroupId

If verification is not finished yet, it may return ValidatePending; retry shortly after.

Steps 3-4: Upload + poll

With the GroupId, call CreateAsset (same as virtual avatar Step 2) to upload the person’s asset, then poll with GetAsset until Active. Different looks of the same person can live under the same GroupId.

Referencing assets in video generation

Once an asset is Status=Active, write it as asset://<asset_id> to reference it in a generation request.

Option A: Unified async task endpoint /v1/task/submit

Put asset://... into reference_images / first_frame / reference_videos / reference_audio:

Option B: Native /doubao endpoint

Put asset://... into the content array’s image_url / video_url / audio_url:

Notes

  • A successful upload does not mean it is immediately usable; wait until Status=Active.
  • Asset URLs must stay publicly reachable, otherwise processing fails.
  • Keep a single character / single person’s assets in one group.
  • asset_id is account-bound: it cannot be referenced across accounts. The gateway records an asset->channel mapping on creation and auto-pins generation back to that channel.
  • Per-user isolation: each token (user) can only query / update / delete assets it created via the gateway; ListAssets / ListAssetGroups return only your own; calling GetAsset / DeleteAsset etc. with someone else’s asset_id is rejected with 403 AssetNotOwned; referencing someone else’s asset:// during video generation is likewise rejected with 403 (prevents misusing another user’s real-person/virtual assets). Users sharing the same channel (same Volcengine account) cannot see each other’s assets.
  • If you create assets in the Volcengine console / experience center (not via this gateway), the gateway has no mapping; those assets are not visible / not operable for regular users (the intended isolation behavior). In multi-channel (multi-account) setups, use a token bound to the matching channel (token fixed channel) to ensure correct routing.