Overview
The Seedance 2.0 API provides programmatic access to uncensored AI video generation. Through this API, you can:
- Upload media — Upload images or videos to cloud storage as reference material
- Generate videos — Create AI videos from text descriptions, reference images, or reference videos
- Track progress — Poll task status and retrieve generated video URLs
Typical Workflow
Authentication
All API requests must include an API key in the HTTP header for authentication.
Header Format
X-API-Key: <your_api_key>API Key Rules
| Format | String provided by admin |
| How to get | Contact admin to activate and receive your key |
Request Example
curl https://api.seedance2.movie/api/v1/video/balance \
-H "X-API-Key: <your_api_key>"Common Info
Base URL
https://api.seedance2.movieRequest Format
- • Content-Type: application/json
- • Encoding: UTF-8
- • HTTP methods: specified per endpoint
Response Format
All endpoints return a unified JSON structure:
Success Response
{
"code": "200",
"message": "Success",
"result": {
"...": "..."
}
}Error Response
{
"code": "INVALID_PARAMETER",
"message": "Invalid parameter: duration must be 4-15"
}Response Fields
| Field | Type | Description |
|---|---|---|
| code | string | Status code. "200" means success, other values indicate specific errors |
| message | string | Status description. "Success" when successful |
| result | object | null | Business data. May be null on error |
File Upload
Before submitting a generation task, if you need to use reference images or videos, you must first obtain a presigned upload URL, then upload the file via HTTP PUT.
Get Presigned Upload URL
/api/v1/video/upload/presignQuery Parameters
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| filename | string | Yes | — | File name (max 128 characters) |
| content_type | string | Yes | — | File MIME type |
Allowed Content Types
| image/png — .png |
| image/jpeg — .jpg, .jpeg |
| image/webp — .webp |
| video/mp4 — .mp4 |
| video/quicktime — .mov |
| video/webm — .webm |
Success Response
{
"code": "200",
"message": "Success",
"result": {
"presigned_url": "https://s3.amazonaws.com/bucket/api/uploads/1/uuid_scene.png?X-Amz-...",
"file_path": "api/uploads/1/uuid_scene.png",
"expires_in": 3600
}
}| Field | Description |
|---|---|
| presigned_url | Presigned upload URL (time-limited, use promptly) |
| file_path | Unique file identifier in cloud storage — use this when referencing the file in tasks |
| expires_in | URL expiration time in seconds |
Upload File
After obtaining the presigned URL, upload the file directly via HTTP PUT:
curl -X PUT "<presigned_url>" \
-H "Content-Type: image/png" \
--data-binary @./scene.png- • The Content-Type during upload must match the content_type used when getting the presigned URL
- • Presigned URLs have a limited validity period — upload promptly after obtaining one
- • After uploading, use the returned file_path to reference the file in generation tasks
Submit Video Generation Task
/api/v1/video/taskRequest Body (JSON)
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| model | string | No | seedance-2.0 | Model selection |
| content | array | Yes | — | Input content array (at least 1 item) |
| resolution | string | No | 720p | Video resolution |
| ratio | string | No | 16:9 | Aspect ratio |
| duration | integer | No | 5 | Video duration in seconds (4–15) |
| generate_audio | boolean | No | false | Whether to generate audio |
| seed | integer | No | — | Random seed (-1 or above, optional) |
| watermark | boolean | No | false | Whether to add watermark |
| callback_url | string | No | — | Callback URL for task completion notification (max 512 chars) |
| return_last_frame | boolean | No | false | Whether to return the last frame image |
Model Options
- • seedance-2.0 — Standard model (default)
- • seedance-2.0-fast — Fast model
Resolution Options
- • 480p
- • 720p (default)
- • 1080p
Aspect Ratio Options
Content Types
Each item in the content array must have a type field:
- •
text— Text prompt describing the video - •
image_url— Reference image (use file_path from upload) - •
video_url— Reference video (use file_path from upload) - •
audio_url— Reference audio - •
sample_id— Sample ID for reference
curl -X POST https://api.seedance2.movie/api/v1/video/task \
-H "X-API-Key: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"content": [
{ "type": "text", "text": "A cat running under cherry blossoms, warm sunlight" }
],
"resolution": "720p",
"ratio": "16:9",
"duration": 8,
"generate_audio": false
}'Success Response
{
"code": "200",
"message": "Success",
"result": {
"task_id": "a1b2c3d4e5f6...",
"status": "pending",
"credit_cost": 14.4
}
}Query Task Status
/api/v1/video/task/{task_id}Path Parameters
| task_id | Task ID returned from submit |
curl https://api.seedance2.movie/api/v1/video/task/a1b2c3d4e5f6 \
-H "X-API-Key: <your_api_key>"Success Response
{
"code": "200",
"message": "Success",
"result": {
"task_id": "a1b2c3d4e5f6...",
"model": "seedance-2.0",
"status": "completed",
"resolution": "720p",
"ratio": "16:9",
"duration": 8,
"generate_audio": false,
"seed": null,
"video_url": "https://cdn.example.com/video.mp4?token=...",
"last_frame_url": null,
"error_code": null,
"error_message": null,
"credit_cost": 14.4,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:33:45Z"
}
}| Field | Description |
|---|---|
| task_id | Task ID |
| model | Model used |
| status | Task status (see status table below) |
| resolution | Video resolution |
| ratio | Aspect ratio |
| duration | Video duration in seconds |
| generate_audio | Whether audio was generated |
| seed | Random seed used |
| video_url | Generated video download URL (available on success, signed URL valid for 7 days) |
| last_frame_url | Last frame image URL (if requested) |
| error_code | Error code (on failure) |
| error_message | Error description (on failure) |
| credit_cost | Credits consumed |
| created_at | Task creation time (ISO 8601) |
| updated_at | Last update time (ISO 8601) |
Task Status
| pending — Waiting to be processed (not terminal) |
| queued — Queued for generation (not terminal) |
| processing — Video is being generated (not terminal) |
| completed — Generation successful (terminal) |
| failed — Generation failed (terminal) |
| cancelled — Task was cancelled (terminal) |
| expired — Task expired (terminal) |
Polling Advice
- • Recommended polling interval: 5–10 seconds
- • Stop polling when status is completed, failed, cancelled, or expired
- • Generation typically takes 1–5 minutes depending on duration and resolution
Task List
/api/v1/video/tasksPaginated query of all tasks for the authenticated API key.
Query Parameters
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| page | integer | No | 1 | Page number (starts from 1, default: 1) |
| page_size | integer | No | 20 | Items per page (1–100, default: 20) |
| status | string | No | — | Filter by task status (optional) |
curl "https://api.seedance2.movie/api/v1/video/tasks?page=1&page_size=10" \
-H "X-API-Key: <your_api_key>"Success Response
{
"code": "200",
"message": "Success",
"result": {
"data": [
"{ ... task objects ... }"
],
"total": 42,
"page": 1,
"page_size": 10
}
}Cancel Task
/api/v1/video/task/{task_id}/cancelCancel a task that is in a non-terminal state. Tasks in pending status can be cancelled immediately. Tasks in queued or processing status will attempt cancellation with the provider.
curl -X POST https://api.seedance2.movie/api/v1/video/task/a1b2c3d4e5f6/cancel \
-H "X-API-Key: <your_api_key>"Success Response
{
"code": "200",
"message": "Success",
"result": {
"task_id": "a1b2c3d4e5f6...",
"status": "cancelled"
}
}Balance Query
/api/v1/video/balanceQuery the credit balance associated with the current API key.
curl https://api.seedance2.movie/api/v1/video/balance \
-H "X-API-Key: <your_api_key>"Success Response
{
"code": "200",
"message": "Success",
"result": {
"total_credits": 10000,
"used_credits": 3250.5,
"remain_credits": 6749.5
}
}| Field | Description |
|---|---|
| total_credits | Total credits in account |
| used_credits | Credits consumed |
| remain_credits | Remaining available credits |
Pricing
Billing Model
The API uses a post-pay model: credits are deducted only after a task completes successfully. Failed tasks are not charged.
Cost = price_per_second × durationPrice Per Second (Credits)
| Model | Resolution | Price / Second | Example (8s) |
|---|---|---|---|
| seedance-2.0 | 1080p | 4.5 | 36.0 |
| seedance-2.0 | 720p | 1.8 | 14.4 |
| seedance-2.0 | 480p | 0.9 | 7.2 |
| seedance-2.0-fast | 1080p | 3.312 | 26.50 |
| seedance-2.0-fast | 720p | 1.44 | 11.52 |
| seedance-2.0-fast | 480p | 0.72 | 5.76 |
The example column shows the cost for an 8-second video: price_per_second × 8.
For credit recharges, please contact the administrator.
Error Codes
Business Error Codes
| Code | Description |
|---|---|
| INVALID_API_KEY | Invalid or disabled API key |
| INVALID_PARAMETER | Invalid parameter value or format |
| MISSING_PARAMETER | Required parameter is missing |
| INSUFFICIENT_CREDIT | Insufficient credit balance |
| CREDIT_DEDUCT_FAILED | Credit deduction failed — please retry |
| TASK_NOT_FOUND | Task not found or does not belong to your API key |
| TASK_SUBMIT_FAILED | Task submission failed — please retry |
| TASK_CANCEL_NOT_ALLOWED | Task cannot be cancelled in its current status |
| CONCURRENCY_LIMIT_REACHED | Max concurrent tasks reached — task is queued |
| FILE_UPLOAD_FAILED | Failed to generate upload URL |
| VIDEO_DOWNLOAD_FAILED | Video processing failed |
| CONTENT_MODERATION_FAILED | Content moderation failed — input or output contains sensitive content |
| COPYRIGHT_VIOLATION | Content may violate copyright restrictions |
| PRIVACY_VIOLATION | Input contains real person imagery which is not allowed |
| SERVICE_BUSY | Service is temporarily busy — please retry later |
| RATE_LIMIT_EXCEEDED | Rate limit exceeded — please slow down |
| INTERNAL_ERROR | Internal server error |
HTTP Status Mapping
While most responses use HTTP 200 with error details in the body, the following HTTP status codes may also be returned:
- • 401 — Invalid API key
- • 400 — Invalid parameter, missing parameter, content moderation, or cancel not allowed
- • 402 — Insufficient credits
- • 404 — Task not found
- • 429 — Rate limit or concurrency limit reached
- • 500 — Internal server error or submission failure
- • 503 — Service busy
Code Examples
Image-to-Video (Python)
Upload an image and generate a video from it:
import requests
import time
API_BASE = "https://api.seedance2.movie"
API_KEY = "<your_api_key>"
HEADERS = {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
}
def upload_file(file_path, file_name, content_type):
"""Step 1: Get presigned URL and upload file"""
resp = requests.post(
f"{API_BASE}/api/v1/video/upload/presign",
headers=HEADERS,
params={"filename": file_name, "content_type": content_type},
)
resp.raise_for_status()
data = resp.json()["result"]
# Upload file to presigned URL
with open(file_path, "rb") as f:
requests.put(
data["presigned_url"],
headers={"Content-Type": content_type},
data=f,
).raise_for_status()
print(f"Uploaded: {data['file_path']}")
return data["file_path"]
def submit_task(file_path):
"""Step 2: Submit image-to-video task"""
resp = requests.post(
f"{API_BASE}/api/v1/video/task",
headers=HEADERS,
json={
"model": "seedance-2.0",
"content": [
{"type": "image_url", "image_url": file_path},
{"type": "text", "text": "The character slowly turns around, wind blowing through hair"},
],
"resolution": "720p",
"ratio": "16:9",
"duration": 8,
},
)
resp.raise_for_status()
result = resp.json()["result"]
print(f"Task submitted: {result['task_id']}")
return result["task_id"]
def poll_task(task_id, interval=5, timeout=600):
"""Step 3: Poll task status"""
elapsed = 0
while elapsed < timeout:
resp = requests.get(
f"{API_BASE}/api/v1/video/task/{task_id}",
headers=HEADERS,
)
task = resp.json()["result"]
print(f"[{elapsed}s] Status: {task['status']}")
if task["status"] == "completed":
print(f"Video URL: {task['video_url']}")
return task
if task["status"] in ("failed", "cancelled", "expired"):
print(f"Failed: {task.get('error_message', 'Unknown error')}")
return task
time.sleep(interval)
elapsed += interval
print("Polling timeout")
return None
if __name__ == "__main__":
path = upload_file("./character.png", "character.png", "image/png")
task_id = submit_task(path)
poll_task(task_id)Text-to-Video (Python)
Generate a video from a text prompt without uploading media:
import requests
import time
API_BASE = "https://api.seedance2.movie"
HEADERS = {
"X-API-Key": "<your_api_key>",
"Content-Type": "application/json",
}
# Submit text-to-video task
resp = requests.post(
f"{API_BASE}/api/v1/video/task",
headers=HEADERS,
json={
"model": "seedance-2.0",
"content": [
{"type": "text", "text": "A spaceship gliding past Saturn's rings, epic cinematic shot"}
],
"resolution": "720p",
"ratio": "21:9",
"duration": 10,
"generate_audio": True,
},
)
task_id = resp.json()["result"]["task_id"]
print(f"Task submitted: {task_id}")
# Poll until complete
while True:
resp = requests.get(
f"{API_BASE}/api/v1/video/task/{task_id}",
headers=HEADERS,
)
task = resp.json()["result"]
print(f"Status: {task['status']}")
if task["status"] == "completed":
print(f"Video URL: {task['video_url']}")
break
elif task["status"] in ("failed", "cancelled", "expired"):
print(f"Error: {task.get('error_message')}")
break
time.sleep(8)Complete Flow (cURL)
Step-by-step API usage with cURL:
# Step 1: Get presigned upload URL
curl -X POST "https://api.seedance2.movie/api/v1/video/upload/presign?filename=scene.png&content_type=image/png" \
-H "X-API-Key: <your_api_key>"
# Step 2: Upload file (use presigned_url from step 1)
curl -X PUT "<presigned_url>" \
-H "Content-Type: image/png" \
--data-binary @./scene.png
# Step 3: Submit generation task (use file_path from step 1)
curl -X POST "https://api.seedance2.movie/api/v1/video/task" \
-H "X-API-Key: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"content": [
{"type": "image_url", "image_url": "<file_path>"},
{"type": "text", "text": "The scene comes alive, flowers blooming"}
],
"duration": 8,
"ratio": "16:9"
}'
# Step 4: Query task status (use task_id from step 3)
curl "https://api.seedance2.movie/api/v1/video/task/<task_id>" \
-H "X-API-Key: <your_api_key>"