Seedance 2.5 Extend
curl --request POST \
--url https://api.freemodel.app/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"seconds": "<string>",
"aspect_ratio": "<string>",
"resolution": "<string>",
"video_urls": [
"<string>"
],
"generate_audio": true
}
'import requests
url = "https://api.freemodel.app/v1/videos"
payload = {
"model": "<string>",
"prompt": "<string>",
"seconds": "<string>",
"aspect_ratio": "<string>",
"resolution": "<string>",
"video_urls": ["<string>"],
"generate_audio": True
}
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({
model: '<string>',
prompt: '<string>',
seconds: '<string>',
aspect_ratio: '<string>',
resolution: '<string>',
video_urls: ['<string>'],
generate_audio: true
})
};
fetch('https://api.freemodel.app/v1/videos', 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.freemodel.app/v1/videos",
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([
'model' => '<string>',
'prompt' => '<string>',
'seconds' => '<string>',
'aspect_ratio' => '<string>',
'resolution' => '<string>',
'video_urls' => [
'<string>'
],
'generate_audio' => true
]),
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.freemodel.app/v1/videos"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"seconds\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"video_urls\": [\n \"<string>\"\n ],\n \"generate_audio\": true\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.freemodel.app/v1/videos")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"seconds\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"video_urls\": [\n \"<string>\"\n ],\n \"generate_audio\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.freemodel.app/v1/videos")
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 \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"seconds\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"video_urls\": [\n \"<string>\"\n ],\n \"generate_audio\": true\n}"
response = http.request(request)
puts response.read_bodySeedance 2.5
Seedance 2.5 Extend
Seedance 2.5 Extend video API via FreeModel: video extension mode model of Seedance 2.5, billed from prepaid balance.
POST
/
v1
/
videos
Seedance 2.5 Extend
curl --request POST \
--url https://api.freemodel.app/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"seconds": "<string>",
"aspect_ratio": "<string>",
"resolution": "<string>",
"video_urls": [
"<string>"
],
"generate_audio": true
}
'import requests
url = "https://api.freemodel.app/v1/videos"
payload = {
"model": "<string>",
"prompt": "<string>",
"seconds": "<string>",
"aspect_ratio": "<string>",
"resolution": "<string>",
"video_urls": ["<string>"],
"generate_audio": True
}
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({
model: '<string>',
prompt: '<string>',
seconds: '<string>',
aspect_ratio: '<string>',
resolution: '<string>',
video_urls: ['<string>'],
generate_audio: true
})
};
fetch('https://api.freemodel.app/v1/videos', 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.freemodel.app/v1/videos",
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([
'model' => '<string>',
'prompt' => '<string>',
'seconds' => '<string>',
'aspect_ratio' => '<string>',
'resolution' => '<string>',
'video_urls' => [
'<string>'
],
'generate_audio' => true
]),
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.freemodel.app/v1/videos"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"seconds\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"video_urls\": [\n \"<string>\"\n ],\n \"generate_audio\": true\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.freemodel.app/v1/videos")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"seconds\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"video_urls\": [\n \"<string>\"\n ],\n \"generate_audio\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.freemodel.app/v1/videos")
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 \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"seconds\": \"<string>\",\n \"aspect_ratio\": \"<string>\",\n \"resolution\": \"<string>\",\n \"video_urls\": [\n \"<string>\"\n ],\n \"generate_audio\": true\n}"
response = http.request(request)
puts response.read_bodyseedance-2.5-extend is the video extension mode model of Seedance 2.5: it continues one to three source clips, up to 1080p.
| Property | Value |
|---|---|
| Model ID | seedance-2.5-extend |
| Input | prompt + video |
| Output | 480p, 720p, 1080p video with native audio |
| Duration | 4 to 30 seconds |
| Price | 480p: $0.15 per second; 720p: $0.335 per second; 1080p: $0.815 per second |
| Reference video billing | Billed seconds = output seconds + reference seconds, measured by the gateway (15 s billed if a clip cannot be measured) |
string
required
Set to
seedance-2.5-extend.string
required
Describe the subject, action, camera movement, lighting, and audio intent.
string
default:"10"
Output length: 4 to 30 seconds.
string
One of
adaptive. adaptive follows the input image or video. Send it explicitly; do not send a pixel size.string
default:"720p"
One of
480p, 720p, 1080p. The price depends on the resolution.string[]
required
One to 3 public source or reference clips, each up to 50 MB (MP4, MOV).
The gateway reads each clip’s length from its MP4/MOV header with HTTP range requests and bills that length, rounded up to whole seconds (up to 15 s). Host clips where range requests work, such as S3, R2, or most CDNs; a clip that cannot be measured bills 15 s.
boolean
default:"true"
Set to
false for a silent video.Request
curl https://api.freemodel.app/v1/videos \
-H "Authorization: Bearer $FREEMODEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5-extend",
"prompt": "The boat keeps drifting toward the shore",
"seconds": "5",
"aspect_ratio": "adaptive",
"resolution": "720p",
"video_urls": ["https://example.com/source.mp4"]
}'
id. Poll and download with the same model:
curl "https://api.freemodel.app/v1/videos/$VIDEO_ID?model=seedance-2.5-extend" \
-H "Authorization: Bearer $FREEMODEL_API_KEY"
curl -L "https://api.freemodel.app/v1/videos/$VIDEO_ID/content?model=seedance-2.5-extend" \
-H "Authorization: Bearer $FREEMODEL_API_KEY" \
--output video.mp4
Price examples
| Resolution | Per second | 5-second clip |
|---|---|---|
| 480p | $0.15 | $0.75 |
| 720p | $0.335 | $1.675 |
| 1080p | $0.815 | $4.075 |
Media inputs must be public
http or https URLs. Private network addresses and
local files are rejected. Failed generations are not charged.