Seedance2 API
Manage API KeysGenerate AI videos programmatically using the Seedance 2.0 model. Create text-to-video, image-to-video, keyframe, and multi-reference videos through a simple REST API.
Introduction
The Seedance2 API provides programmatic access to the same Seedance 2.0 video generation capabilities available on seedance2-ai.ai. Your API usage shares the same account, credits, and task history as the web interface.
Base URL: https://seedance2-ai.ai/api/v1
Model: seedance2 or seedance2-fast
Authentication
All API requests require a Bearer token in the Authorization header. You can create and manage API keys from your Account Settings.
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://seedance2-ai.ai/api/v1/account/creditsImportant: Your API key is shown only once at creation. Store it securely. You can create up to 10 API keys per account.
Quick Start
Generate a video in two steps: create a task, then poll for the result.
# 1. Create a text-to-video task
TASK_ID=$(curl -s -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2",
"inputs": {
"prompt": "A golden retriever running on the beach at sunset",
"duration": "5s",
"resolution": "1280x720"
}
}' \
https://seedance2-ai.ai/api/v1/jobs/createTask | jq -r '.taskId')
echo "Task created: $TASK_ID"
# 2. Poll for result
while true; do
RESULT=$(curl -s -H "Authorization: Bearer $API_KEY" \
"https://seedance2-ai.ai/api/v1/jobs/queryTask?taskId=$TASK_ID")
STATUS=$(echo $RESULT | jq -r '.status')
echo "Status: $STATUS"
if [ "$STATUS" = "COMPLETED" ] || [ "$STATUS" = "FAILED" ]; then
echo $RESULT | jq .
break
fi
sleep 5
doneEndpoints
/api/v1/jobs/createTaskCreate a new video generation task
/api/v1/jobs/queryTaskQuery task status and result
/api/v1/account/creditsCheck your credits balance
Text to Video
Generate a video from a text prompt. No images required.
curl -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2",
"inputs": {
"prompt": "A futuristic city with flying cars at night, neon lights reflecting on wet streets",
"duration": "5s",
"resolution": "1280x720"
}
}' \
https://seedance2-ai.ai/api/v1/jobs/createTask| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | Yes | Text description of the video to generate |
| duration | string | No | Video length: "4s" to "15s" (default: "5s") |
| resolution | string | No | Aspect ratio via resolution. Options: 720x720, 720x960, 960x720, 1280x720, 720x1280, 1280x540 |
| upscaleResolution | string | No | Upscale output: "2k" or "4k" |
Image to Video
Animate a static image into a video. Provide one image URL as the starting frame.
curl -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2",
"inputs": {
"urls": ["https://example.com/photo.jpg"], // or "asset://asset-20260326-abc123"
"prompt": "The woman slowly turns her head and smiles",
"duration": "5s"
}
}' \
https://seedance2-ai.ai/api/v1/jobs/createTask| Parameter | Type | Required | Description |
|---|---|---|---|
| urls | string[] | Yes | Array with one image URL (the source frame). Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123") |
| prompt | string | No | Text description of the desired motion |
| duration | string | No | Video length: "4s" to "15s" (default: "5s") |
| upscaleResolution | string | No | Upscale output: "2k" or "4k" |
First & Last Frame
Define the starting and ending frames, and the model generates the transition between them. Uses videoInputMode: "keyframe".
curl -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2",
"inputs": {
"urls": [
"https://example.com/first-frame.jpg",
"https://example.com/last-frame.jpg"
],
"prompt": "Smooth camera transition from day to night",
"duration": "5s",
"videoInputMode": "keyframe"
}
}' \
https://seedance2-ai.ai/api/v1/jobs/createTask| Parameter | Type | Required | Description |
|---|---|---|---|
| urls | string[] | Yes | Array with exactly 2 image URLs: [first_frame, last_frame]. Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123") |
| videoInputMode | string | Yes | Must be "keyframe" |
| prompt | string | No | Text description guiding the transition |
| duration | string | No | Video length: "4s" to "15s" (default: "5s") |
| upscaleResolution | string | No | Upscale output: "2k" or "4k" |
Multi-Reference
Use multiple reference images, videos, and audio files to guide generation. Uses videoInputMode: "reference".
curl -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2",
"inputs": {
"urls": [
"https://example.com/ref1.jpg",
"https://example.com/ref2.jpg"
],
"videoUrls": ["https://example.com/motion-ref.mp4"],
"audioUrls": ["https://example.com/audio.mp3"],
"prompt": "Character walks through a garden",
"duration": "5s",
"videoInputMode": "reference",
"resolution": "1280x720"
}
}' \
https://seedance2-ai.ai/api/v1/jobs/createTask| Parameter | Type | Required | Description |
|---|---|---|---|
| urls | string[] | No | Reference image URLs (max 9). Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123") |
| videoUrls | string[] | No | Reference video URLs (max 3, each ≤15s) |
| audioUrls | string[] | No | Reference audio URLs (max 3, each ≤15s) |
| videoInputMode | string | Yes | Must be "reference" |
| prompt | string | No | Text description |
| duration | string | No | Video length: "4s" to "15s" (default: "5s") |
| resolution | string | Yes | Required for reference mode. Options: 720x720, 720x960, 960x720, 1280x720, 720x1280, 1280x540 |
| upscaleResolution | string | No | Upscale output: "2k" or "4k" |
Reference Constraints
- Max 9 images, 3 videos, 3 audio files
- Max 12 total files across all types
- Each video/audio must be ≤ 15 seconds
- Images must be at least 400px on the shortest side
Parameters Reference
Complete reference of all inputs parameters for the seedance2 model.
| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | No | Text description (required for text-to-video, optional for other modes) |
| urls | string[] | No | Image URLs. Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123"). Maps to uploadedUrls internally. |
| videoUrls | string[] | No | Video reference URLs (reference mode only) |
| audioUrls | string[] | No | Audio reference URLs (reference mode only) |
| duration | string | No | "4s" to "15s". Default: "5s" |
| resolution | string | No | 720x720 | 720x960 | 960x720 | 1280x720 | 720x1280 | 1280x540 |
| videoInputMode | string | No | "keyframe" (default) or "reference" |
| upscaleResolution | string | No | "2k" or "4k" for higher quality output |
Top-level request fields: model (required), inputs (required), callBackUrl (optional webhook URL).
Credits & Pricing
API usage consumes the same credits as the web interface. Credits are calculated based on duration and options.
| Configuration | Formula | seedance2 (5s) | seedance2-fast (5s) |
|---|---|---|---|
| Base | duration_seconds × 40 | 200 | 160 |
| + 2K Upscale | base + duration × 20 | 300 | 260 |
| + 4K Upscale | base + duration × 40 | 400 | 360 |
| Reference + Video Ref | base × 2 + upscale | 400 | 320 |
Check your balance: GET /api/v1/account/credits
Webhook Callback
Instead of polling, you can provide a callBackUrl to receive results automatically when a task completes or fails.
curl -X POST \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2",
"callBackUrl": "https://your-server.com/webhook/seedance",
"inputs": {
"prompt": "A cat playing piano",
"duration": "5s"
}
}' \
https://seedance2-ai.ai/api/v1/jobs/createTaskCallback Payload
When the task finishes, we send a POST request to your URL with the same format as the queryTask response:
// POST to your callBackUrl
{
"taskId": "task_abc123",
"model": "seedance2",
"status": "COMPLETED",
"creditsUsed": 200,
"output": [
{
"url": "https://static.seedance2-pro.com/videos/result.mp4",
"width": 1280,
"height": 720
}
],
"error": null,
"createTime": 1711234567890,
"completeTime": 1711234612345
}Retry Policy: If your endpoint returns a non-2xx status, we retry up to 3 times with increasing delays (1s, 5s, 30s).
Response Format
createTask Response
// 200 OK
{ "taskId": "task_abc123" }queryTask Response
{
"taskId": "task_abc123",
"model": "seedance2",
"status": "COMPLETED", // "PENDING" | "PROCESSING" | "COMPLETED" | "FAILED"
"creditsUsed": 200,
"output": [ // null when status is not "COMPLETED"
{
"url": "https://static.seedance2-pro.com/videos/result.mp4",
"width": 1280,
"height": 720
}
],
"error": null, // error message when status is "FAILED"
"createTime": 1711234567890,
"completeTime": 1711234612345
}credits Response
{
"credits": 5000,
"availableCredits": 4800
}Error Handling
| Status Code | Meaning | Action |
|---|---|---|
| 400 | Invalid parameters | Check the error message and fix your request |
| 401 | Invalid or missing API key | Check your Authorization header format |
| 402 | Insufficient credits | Purchase more credits at seedance2-ai.ai |
| 403 | Access denied | You can only query your own tasks |
| 404 | Task not found | Verify the taskId is correct |
| 429 | Concurrency limit (3 tasks) | Wait for existing tasks to complete |
| 500 | Internal server error | Retry after a few seconds |
Full Examples
Complete workflow: create a task, poll for completion, and handle the result.
const API_KEY = process.env.API_KEY;
const BASE = "https://seedance2-ai.ai/api/v1";
const headers = {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
};
// Check credits first
async function checkCredits() {
const res = await fetch(`${BASE}/account/credits`, { headers });
return res.json();
}
// Create a task (any mode)
async function createTask(inputs, callBackUrl) {
const res = await fetch(`${BASE}/jobs/createTask`, {
method: "POST",
headers,
body: JSON.stringify({
model: "seedance2",
inputs,
...(callBackUrl && { callBackUrl }),
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`[${res.status}] ${err.message}`);
}
return res.json();
}
// Poll until done (timeout: 5 min)
async function waitForResult(taskId, timeoutMs = 300000) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const res = await fetch(
`${BASE}/jobs/queryTask?taskId=${taskId}`,
{ headers }
);
const result = await res.json();
if (result.status === "COMPLETED") return result;
if (result.status === "FAILED") throw new Error(result.error);
await new Promise((r) => setTimeout(r, 5000));
}
throw new Error("Timeout waiting for task");
}
// Example: Image to Video
async function main() {
const { availableCredits } = await checkCredits();
console.log(`Credits: ${availableCredits}`);
const { taskId } = await createTask({
urls: ["https://example.com/photo.jpg"],
prompt: "The person slowly looks up and smiles",
duration: "5s",
});
console.log(`Task: ${taskId}`);
const result = await waitForResult(taskId);
console.log(`Video: ${result.output[0].url}`);
}
main().catch(console.error);Need help? Join our Discord or contact us