Seedance 3.0 Developer API / v1

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.

Shared account creditsAsynchronous video tasksIdempotent requests
POST /api/v1/videos
{
  "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 key. Your credits. Your application.
01 / START BUILDING

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.

Terminal
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.

Base URLhttps://seedance3ai.dev/api/v1

Default 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.

POST/api/v1/videos

Use 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.

ParameterValues and requirements
modelstringseedance-2.5

Required. The API currently supports Seedance 2.5.

modestringtext-to-video | image-to-video | reference-to-video

Required. Choose the input workflow; media fields must match this mode.

promptstring3–30,000 characters

Required. Describe the scene, movement and audio.

durationinteger4, 5, 6, 8, 10, 12, 15, 20, 25, 29, 30

Required, in seconds. Editing uses the source video length, rounded up for billing.

resolutionstring480p | 720p | 1080p

Required. Determines the credit rate.

aspectRatiostring1:1 | 4:3 | 3:4 | 16:9 | 9:16 | 21:9

Required. Image-to-video uses the first frame ratio.

firstFrameUrl / lastFrameUrlstringUploaded publicObjectUrl

Image-to-video requires a first frame. A last frame is optional.

referenceImageUrlsstring[]Up to 30 images

For reference-to-video. Upload every file to your account first.

referenceVideoUrls / referenceAudioUrlsstring[]Up to 10 videos / 10 audio files

Each group totals at most 30 seconds. Server validates media before generation.

referenceTaskTypestringreference | edit | extend

Optional, defaults to reference. Edit and extend require reference-to-video with exactly one source video.

generateAudiobooleantrue

Optional. Seedance 2.5 includes native audio; false is rejected.

batchCountinteger1

Optional. 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
request.json
{
  "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
request.json
{
  "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"
  ]
}
BRING YOUR REFERENCES

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.

upload.mjs
// 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.

GET /api/v1/videos/:id
curl --fail-with-body "https://seedance3ai.dev/api/v1/videos/TASK_ID" \
  -H "Authorization: Bearer $SEADANCE_API_KEY"
queuedprocessingsucceeded / failed
Example successful task
{
  "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.

ONE ACCOUNT, ONE BALANCE

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.

Read models, pricing and your balance
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 credits

Retry 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.

HTTPMeaningNext step
400Invalid requestCheck the error message, fields, and media restrictions before retrying.
401Invalid API keyCheck the Bearer header. Revoked keys cannot be reused.
402Insufficient creditsAdd credits to the same Seedance 3.0 account.
403Access deniedAPI access is disabled or the key lacks the required scope.
404Video not foundUse a task ID created through this API by your account.
409Request conflictFor 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.
410Video deletedvideo_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.
429Account limitRespect Retry-After. Rate, concurrent-task and daily-credit limits apply across all keys. Daily budgets reset at 00:00 UTC.
500 / 503Temporary service errorPreserve 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.

Open API dashboard