Limited Time Offer: Save up to 25% OFF now!

SD 2.0 API

Manage API Keys

Generate 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/credits

Important: 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
done

Endpoints

POST/api/v1/jobs/createTask

Create a new video generation task

GET/api/v1/jobs/queryTask

Query task status and result

GET/api/v1/account/credits

Check 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
ParameterTypeRequiredDescription
promptstringYesText description of the video to generate
durationstringNoVideo length: "4s" to "15s" (default: "5s")
resolutionstringNoAspect ratio via resolution. Options: 720x720, 720x960, 960x720, 1280x720, 720x1280, 1280x540
upscaleResolutionstringNoUpscale 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
ParameterTypeRequiredDescription
urlsstring[]YesArray with one image URL (the source frame). Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123")
promptstringNoText description of the desired motion
durationstringNoVideo length: "4s" to "15s" (default: "5s")
upscaleResolutionstringNoUpscale 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
ParameterTypeRequiredDescription
urlsstring[]YesArray with exactly 2 image URLs: [first_frame, last_frame]. Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123")
videoInputModestringYesMust be "keyframe"
promptstringNoText description guiding the transition
durationstringNoVideo length: "4s" to "15s" (default: "5s")
upscaleResolutionstringNoUpscale 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
ParameterTypeRequiredDescription
urlsstring[]NoReference image URLs (max 9). Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123")
videoUrlsstring[]NoReference video URLs (max 3, each ≤15s)
audioUrlsstring[]NoReference audio URLs (max 3, each ≤15s)
videoInputModestringYesMust be "reference"
promptstringNoText description
durationstringNoVideo length: "4s" to "15s" (default: "5s")
resolutionstringYesRequired for reference mode. Options: 720x720, 720x960, 960x720, 1280x720, 720x1280, 1280x540
upscaleResolutionstringNoUpscale 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.

ParameterTypeRequiredDescription
promptstringNoText description (required for text-to-video, optional for other modes)
urlsstring[]NoImage URLs. Supports both HTTP URLs and asset references (e.g. "asset://asset-20260326-abc123"). Maps to uploadedUrls internally.
videoUrlsstring[]NoVideo reference URLs (reference mode only)
audioUrlsstring[]NoAudio reference URLs (reference mode only)
durationstringNo"4s" to "15s". Default: "5s"
resolutionstringNo720x720 | 720x960 | 960x720 | 1280x720 | 720x1280 | 1280x540
videoInputModestringNo"keyframe" (default) or "reference"
upscaleResolutionstringNo"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.

ConfigurationFormulasd2 (5s)sd2-fast (5s)
Baseduration_seconds × 40200160
+ 2K Upscalebase + duration × 20300260
+ 4K Upscalebase + duration × 40400360
Reference + Video Refbase × 2 + upscale400320

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/createTask

Callback 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 CodeMeaningAction
400Invalid parametersCheck the error message and fix your request
401Invalid or missing API keyCheck your Authorization header format
402Insufficient creditsPurchase more credits at seegen.ai
403Access deniedYou can only query your own tasks
404Task not foundVerify the taskId is correct
429Concurrency limit (3 tasks)Wait for existing tasks to complete
500Internal server errorRetry 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