S
Seedance 2.0 API Guide

Seedance 2.0 Video Generation API

Access ByteDance Seedance 2.0 video generation models through the TokenHub unified API. Supports text-to-video, image-to-video, video editing, audio-driven generation and more. This guide walks you through the complete integration process.

Text → VideoImage → VideoVideo → VideoAudio Reference480p / 720p / 1080p4–15 sec

1Get Your API Key

  1. Visit tokenhub.store to create an account (GitHub / Google sign-in supported)
  2. Go to Dashboard → API Keys, click "Create New Key"
  3. Go to Dashboard → Billing to add credits (1 Credit = $1 USD)
  4. Copy your API Key (format: th-xxxxxxxxxxxx...
⚠️ The API Key is only shown once upon creation. Save it securely. If lost, you'll need to create a new one.

2API Overview

Base URL

https://tokenhub.store/api/v1

Authentication

All requests require an API Key in the header:

Header
Authorization: Bearer th-your-api-key

Two Endpoints

POST
/videos/generations

Create a video generation task, returns task ID

GET
/videos/generations/{task_id}

Query task status, returns video URL on success

3Models & Pricing

Model IDInputPriceDescription
doubao-seedance-2.0No video input$6.970/1M (1080p $7.727)Flagship model, highest quality. 1080p supported.
With video input$4.242/1M (1080p $4.697)Flagship with video input, cost-effective.
doubao-seedance-2.0-fastNo video input$5.606/1MFast model, quicker generation.
With video input$3.333/1MFast model with video input, most affordable.

Billing Details:

  • Output video: billed per 1M tokens (token count depends on resolution and duration)
  • Input image: free (no charge)
  • Input video: billed per 1M tokens at the with-video-input rate
  • Total cost = total tokens consumed × per-token rate (see table above)

Example: doubao-seedance-2.0 without video input (≤720p), generating a 5s video at ~1M tokens → cost ≈ $6.970

4Request Parameters

ParameterTypeRequiredDescription
modelstringRequiredModel ID, e.g. "doubao-seedance-2.0"
promptstringRequiredVideo description text. English prompts generally yield better results
durationnumberOptionalVideo duration (sec), range 4–15, default 5
resolutionstringOptional"480p", "720p", or "1080p" (default 720p; 1080p only for doubao-seedance-2.0)
aspect_ratiostringOptionalAspect ratio: "adaptive" (default), "16:9", "9:16", "1:1", etc.
image_urlstringOptionalReference image URL (image-to-video)
image_urlsstring[]OptionalArray of multiple reference image URLs
video_urlstringOptionalReference video URL (video editing / video-to-video)
video_urlsstring[]OptionalArray of multiple reference video URLs (max 3)
video_durationsnumber[]OptionalArray of per-video durations in seconds, e.g. [3, 5]
input_video_durationnumberOptionalTotal input video duration in seconds (alternative to video_durations)
audio_urlstringOptionalReference audio URL (background music / SFX)
audio_urlsstring[]OptionalArray of multiple reference audio URLs (max 3)
generate_audiobooleanOptionalWhether to generate audio, default true
watermarkbooleanOptionalWhether to add watermark, default false
contentarrayOptionalMedia assets array. Each item: { type: "image_url", image_url: { url }, role }. Supported roles: first_frame (max 1), last_frame (max 1), reference_image, reference_video, reference_audio

5Input Limits

You can freely combine text, images, videos, and audio as input. Note the following limits:

Images: 0–9 per request
Videos: 0–3 per request, each 2–15s, total duration ≤ 15s
Audios: 0–3 per request, each 2–15s, total duration ≤ 15s
❌ "Text + Audio only" and "Pure Audio" input are NOT supported

Supported Formats

  • Image formats: JPEG, PNG, WebP, BMP, TIFF, GIF (max 30MB each)
  • Video formats: MP4, MOV (H.264/H.265, max 50MB each)
  • Audio formats: WAV, MP3 (max 15MB each)
⚡ Tip: Only video duration affects billing. Total cost = (input video duration + output video duration) × rate. Input images are free.

6Complete API Examples

The most basic usage — describe a scene in text to generate a video.

bash
curl -X POST https://tokenhub.store/api/v1/videos/generations \
  -H "Authorization: Bearer th-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2.0",
    "prompt": "A golden retriever running on a sunny beach, waves crashing in the background, cinematic slow motion, 4K quality",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9",
    "watermark": false
  }'

