curl --request POST \
--url https://api.budgetpixel.com/v1/videos/seedance-2.0 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "<string>",
"aspect_ratio": "16:9",
"audio": "<string>",
"end_image": "<string>",
"generate_audio": true,
"image": "<string>",
"length_seconds": 5,
"reference_images": [
"<string>"
],
"resolution": "720p",
"video": "<string>"
}
'import requests
url = "https://api.budgetpixel.com/v1/videos/seedance-2.0"
payload = {
"prompt": "<string>",
"aspect_ratio": "16:9",
"audio": "<string>",
"end_image": "<string>",
"generate_audio": True,
"image": "<string>",
"length_seconds": 5,
"reference_images": ["<string>"],
"resolution": "720p",
"video": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: '<string>',
aspect_ratio: '16:9',
audio: '<string>',
end_image: '<string>',
generate_audio: true,
image: '<string>',
length_seconds: 5,
reference_images: ['<string>'],
resolution: '720p',
video: '<string>'
})
};
fetch('https://api.budgetpixel.com/v1/videos/seedance-2.0', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.budgetpixel.com/v1/videos/seedance-2.0",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => '<string>',
'aspect_ratio' => '16:9',
'audio' => '<string>',
'end_image' => '<string>',
'generate_audio' => true,
'image' => '<string>',
'length_seconds' => 5,
'reference_images' => [
'<string>'
],
'resolution' => '720p',
'video' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.budgetpixel.com/v1/videos/seedance-2.0"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"16:9\",\n \"audio\": \"<string>\",\n \"end_image\": \"<string>\",\n \"generate_audio\": true,\n \"image\": \"<string>\",\n \"length_seconds\": 5,\n \"reference_images\": [\n \"<string>\"\n ],\n \"resolution\": \"720p\",\n \"video\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.budgetpixel.com/v1/videos/seedance-2.0")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"16:9\",\n \"audio\": \"<string>\",\n \"end_image\": \"<string>\",\n \"generate_audio\": true,\n \"image\": \"<string>\",\n \"length_seconds\": 5,\n \"reference_images\": [\n \"<string>\"\n ],\n \"resolution\": \"720p\",\n \"video\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.budgetpixel.com/v1/videos/seedance-2.0")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"16:9\",\n \"audio\": \"<string>\",\n \"end_image\": \"<string>\",\n \"generate_audio\": true,\n \"image\": \"<string>\",\n \"length_seconds\": 5,\n \"reference_images\": [\n \"<string>\"\n ],\n \"resolution\": \"720p\",\n \"video\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"message": "<string>",
"model": "<string>",
"status": "pending"
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}Generate video with SeeDance 2.0
ByteDance SeeDance 2.0 — text-to-video; image-to-video (start + optional end frame); reference-images-to-video (up to 9 images); and video-to-video editing (supply a video). Resolutions 480p–4K, each priced differently (see resolution_pricing in GET /v1/models); 4K is for text/image/reference modes, not video-edit. Optional audio. 4K output is H.265 (HEVC) 10-bit; 480p, 720p and 1080p are H.264. A browser without a hardware HEVC decoder shows H.265 as a black frame with audio — the job status reports the codec in video_codec.
Asynchronous. Returns a job id (the video is not in this response). Poll GET /v1/videos/{id} until status is succeeded — the video URL is in that response’s video_url.
Examples, sample output and pricing: SeeDance 2.0
curl --request POST \
--url https://api.budgetpixel.com/v1/videos/seedance-2.0 \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "<string>",
"aspect_ratio": "16:9",
"audio": "<string>",
"end_image": "<string>",
"generate_audio": true,
"image": "<string>",
"length_seconds": 5,
"reference_images": [
"<string>"
],
"resolution": "720p",
"video": "<string>"
}
'import requests
url = "https://api.budgetpixel.com/v1/videos/seedance-2.0"
payload = {
"prompt": "<string>",
"aspect_ratio": "16:9",
"audio": "<string>",
"end_image": "<string>",
"generate_audio": True,
"image": "<string>",
"length_seconds": 5,
"reference_images": ["<string>"],
"resolution": "720p",
"video": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: '<string>',
aspect_ratio: '16:9',
audio: '<string>',
end_image: '<string>',
generate_audio: true,
image: '<string>',
length_seconds: 5,
reference_images: ['<string>'],
resolution: '720p',
video: '<string>'
})
};
fetch('https://api.budgetpixel.com/v1/videos/seedance-2.0', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.budgetpixel.com/v1/videos/seedance-2.0",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => '<string>',
'aspect_ratio' => '16:9',
'audio' => '<string>',
'end_image' => '<string>',
'generate_audio' => true,
'image' => '<string>',
'length_seconds' => 5,
'reference_images' => [
'<string>'
],
'resolution' => '720p',
'video' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.budgetpixel.com/v1/videos/seedance-2.0"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"16:9\",\n \"audio\": \"<string>\",\n \"end_image\": \"<string>\",\n \"generate_audio\": true,\n \"image\": \"<string>\",\n \"length_seconds\": 5,\n \"reference_images\": [\n \"<string>\"\n ],\n \"resolution\": \"720p\",\n \"video\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.budgetpixel.com/v1/videos/seedance-2.0")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"16:9\",\n \"audio\": \"<string>\",\n \"end_image\": \"<string>\",\n \"generate_audio\": true,\n \"image\": \"<string>\",\n \"length_seconds\": 5,\n \"reference_images\": [\n \"<string>\"\n ],\n \"resolution\": \"720p\",\n \"video\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.budgetpixel.com/v1/videos/seedance-2.0")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"<string>\",\n \"aspect_ratio\": \"16:9\",\n \"audio\": \"<string>\",\n \"end_image\": \"<string>\",\n \"generate_audio\": true,\n \"image\": \"<string>\",\n \"length_seconds\": 5,\n \"reference_images\": [\n \"<string>\"\n ],\n \"resolution\": \"720p\",\n \"video\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"message": "<string>",
"model": "<string>",
"status": "pending"
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}{
"error": {
"code": "model_not_available",
"message": "<string>",
"type": "invalid_request_error"
}
}Authorizations
API key as a bearer token: Authorization: Bearer bpx_live_xxx
Body
Text description of the video.
Aspect ratio. Ignored when an input image or video already sets the frame.
16:9, 9:16, 1:1, 4:3, 3:4, 21:9 Optional reference audio (MP3/WAV/OGG) for the generated video. Provide a public audio URL or an uploaded-file URL from POST /v1/uploads (passed by URL, not inlined). Must accompany reference_images or a video input — audio can't be the only input, and it can't be combined with image/end_image (start/end frames): to pair a picture with audio, pass the picture in reference_images.
Optional end frame, used together with image (the start frame) to interpolate the video between the two frames. Same input forms as image.
Generate audio with the video.
Optional start frame for image-to-video. Provide a public image URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads. Omit for text-to-video.
Video length in seconds (4–15).
4 <= x <= 15Optional reference images that guide the generated video. Each item is a public image URL, a data URI, raw base64, or an uploaded-file URL from POST /v1/uploads. Can't be combined with image/end_image (start/end frames). Up to 9 on their own (reference-images-to-video); may also accompany a video to guide a video-edit, in which case up to 6 are used.
9Output resolution. Pricing varies by resolution — see resolution_pricing in GET /v1/models. 4K output is H.265 (HEVC) 10-bit; 480p, 720p and 1080p are H.264.
480p, 720p, 1080p, 4k Optional input video for video-to-video editing (2-15s, ≤100MB). Provide a public video URL or an uploaded-file URL from POST /v1/uploads (videos are passed by URL, not inlined). When set, the request runs in video-edit mode; you may also pass reference_images (up to 6) and/or an audio track to guide the edit. Not combinable with image/end_image. Billed on the INPUT duration at half the output per-second rate in addition to the output — estimate via POST /v1/cost.