Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .vitepress/theme/OfficialNativeApiSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const models = [
text: 'Seedance 2.0 Official',
link: '/model-api-reference/official-native-api/bytedance/seedance-2.0-official',
},
{
text: 'Media Assets for Seedance',
link: '/model-api-reference/official-native-api/bytedance/media-assets',
},
]

const openaiModels = [
Expand Down
6 changes: 5 additions & 1 deletion api-reference/models/assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ description: Register reusable media Assets and retrieve their current metadata

# Media Assets API

Register media file URLs into the platform asset library and get an `asset_url` for use in video generation requests.
Use the official-compatible Asset protocol exposed at `/v1/assets` to register media URLs and get an `asset_url` for
native video generation requests.

For an end-to-end example that registers media and uses the returned `asset://` reference with Seedance, see
[Media Assets for Seedance](/model-api-reference/official-native-api/bytedance/media-assets).

## Overview

Expand Down
160 changes: 160 additions & 0 deletions model-api-reference/official-native-api/bytedance/media-assets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
title: Media Assets for Seedance
description: Register reusable media through the official-compatible Asset protocol, then use asset:// references with Seedance 2.0 and 2.5.
---

# Media Assets for Seedance

SandBase exposes the official-compatible Asset protocol at `/v1/assets`. The Asset request and the returned `asset://`
reference follow the official protocol, and the reference is passed through unchanged in the native ByteDance Contents
Generations request. Both
[Seedance 2.5 Official](./seedance-2.5-official) and [Seedance 2.0 Official](./seedance-2.0-official) accept that reference
where they normally accept a public HTTP(S) URL.

The complete workflow is:

1. Register a reachable media URL with `POST /v1/assets`.
2. Query `GET /v1/assets/{external_id}` until the provider reports that the Asset is usable.
3. Put the returned `asset_url` in a Seedance `content` item and submit the generation task.

## Official-compatible Asset operations

| Method | Path | Purpose |
| --- | --- | --- |
| `POST` | `/v1/assets` | Register a reachable media URL and receive an official-compatible `asset://` reference |
| `GET` | `/v1/assets/{external_id}` | Read the provider status and obtain the current preview/download URL |

The public API currently exposes registration and lookup. Asset groups, listing, renaming, updating, and deletion are
not public operations. Assets belong to the organization associated with the API key.

## Step 1: register the Asset

Send the reachable URL to `POST /v1/assets`. `asset_type` is case-sensitive and must be `Image`, `Video`, or `Audio`:

```bash
curl -X POST https://api.sandbase.ai/v1/assets \
-H "Authorization: Bearer $SANDBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product-reference.png",
"asset_type": "Image",
"name": "Product reference"
}'
```

Save `asset_url` from the response:

```json
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"asset_url": "asset://asset-20260710150403-hx4hf",
"asset_type": "Image",
"name": "Product reference",
"created_at": "2026-07-10T15:04:03Z"
}
```

The value after `asset://` is the `external_id` used by the official-compatible lookup operation.

## Step 2: check readiness

Query the Asset with the `external_id`, without the `asset://` prefix:

```bash
curl https://api.sandbase.ai/v1/assets/asset-20260710150403-hx4hf \
-H "Authorization: Bearer $SANDBASE_API_KEY"
```

```json
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"external_id": "asset-20260710150403-hx4hf",
"asset_url": "asset://asset-20260710150403-hx4hf",
"status": "Active",
"asset_type": "Image",
"name": "Product reference",
"download_url": "https://media.example.com/current-signed-url",
"created_at": "2026-07-10T15:04:03Z"
}
```

Treat `status` as an open provider value rather than an exhaustive enum. Wait until the provider reports a usable
state before submitting the generation task; a common ready value is `Active`. `download_url` is provider-managed and
can be empty while processing. Query the Asset again when you need a current preview URL. Keep using the persistent
`asset_url` in Seedance requests rather than copying `download_url`.

## Step 3: generate with the Asset

Place `asset_url` in the URL field that matches the media type. This example uses the registered image as a visual
reference:

```bash
curl -X POST https://api.sandbase.ai/api/v3/contents/generations/tasks \
-H "Authorization: Bearer $SANDBASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bytedance/seedance/2.5-official",
"content": [
{
"type": "text",
"text": "Create a cinematic product shot. Keep the bottle shape and label from the reference image."
},
{
"type": "image_url",
"image_url": {"url": "asset://asset-20260710150403-hx4hf"},
"role": "reference_image"
}
],
"ratio": "16:9",
"resolution": "1080p",
"duration": 5,
"generate_audio": true
}'
```

The create response returns a task `id`. Poll
`GET /api/v3/contents/generations/tasks/{task_id}` as described on the selected model page.

## Choose the content item and role

| Asset type | `content[].type` | URL field | Supported role | Use it for |
| --- | --- | --- | --- | --- |
| Image | `image_url` | `image_url.url` | `first_frame` | Start the video from this exact frame |
| Image | `image_url` | `image_url.url` | `last_frame` | End on this frame; include a `first_frame` in the same request |
| Image | `image_url` | `image_url.url` | `reference_image` | Preserve a subject, product, composition, costume, or visual style |
| Video | `video_url` | `video_url.url` | `reference_video` | Follow motion, timing, camera work, or editing rhythm |
| Audio | `audio_url` | `audio_url.url` | `reference_audio` | Follow voice, dialogue, music, or sound design |

Audio cannot be the only input. Combine a `reference_audio` Asset with text, an image, or a video. Any request that
contains a `video_url` uses the video-to-video billing rate.

### Video Asset example

```json
{
"type": "video_url",
"video_url": {"url": "asset://asset-20260710150403-video1"},
"role": "reference_video"
}
```

### Audio Asset example

```json
{
"type": "audio_url",
"audio_url": {"url": "asset://asset-20260710150403-audio1"},
"role": "reference_audio"
}
```

## Direct URL or `asset://` reference?

| Input | Best when | Trade-off |
| --- | --- | --- |
| Public HTTP(S) URL | The media is already hosted and used once | Fastest path, but the URL must remain reachable through task submission and provider fetch |
| `asset://` reference | The media is reused through the official Asset protocol | Adds a registration/readiness step, then gives a persistent reference for later Seedance tasks |

For request parameters, polling, task statuses, and billing, continue with
[Seedance 2.5 Official](./seedance-2.5-official), [Seedance 2.0 Official](./seedance-2.0-official), or the complete
[Official Native API overview](/model-api-reference/official-native-api).
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@ bytedance/seedance/2.0-official
Choose this lower-priced model when 480p or 720p output is sufficient. It supports text, image, video, and audio
references using the same request structure as Seedance 2.5 Official.

## Use reusable media

Seedance accepts public HTTP(S) references directly. It also supports the official-compatible Asset protocol: register
the media URL with `/v1/assets`, then pass the returned `asset://` reference through unchanged in the same native
`content` shape:

```json
{
"model": "bytedance/seedance/2.0-official",
"content": [
{"type": "text", "text": "Keep the product appearance and add a slow cinematic camera orbit"},
{
"type": "image_url",
"image_url": {"url": "asset://asset-20260710150403-hx4hf"},
"role": "reference_image"
}
],
"ratio": "16:9",
"resolution": "720p",
"duration": 5
}
```

See [Media Assets for Seedance](./media-assets) for the complete registration, readiness, and generation
workflow, including image, video, and audio roles.

## Create a task

```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@ bytedance/seedance/2.5-official
Choose this model when you need up to 1080p output. It supports 480p, 720p, and 1080p generation with text, image,
video, and audio references.

## Use reusable media

Seedance accepts public HTTP(S) references directly. It also supports the official-compatible Asset protocol: register
the media URL with `/v1/assets`, then pass the returned `asset://` reference through unchanged in the same native
`content` shape:

```json
{
"model": "bytedance/seedance/2.5-official",
"content": [
{"type": "text", "text": "Keep the product appearance and add a slow cinematic camera orbit"},
{
"type": "image_url",
"image_url": {"url": "asset://asset-20260710150403-hx4hf"},
"role": "reference_image"
}
],
"ratio": "16:9",
"resolution": "1080p",
"duration": 5
}
```

See [Media Assets for Seedance](./media-assets) for the complete registration, readiness, and generation
workflow, including image, video, and audio roles.

## Create a task

```bash
Expand Down
1 change: 1 addition & 0 deletions model-api-reference/official-native-api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ GPT Image 2 uses the native OpenAI Images API at `/v1/images/generations`. Pass

- [Seedance 2.5 Official](/model-api-reference/official-native-api/bytedance/seedance-2.5-official)
- [Seedance 2.0 Official](/model-api-reference/official-native-api/bytedance/seedance-2.0-official)
- [Media Assets for Seedance](/model-api-reference/official-native-api/bytedance/media-assets)

## Google

Expand Down
17 changes: 17 additions & 0 deletions scripts/validate-doc-content.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,22 @@ const nativeReference = readFileSync('model-api-reference/official-native-api/in
assert.match(nativeReference, /`DELETE`\s*\|\s*`\/api\/v3\/contents\/generations\/tasks\/\{task_id\}`/, 'Official Native API must document task deletion')
assert.match(nativeReference, /Cancel or remove a task/, 'Official Native API must explain task cancellation semantics')

const seedanceAssetReference = readFileSync('model-api-reference/official-native-api/bytedance/media-assets.md', 'utf8')
assert.match(seedanceAssetReference, /`POST \/v1\/assets`/, 'Seedance Asset guide must document Asset registration')
assert.match(seedanceAssetReference, /`GET \/v1\/assets\/\{external_id\}`/, 'Seedance Asset guide must document Asset readiness lookup')
assert.match(seedanceAssetReference, /asset:\/\/asset-/, 'Seedance Asset guide must use the persistent Asset reference in a generation request')
assert.match(seedanceAssetReference, /reference_image[\s\S]*reference_video[\s\S]*reference_audio/, 'Seedance Asset guide must map image, video, and audio roles')
assert.match(seedanceAssetReference, /official-compatible Asset protocol/, 'Seedance Asset guide must describe the official-compatible protocol boundary')
assert.match(seedanceAssetReference, /passed through unchanged/, 'Seedance Asset guide must state that asset references pass through unchanged')
assert.doesNotMatch(seedanceAssetReference, /\/v1\/upload/, 'Seedance official Asset guide must not mix in the generic upload endpoint')
assert.doesNotMatch(seedanceAssetReference, /SandBase Asset library/, 'Seedance Asset guide must not describe the compatible Asset protocol as a separate SandBase library')
assert.doesNotMatch(seedanceAssetReference, /POST \/api\/v3\/assets/, 'Seedance Asset guide must not expose the internal Asset gateway')

for (const filename of ['seedance-2.5-official.md', 'seedance-2.0-official.md']) {
const seedanceModelReference = readFileSync(`model-api-reference/official-native-api/bytedance/${filename}`, 'utf8')
assert.match(seedanceModelReference, /Media Assets for Seedance/, `${filename} must link the Asset workflow`)
assert.match(seedanceModelReference, /asset:\/\/asset-/, `${filename} must show how to use a reusable Asset`)
}

assert.ok(inspected > 0, 'content validation did not inspect any public hand-written pages')
console.log(`public hand-written content: ok (${inspected} pages)`)
2 changes: 2 additions & 0 deletions scripts/validate-public-api-surface.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,8 @@ assert.doesNotMatch(modelSidebar, /text: 'Official Native API'/, 'Model API main
assert.match(officialNativeSidebar, /Official Native API/, 'Custom sidebar must expose Official Native API')
assert.match(officialNativeSidebar, /official-native-api\/bytedance\/seedance-2\.5-official/, 'Official Native API sidebar must expose Seedance 2.5')
assert.match(officialNativeSidebar, /official-native-api\/bytedance\/seedance-2\.0-official/, 'Official Native API sidebar must expose Seedance 2.0')
assert.match(officialNativeSidebar, /Media Assets for Seedance/, 'Official Native API sidebar must expose the Seedance Asset workflow')
assert.match(officialNativeSidebar, /official-native-api\/bytedance\/media-assets/, 'Official Native API sidebar must link the Seedance Asset workflow')
assert.match(officialNativeSidebar, /Gemini Omni Flash Preview/, 'Official Native API sidebar must expose Gemini Omni')
assert.match(officialNativeSidebar, /official-native-api\/google\/gemini-omni-flash-preview/, 'Official Native API sidebar must link Gemini Omni')
assert.match(officialNativeSidebar, /Nano Banana Pro/, 'Official Native API sidebar must expose Gemini 3 Pro Image')
Expand Down