Response:

json
{
  "id": "xxxxxx-task-id",
  "object": "video.generation.task",
  "model": "doubao-seedance-2.0",
  "status": "queued",
  "created": 1719900000
}

Video generation is asynchronous — poll the status until complete.

bash
# Poll task status using the task_id from creation response
curl https://tokenhub.store/api/v1/videos/generations/YOUR_TASK_ID \
  -H "Authorization: Bearer th-your-api-key"

Task in progress:

json
{
  "id": "YOUR_TASK_ID",
  "object": "video.generation.task",
  "model": "doubao-seedance-2.0",
  "status": "running",
  "created": 1719900000
}

Task completed (video URL received):

json
{
  "id": "YOUR_TASK_ID",
  "object": "video.generation.task",
  "model": "doubao-seedance-2.0",
  "status": "succeeded",
  "created": 1719900000,
  "data": [
    {
      "video_url": "https://tokenhub-data.tos-cn-hongkong.volces.com/user_sd_file/YOUR_TASK_ID.mp4",
      "cover_image_url": "https://tokenhub-data.tos-cn-hongkong.volces.com/user_sd_file/YOUR_TASK_ID_cover.jpg"
    }
  ],
  "usage": {
    "video_duration": 5
  }
}
💡 Recommended polling interval: every 3-5 seconds. Status values: queued → waiting, running → generating, succeeded → done, failed → error

7Python Full Example

python
import requests
import time

API_BASE = "https://tokenhub.store/api/v1"
API_KEY = "th-your-api-key"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# Step 1: Create video generation task
payload = {
    "model": "doubao-seedance-2.0",
    "prompt": "A majestic eagle soaring over snow-capped mountains, golden hour lighting, cinematic aerial shot",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9",
    "watermark": False
}

resp = requests.post(f"{API_BASE}/videos/generations", json=payload, headers=headers)
task = resp.json()
task_id = task["id"]
print(f"Task created: {task_id}, status: {task['status']}")

# Step 2: Poll for result
while True:
    resp = requests.get(f"{API_BASE}/videos/generations/{task_id}", headers=headers)
    result = resp.json()
    status = result["status"]
    print(f"Status: {status}")

    if status == "succeeded":
        video_url = result["data"][0]["video_url"]
        duration = result["usage"]["video_duration"]
        print(f"Video ready! Duration: {duration}s")
        print(f"URL: {video_url}")
        break
    elif status == "failed":
        print(f"Failed: {result.get('error', {}).get('message', 'Unknown error')}")
        break

    time.sleep(5)

8JavaScript / Node.js Full Example

javascript
const API_BASE = "https://tokenhub.store/api/v1";
const API_KEY = "th-your-api-key";

const headers = {
  "Authorization": `Bearer ${API_KEY}`,
  "Content-Type": "application/json"
};

// Step 1: Create task
const createResp = await fetch(`${API_BASE}/videos/generations`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    model: "doubao-seedance-2.0",
    prompt: "A majestic eagle soaring over snow-capped mountains, cinematic aerial shot",
    duration: 5,
    resolution: "720p",
    aspect_ratio: "16:9",
    watermark: false,
  }),
});
const task = await createResp.json();
console.log("Task created:", task.id);

// Step 2: Poll for result
const poll = async () => {
  while (true) {
    const resp = await fetch(`${API_BASE}/videos/generations/${task.id}`, { headers });
    const result = await resp.json();
    console.log("Status:", result.status);

    if (result.status === "succeeded") {
      console.log("Video URL:", result.data[0].video_url);
      console.log("Duration:", result.usage.video_duration, "seconds");
      return result;
    }
    if (result.status === "failed") {
      console.error("Failed:", result.error?.message);
      return result;
    }
    await new Promise(r => setTimeout(r, 5000));
  }
};

await poll();

9Image-to-Video Python Example

python
import requests, time

API_BASE = "https://tokenhub.store/api/v1"
headers = {
    "Authorization": "Bearer th-your-api-key",
    "Content-Type": "application/json"
}

