Seedance 2.5.
Inside your product.
Turn text, images and reference media into video with one API. Use your Seedance 3.0 credits, keep your existing workflow, and build with a clear request-to-result contract.
{
"model": "seedance-2.5",
"mode": "text-to-video",
"prompt": "A paper boat drifting into the morning light",
"duration": 5,
"resolution": "720p",
"aspectRatio": "16:9"
}Your first video, in a few requests.
Save your key as SEADANCE_API_KEY on your server. Set SEADANCE_REQUEST_KEY to a unique value for this video (for example, uuidgen), and keep that value for retries. Make sure your account has enough credits. This example reserves 350 credits for a 5-second 720p video. Copy the returned id to query its status.
export SEADANCE_API_KEY="sd_live_your_key"
# Keep this value for retries; choose a new value for a new video.
export SEADANCE_REQUEST_KEY="${SEADANCE_REQUEST_KEY:-$(uuidgen)}"
curl --fail-with-body "https://seedance3ai.dev/api/v1/videos" \
-H "Authorization: Bearer $SEADANCE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $SEADANCE_REQUEST_KEY" \
--data '{
"model": "seedance-2.5",
"mode": "text-to-video",
"prompt": "A paper boat floating through a sunlit stream, gentle camera movement",
"aspectRatio": "16:9",
"resolution": "720p",
"duration": 5
}'This documentation never runs a generation automatically. Sending a create request uses your credits.
Authenticate from your server.
Every API call uses Authorization: Bearer sd_live_…. Keep keys out of browsers, mobile apps, public repositories and client-side bundles. The full key is shown once; you can revoke it in the API dashboard.
https://seedance3ai.dev/api/v1Default key scopes: videos:write for uploads and generation; videos:read for models and task status; account:read for credits. Account access and limits apply across all keys.
Create a video task.
/api/v1/videosUse Content-Type: application/json and a unique Idempotency-Key for each intended generation. The server may take time to accept the upstream task. If your connection times out, repeat the same body with the same key. HTTP 202 means accepted, not finished. Idempotency-Key accepts 1–128 printable ASCII characters without spaces.
| Parameter | Values and requirements |
|---|---|
modelstring | seedance-2.5Required. The API currently supports Seedance 2.5. |
modestring | text-to-video | image-to-video | reference-to-videoRequired. Choose the input workflow; media fields must match this mode. |
promptstring | 3–30,000 charactersRequired. Describe the scene, movement and audio. |
durationinteger | 4, 5, 6, 8, 10, 12, 15, 20, 25, 29, 30Required, in seconds. Editing uses the source video length, rounded up for billing. |
resolutionstring | 480p | 720p | 1080pRequired. Determines the credit rate. |
aspectRatiostring | 1:1 | 4:3 | 3:4 | 16:9 | 9:16 | 21:9Required. Image-to-video uses the first frame ratio. |
firstFrameUrl / lastFrameUrlstring | Uploaded publicObjectUrlImage-to-video requires a first frame. A last frame is optional. |
referenceImageUrlsstring[] | Up to 30 imagesFor reference-to-video. Upload every file to your account first. |
referenceVideoUrls / referenceAudioUrlsstring[] | Up to 10 videos / 10 audio filesEach group totals at most 30 seconds. Server validates media before generation. |
referenceTaskTypestring | reference | edit | extendOptional, defaults to reference. Edit and extend require reference-to-video with exactly one source video. |
generateAudioboolean | trueOptional. Seedance 2.5 includes native audio; false is rejected. |
batchCountinteger | 1Optional. One video per request. |
Seedance 2.5 supports text, first/last frames, multimodal references, video editing and extension through these fields. GET /models is the current source of truth for available capabilities and pricing.
Image-to-video request example
{
"model": "seedance-2.5",
"mode": "image-to-video",
"prompt": "A paper boat floating through a sunlit stream, gentle camera movement",
"aspectRatio": "16:9",
"resolution": "720p",
"duration": 5,
"firstFrameUrl": "YOUR_UPLOADED_PUBLIC_OBJECT_URL"
}Reference-to-video request example
{
"model": "seedance-2.5",
"mode": "reference-to-video",
"prompt": "A paper boat floating through a sunlit stream, gentle camera movement",
"aspectRatio": "16:9",
"resolution": "720p",
"duration": 5,
"referenceImageUrls": [
"YOUR_UPLOADED_IMAGE_URL"
],
"referenceVideoUrls": [
"YOUR_UPLOADED_VIDEO_URL"
]
}Upload once. Reference by URL.
POST /uploads with fileName, contentType, size (bytes) and kind (image, video or audio). PUT the raw file bytes to uploadUrl using requiredHeaders before expiresAt. After the upload succeeds, use publicObjectUrl in the generation request. References must belong to the same account; arbitrary external URLs and base64 inputs are not accepted.
// Node.js 20+ · upload once, then use publicObjectUrl
import { readFile } from "node:fs/promises";
const bytes = await readFile("./first-frame.jpg");
const signed = await fetch("https://seedance3ai.dev/api/v1/uploads", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SEADANCE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
fileName: "first-frame.jpg", contentType: "image/jpeg",
size: bytes.length, kind: "image",
}),
});
const upload = await signed.json();
if (!signed.ok) throw new Error(JSON.stringify(upload));
const stored = await fetch(upload.uploadUrl, {
method: "PUT", headers: upload.requiredHeaders, body: bytes,
});
if (!stored.ok) throw new Error("Upload failed");
console.log(upload.publicObjectUrl);
// Use this URL as firstFrameUrl in an image-to-video request.The declared size and content type must match the uploaded file. Upload URLs expire; request another if needed. Media duration, dimensions and format are validated before generation.
Follow the task to completion.
GET /videos/:id returns the current task. Poll every 5–10 seconds, stop at succeeded or failed, and back off when Retry-After is present. Queries are restricted to API tasks owned by your account. The current integration uses polling.
curl --fail-with-body "https://seedance3ai.dev/api/v1/videos/TASK_ID" \
-H "Authorization: Bearer $SEADANCE_API_KEY"queuedprocessingsucceeded / failed{
"id": "a1b2c3d4-1234-4567-8901-abcdef123456",
"status": "succeeded",
"credits_reserved": 350,
"created_at": "2026-10-27T00:00:00.000Z",
"output": {
"url": "https://your-result-host.example/video.mp4"
},
"error": null,
"refund_status": "not_applicable"
}output is null until a video is available. A failed task includes an error; check refund_status for the credit refund state. Download successful results promptly. Deleting a video does not reset its request: replaying that Idempotency-Key returns 410 video_deleted and cannot create it again.
Know the credit cost before you build.
API generation uses the same account credits and Seedance 2.5 rates as the website. Credits are reserved when a request is accepted. Failed generations return those credits to your one-time balance. A validation failure before task creation does not create a billable video.
480p
30credits / output sec
+ 20 credits / reference video sec
720p
70credits / output sec
+ 50 credits / reference video sec
1080p
160credits / output sec
+ 90 credits / reference video sec
Cost = output duration × output rate, plus any reference-video duration × reference rate. Reference video time is measured on the server; the total is rounded down to whole seconds for billing. Native audio is included. For example, 5 seconds at 720p costs 350 credits, or 600 credits with a 5-second reference video.
curl --fail-with-body "https://seedance3ai.dev/api/v1/models" \
-H "Authorization: Bearer $SEADANCE_API_KEY"
curl --fail-with-body "https://seedance3ai.dev/api/v1/credits" \
-H "Authorization: Bearer $SEADANCE_API_KEY"See the API dashboard for available credits, request history and account limits. Add credits through the website pricing page using the same account; there is no separate API balance or API top-up endpoint. An active subscription is not required when you have enough available credits. Subscription expiration and one-time credit rules are the same as website usage.
Adding credits does not raise API rate, concurrency or daily limits, or re-enable a disabled account. The daily limit counts all reserved credits, including refunded failures, and resets at 00:00 UTC. Contact support if your application needs higher limits.
View plans and add creditsRetry safely. Avoid duplicate charges.
Use one Idempotency-Key per intended video and preserve it with the exact request body until the result is known. New keys represent new generations. An error response contains error.code, error.message and request_id; include the request ID when contacting support.
| HTTP | Meaning | Next step |
|---|---|---|
| 400 | Invalid request | Check the error message, fields, and media restrictions before retrying. |
| 401 | Invalid API key | Check the Bearer header. Revoked keys cannot be reused. |
| 402 | Insufficient credits | Add credits to the same Seedance 3.0 account. |
| 403 | Access denied | API access is disabled or the key lacks the required scope. |
| 404 | Video not found | Use a task ID created through this API by your account. |
| 409 | Request conflict | For request_in_progress, wait and retry the same body and key. idempotency_conflict means the key was reused for a different body. request_expired or request_previously_failed confirms no video was submitted: fix the reported issue, then use a new key. |
| 410 | Video deleted | video_deleted means the original request was processed, but its video was deleted. Its key cannot generate again. Stop retrying; use a new key only when you intentionally want a new, billable generation. |
| 429 | Account limit | Respect Retry-After. Rate, concurrent-task and daily-credit limits apply across all keys. Daily budgets reset at 00:00 UTC. |
| 500 / 503 | Temporary service error | Preserve the Idempotency-Key. Retry the same submission; do not create a new key after an uncertain result. |
If submission returns request_in_progress, wait and repeat the same request. Never switch to a new key just to get past a timeout. If a failed task's refund is still pending, keep its task ID and contact support.
Ready to connect?
Create a key and build your first integration.