Asset library (virtual characters)

POST /v1/assets · GET /v1/assets · GET /v1/assets/{id} · DELETE /v1/assets/{id}

Seedance videos on the overseas line (-hw series) support a virtual-character asset library: upload a portrait image as an asset to get an asset://<asset ID>, then use it as a person / character reference in video generation requests so the character's face, outfit, and other features stay consistent across the generated video.

Org-private + isolated: the assets you upload belong only to your organization, and only you can reference them; another org cannot use your asset:// ID even if they obtain it, and listing only ever shows your own assets.

Virtual characters only: the asset library accepts only synthetic / virtual characters; material must not resemble a real natural person (upstream reviews it and rejects anything that looks like a real person).

1. Upload an asset: POST /v1/assets

Two upload methods, pick one:

Field Type Required Description
file file Yes Image file. Formats jpeg / png / webp / bmp / tiff / gif / heic; aspect ratio (0.4, 2.5); width/height 300–6000px; < 30 MB.
name string No Asset name for your own management (not used in generation).
curl https://api.portal.aiin1.ai/v1/assets \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@portrait.jpg" \
  -F "name=hero-mei"

1.2 Method B: provide a public image URL (application/json)

Field Type Required Description
source_url string Yes A publicly accessible http(s) image URL (upstream must be able to fetch it).
name string No Asset name.
curl https://api.portal.aiin1.ai/v1/assets \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "source_url": "https://example.com/portrait.jpg", "name": "hero-mei" }'

1.3 Response

Upload is asynchronous preprocessing (upstream review + ingestion, typically ~10 seconds). The endpoint waits inline for a short while:

  • Preprocessing done → 200, status: "active" (ready to use in generation immediately).
  • Still processing → 202, status: "processing" (poll via Query until active later).
  • Review failed → 200, status: "failed", with a fail_reason.
{
  "id": "asset-20260722081357-abcde",
  "asset": "asset://asset-20260722081357-abcde",
  "status": "active",
  "name": "hero-mei",
  "asset_type": "Image"
}
Field Description
id Asset ID.
asset The reference string you can paste straight into a video request's image_url / reference_image_urls.
status processing / active / failed. Only active can be used in generation.

Only an asset with status=active can be referenced in a video request; a processing / failed one is rejected by the video endpoint with 400.

2. Query an asset: GET /v1/assets/{id}

Look up a single asset by ID; if it is still processing, its latest status is refreshed once automatically.

curl https://api.portal.aiin1.ai/v1/assets/asset-20260722081357-abcde \
  -H "Authorization: Bearer YOUR_API_KEY"
{ "id": "asset-20260722081357-abcde", "asset": "asset://asset-20260722081357-abcde", "status": "active", "name": "hero-mei", "asset_type": "Image", "created_at": "2026-07-22T08:13:57+00:00" }

An asset not belonging to your org returns 404.

3. List assets: GET /v1/assets

List all of your org's assets (excluding deleted ones), newest first.

curl https://api.portal.aiin1.ai/v1/assets \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "object": "list",
  "data": [
    { "id": "asset-20260722081357-abcde", "asset": "asset://asset-20260722081357-abcde", "status": "active", "name": "hero-mei", "asset_type": "Image", "created_at": "2026-07-22T08:13:57+00:00" }
  ]
}

4. Delete an asset: DELETE /v1/assets/{id}

curl -X DELETE https://api.portal.aiin1.ai/v1/assets/asset-20260722081357-abcde \
  -H "Authorization: Bearer YOUR_API_KEY"
{ "id": "asset-20260722081357-abcde", "deleted": true }

An asset not belonging to your org returns 404.

5. Using an asset in a video

Once you have an active asset://<id>, put it in a video generation request's image_url (single) or reference_image_urls (multiple). The model must be an overseas -hw line name, and refer to it in prompt by @Image1 / @Image2 index (do not write the asset ID):

curl https://api.portal.aiin1.ai/v1/videos \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2-0-hw",
    "prompt": "@Image1 portrait smiling and waving at the camera in a café, natural light",
    "seconds": "5",
    "size": "1280x720",
    "reference_image_urls": ["asset://asset-20260722081357-abcde"]
  }'

6. Common errors

HTTP Scenario Notes
400 Missing file / source_url You must provide one of the two.
400 Unsupported image type Only jpeg / png / webp / bmp / tiff / gif / heic.
400 Video referenced an asset that isn't yours asset:// must be an asset your org has uploaded and that is active; otherwise the video endpoint returns 400.
401 Invalid API key Check the Authorization header.
404 Asset not found / not your org The queried/deleted ID is wrong or not owned by your org.
413 Image too large Each image must be < 30 MB.
503 Asset library unavailable Your org doesn't have the overseas (-hw) line enabled, or storage is temporarily unavailable.