# Image-to-Video with a single reference image
payload = {
    "model": "doubao-seedance-2.0",
    "prompt": "The woman in the photo turns to face the camera and smiles warmly, her hair gently blowing in the wind",
    "duration": 5,
    "resolution": "720p",
    "image_url": "https://your-bucket.com/portrait.jpg",
    "watermark": False
}

resp = requests.post(f"{API_BASE}/videos/generations", json=payload, headers=headers)
task_id = resp.json()["id"]
print(f"Task: {task_id}")

# Poll for result
while True:
    r = requests.get(f"{API_BASE}/videos/generations/{task_id}", headers=headers).json()
    if r["status"] == "succeeded":
        print(f"Done: {r['data'][0]['video_url']}")
        break
    elif r["status"] == "failed":
        print(f"Error: {r.get('error', {}).get('message')}")
        break
    time.sleep(5)

10Real-Person Image to Video

When your input image contains a real person, TokenHub automatically routes the request to an upstream that supports real-person generation. No client changes required.

Triggers automatically when the upstream content filter detects a real person in the input image.

Request shape is identical to ordinary image-to-video — same POST /v1/videos/generations body.

Two possible response shapes

  • Normal: { "id": "cgt-...", "status": "queued" } (existing behaviour)
  • Real-person path: { "id": "pat-...", "status": "queued" } — additional asset processing, expect 10-90 seconds of extra latency

GET polling is identical — call /v1/videos/generations/{id} with whichever id POST returned, until status is succeeded or failed. The id rewrites are handled server-side; you always see the same id for the lifetime of the request.

Error: unsupported_real_person_input

Returned with status 400 when no real-person-capable provider is configured for your account. Contact your administrator to enable a supported provider.

Error: Asset processing timed out

Returned via GET with status: failed when the upstream asset preparation exceeds 5 minutes. Safe to retry the request.

Complete lifecycle example

The pat-id is opaque to your client — keep polling until status changes.

bash
# POST
curl -X POST https://tokenhub.store/api/v1/videos/generations \
  -H "Authorization: Bearer $TH_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2.0",
    "prompt": "let her dance and spin",
    "duration": 8,
    "resolution": "480p",
    "content": [
      { "type": "image_url", "image_url": { "url": "https://example.com/portrait.png" }, "role": "first_frame" }
    ]
  }'
# → {"id":"pat-abc123","status":"queued"}

# GET (asset still uploading)
curl https://tokenhub.store/api/v1/videos/generations/pat-abc123 -H "Authorization: Bearer $TH_KEY"
# → {"id":"pat-abc123","status":"queued"}

# GET (upstream task running)
# → {"id":"pat-abc123","status":"running"}

# GET (complete — id stays pat-, video_url in data)
# → {"id":"pat-abc123","status":"succeeded","data":[{"video_url":"..."}]}

11Prompt Tips

Basic Structure

Recommended format: [Subject] + [Action] + [Environment/Background] + [Camera/Style]

Good Prompt Examples

  • "A young woman walking through a cherry blossom garden, petals falling in slow motion, soft natural lighting, cinematic 35mm film look"
  • "Close-up of hands pouring latte art into a ceramic cup, steam rising, warm cafe ambiance, shallow depth of field"
  • "Aerial drone shot of a winding river through autumn forest, golden and red leaves, morning mist, 4K cinematic"

Tips for Reference Images/Videos

  • Use "image 1", "image 2", "video 1", "audio 1" in the prompt to reference your assets
  • Specify scene content per time segment (e.g. "0-2s: xxx, 2-4s: xxx")
  • Specify start/end frames (e.g. "first frame is image 1", "end frame freezes on image 2")
  • Specify camera composition source (e.g. "use video 1 POV throughout")
  • Specify audio usage (e.g. "use audio 1 as background music throughout")

Tips

  • English prompts generally produce better results; Chinese is also supported
  • More specific, vivid descriptions lead to better results
  • Avoid overly abstract descriptions (e.g. "a nice video")
  • Camera language greatly improves quality (slow motion, close-up, aerial shot, tracking shot...)

12FAQ

Ready to Start?

Sign up for TokenHub and start using the Seedance 2.0 Video Generation API now

© 2026 TokenHub · Powered by ByteDance Seedance 2.0 · support@tokenhub.store