SD 2.0 API
Manage API KeysGenerate AI videos programmatically using the SD 2.0 model. Create text-to-video, image-to-video, keyframe, and multi-reference videos through a simple REST API.
Introduction
The SD 2.0 API provides programmatic access to the same SD 2.0 video generation capabilities available on seegen.ai. Your API usage shares the same account, credits, and task history as the web interface.
Base URL: https://seegen.ai/api/v1
Model: sd2 or sd2-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://seegen.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": "sd2",
"inputs": {
"prompt": "A golden retriever running on the beach at sunset",
"duration": "5s",
"resolution": "1280x720"
}
}' \
https://seegen.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://seegen.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": "sd2",
"inputs": {
"prompt": "A futuristic city with flying cars at night, neon lights reflecting on wet streets",
"duration": "5s",
"resolution": "1280x720"
}
}' \
https://seegen.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": "sd2",
"inputs": {
"urls": ["https://example.com/photo.jpg"], // or "asset://asset-20260326-abc123"
"prompt": "The woman slowly turns her head and smiles",
"duration": "5s"
}
}' \
https://seegen.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": "sd2",
"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://seegen.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": "sd2",
"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://seegen.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 sd2 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 | sd2 (5s) | sd2-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": "sd2",
"callBackUrl": "https://your-server.com/webhook/seedance",
"inputs": {
"prompt": "A cat playing piano",
"duration": "5s"
}
}' \
https://seegen.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": "sd2",
"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": "sd2",
"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 seegen.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://seegen.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: "sd2",
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