Assets
Pre-upload media files for use as references in video generation.
The Assets API lets you pre-upload images, videos, and audio files into provider storage. Once uploaded, reference them in generation requests using asset://{assetId} URIs instead of direct URLs.
This is useful for Seedance 2.0 multimodal references (reference_image_urls, reference_video_urls, reference_audio_urls, start_image, end_image) where the source media may be large or behind authentication.
Create an asset
POST /v2/assets/create
Upload a media file by providing its URL. The file is fetched and stored by the provider asynchronously.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Public URL of the media file to upload |
type | string | Yes | Media type: "image", "video", or "audio" |
Response
Status: 201 Created
{
"assetId": "abc123def456"
}Get asset status
GET /v2/assets/:assetId
Check the processing status of an uploaded asset.
Response
Status: 200 OK
{
"status": "Active",
"url": "https://storage.provider.com/...",
"errorMsg": null
}| Status | Meaning |
|---|---|
Processing | The asset is still being uploaded and processed |
Active | Ready to use — reference as asset://{assetId} |
Failed | Upload failed — check errorMsg for details |
Usage in generation requests
Once an asset reaches Active status, use it in any field that accepts media URLs:
{
"prompt": "A person dancing to upbeat music",
"model": "seedance-2",
"seedanceParams": {
"reference_audio_urls": ["asset://abc123def456"],
"reference_image_urls": ["asset://xyz789", "https://example.com/photo.jpg"]
}
}You can mix asset:// URIs with direct URLs in the same request.
Code examples
# 1. Create an asset
curl -X POST https://api.apiframe.ai/v2/assets/create \
-H "X-API-Key: afk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/reference.mp4", "type": "video"}'
# 2. Check status
curl https://api.apiframe.ai/v2/assets/abc123def456 \
-H "X-API-Key: afk_your_api_key_here"import requests
import time
headers = {
"X-API-Key": "afk_your_api_key_here",
"Content-Type": "application/json",
}
# 1. Create an asset
resp = requests.post(
"https://api.apiframe.ai/v2/assets/create",
headers=headers,
json={"url": "https://example.com/reference.mp4", "type": "video"},
)
asset_id = resp.json()["assetId"]
# 2. Poll until active
while True:
status = requests.get(
f"https://api.apiframe.ai/v2/assets/{asset_id}",
headers=headers,
).json()
if status["status"] == "Active":
break
time.sleep(2)
# 3. Use in generation
requests.post(
"https://api.apiframe.ai/v2/videos/generate",
headers=headers,
json={
"prompt": "A cinematic scene inspired by the reference",
"model": "seedance-2",
"seedanceParams": {
"reference_video_urls": [f"asset://{asset_id}"],
},
},
)const headers = {
"X-API-Key": "afk_your_api_key_here",
"Content-Type": "application/json",
};
// 1. Create an asset
const createResp = await fetch("https://api.apiframe.ai/v2/assets/create", {
method: "POST",
headers,
body: JSON.stringify({ url: "https://example.com/reference.mp4", type: "video" }),
});
const { assetId } = await createResp.json();
// 2. Poll until active
let status;
do {
await new Promise((r) => setTimeout(r, 2000));
const resp = await fetch(`https://api.apiframe.ai/v2/assets/${assetId}`, { headers });
status = await resp.json();
} while (status.status !== "Active");
// 3. Use in generation
await fetch("https://api.apiframe.ai/v2/videos/generate", {
method: "POST",
headers,
body: JSON.stringify({
prompt: "A cinematic scene inspired by the reference",
model: "seedance-2",
seedanceParams: {
reference_video_urls: [`asset://${assetId}`],
},
}),
});