curl https://api.apipod.ai/v1/videos/generations \
-H "Authorization: Bearer $APIPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
}'import os
import requests
payload = {
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": True
}
response = requests.post(
"https://api.apipod.ai/v1/videos/generations",
headers={
"Authorization": f"Bearer {os.environ['APIPOD_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload := map[string]any{}
if err := json.Unmarshal([]byte(`{
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
}`), &payload); err != nil {
panic(err)
}
body, err := json.Marshal(payload)
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.apipod.ai/v1/videos/generations", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("APIPOD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}use reqwest::Client;
use serde_json::json;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let payload = json!({
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
});
let response = Client::new()
.post("https://api.apipod.ai/v1/videos/generations")
.bearer_auth(env::var("APIPOD_API_KEY")?)
.json(&payload)
.send()
.await?
.error_for_status()?;
println!("{}", response.text().await?);
Ok(())
}const response = await fetch("https://api.apipod.ai/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIPOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(
{
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
}
),
});
if (!response.ok) {
throw new Error(`APIPod request failed: ${response.status} ${await response.text()}`);
}
console.log(await response.json());{
"code": 200,
"message": "success",
"data": {
"task_id": "vid_task_01JEXAMPLE"
}
}Seedance 2.5 Draft
Seedance 2.5 Draft is a two-stage workflow: submit a normal request to create a low-cost 480p draft preview, then submit the completed draft’s task ID as…
curl https://api.apipod.ai/v1/videos/generations \
-H "Authorization: Bearer $APIPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
}'import os
import requests
payload = {
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": True
}
response = requests.post(
"https://api.apipod.ai/v1/videos/generations",
headers={
"Authorization": f"Bearer {os.environ['APIPOD_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload := map[string]any{}
if err := json.Unmarshal([]byte(`{
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
}`), &payload); err != nil {
panic(err)
}
body, err := json.Marshal(payload)
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.apipod.ai/v1/videos/generations", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("APIPOD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}use reqwest::Client;
use serde_json::json;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let payload = json!({
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
});
let response = Client::new()
.post("https://api.apipod.ai/v1/videos/generations")
.bearer_auth(env::var("APIPOD_API_KEY")?)
.json(&payload)
.send()
.await?
.error_for_status()?;
println!("{}", response.text().await?);
Ok(())
}const response = await fetch("https://api.apipod.ai/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIPOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(
{
"model": "seedance-2.5-draft",
"prompt": "A cinematic tracking shot through a rain-soaked neon street, realistic motion, synchronized ambient sound.",
"duration": 4,
"aspect_ratio": "adaptive",
"resolution": "480p",
"generate_audio": true
}
),
});
if (!response.ok) {
throw new Error(`APIPod request failed: ${response.status} ${await response.text()}`);
}
console.log(await response.json());{
"code": 200,
"message": "success",
"data": {
"task_id": "vid_task_01JEXAMPLE"
}
}Authorizations
Use your APIPod API key as a Bearer token in the Authorization header.
Body
Public APIPod model ID.
"seedance-2.5-draft"The data.task_id of a completed draft (from GET /v1/videos/status/{task_id}), created by the same user within the last 7 days. When set, creates the 1080p final video; only resolution, output_format, watermark, and callback_url may be sent alongside it. Do not send an upstream task ID.
Draft stage: text instructions, up to 30000 characters; required unless media is provided. Final stage: not allowed (reused from the draft).
30000Draft stage: reference image URLs, up to 30 images (1-2 images without other media are treated as first/last frames). Final stage: not allowed.
30Draft stage: reference video URLs, up to 10 videos. When videos are present, billing adds the total input-video duration. Final stage: not allowed.
10Draft stage: reference audio URLs, up to 10 audios; audio needs at least one image or video reference. Final stage: not allowed.
10Draft stage: output duration in seconds, 4-30 (default 4); duration=-1 is not supported. Final stage: not allowed - the draft duration is reused and billed.
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 4 <= x <= 30Draft stage: output aspect ratio (default adaptive). Final stage: not allowed (reused from the draft).
adaptive, 969, 243, 61, 184, 556, 1269 Draft previews support only 480p (filled in when omitted). Final videos created with draft_task_id support only 1080p (filled in when omitted).
480p, 1080p Draft stage: whether to generate synchronized audio (default true). Final stage: not allowed (reused from the draft).
Output container format, mp4 (default) or mov. Allowed in both stages.
mp4, mov Was this page helpful?