Skip to content

Seedance: video generation API

Generate video with Seedance 2.0 / 2.5: parameters, results, and caveats.

ItemValue
Base URLhttps://api.hop-base.com/v1
Submit a taskPOST /v1/video/generate
Poll a taskGET /v1/video/tasks/{task_id}
List tasksGET /v1/video/tasks
Upload an asset (2.0 only)POST /v1/sd/assets
Key groupChina: "Seedance China (Doubao)"; overseas: "Seedance overseas + Seedream"

Available models

VariantModel IDResolutionsDuration (s)Official price
2.0 Standard (China)doubao-seedance-2-0-260128-a480p / 720p / 1080p4–15$4.12from/ 1M tokens
2.0 Fast (China)doubao-seedance-2-0-fast-260128-a480p / 720p4–15$2.43from/ 1M tokens
2.0 Mini (China)doubao-seedance-2-0-mini-260615-a480p / 720p4–15$0.824from/ 1M tokens
2.5 (China)doubao-seedance-2-5-260628-a480p / 720p / 1080p4–30$6.18from/ 1M tokens
2.0 Standard (Overseas)dreamina-seedance-2-0-hc
dreamina-seedance-2-0-ep
dreamina-seedance-2-0-260128
480p / 720p / 1080p / 4K4–15$2.40from/ 1M tokens
2.0 Fast (Overseas)dreamina-seedance-2-0-fast-hc
dreamina-seedance-2-0-fast-ep
dreamina-seedance-2-0-fast-260128
480p / 720p4–15$3.30from/ 1M tokens
2.0 Mini (Overseas)dreamina-seedance-2-0-mini-hc
dreamina-seedance-2-0-mini-ep
dreamina-seedance-2-0-mini-260615
480p / 720p4–15$2.10from/ 1M tokens
2.5 (Overseas)dreamina-seedance-2-5-260628480p / 720p / 1080p4–30$6.40from/ 1M tokens

On overseas 2.5, 1080p works only where your group supports it, and 4K is not supported.

China models are served by the Seedance China (Doubao) group and overseas models by the Seedance overseas + Seedream group. The China group covers Standard, Fast, Mini, and Seedance 2.5; only 4K needs the overseas Standard model. Overseas keys cannot call doubao-* IDs.

Per-tier prices and full specs for each model are on its model card, for example dreamina-seedance-2-5-260628 and doubao-seedance-2-0-260128-a.

Request parameters

All fields are top-level JSON fields — do not nest them under parameters. Integers and booleans sent as strings ("5", "true") or integers sent as decimals are rejected. The whole request body is capped at 64 MB, inline Data URLs included.

ParameterRequiredType & limitsDefaultDescription
modelRequireda model ID from the table above—Sets the duration, resolution and media limits
contentRequirednon-empty array, shapes below—The prompt goes in a text item
durationOptionalinteger; 2.0: 4–15 or -1; 2.5: 4–30 or -12.0: 5; 2.5: -1Length in seconds; -1 lets the model choose
resolutionOptionalper model in the model table720pMust be one the model lists
ratioOptional16:9 / 4:3 / 1:1 / 3:4 / 9:16 / 21:9 / adaptiveadaptiveadaptive follows the reference image or lets the model choose
generate_audioOptionalboolean2.5: true; 2.0: noneOn 2.0, send it explicitly
watermarkOptionalboolean2.5: false; 2.0: noneOn 2.0, send it explicitly
return_last_frameOptionalboolean2.5: trueReturns task.last_frame_url when available; not guaranteed on 2.0
priorityOptionalinteger 0–9—Scheduling hint for the task queue; completion time is not guaranteed
execution_expires_afterOptionalinteger 3600–259200 (seconds)—Does not change the 24-hour limit
callback_urlOptionalHTTP(S) URL—Does not replace polling
safety_identifierOptional1–64 ASCII characters—Stable ID for your end user, used for abuse monitoring; do not put personal data in it

frames, seed, camera_fixed, draft, draft_task, and service_tier are rejected (400) on both generations. Every field is also listed in API reference: Submit a video task.

Common mistakes when porting from OpenAI-style APIs.

size, seconds, n, and aspect_ratio are not Seedance parameters: they are ignored without an error, and the task runs at the default duration and 720p. Use duration, resolution, and ratio.

content items

content items are text / image_url / video_url / audio_url:

"content": [
  { "type": "text", "text": "An orange cat runs across the grass, camera follows" },
  { "type": "image_url", "image_url": { "url": "https://example.com/cat.png" }, "role": "reference_image" },
  { "type": "video_url", "video_url": { "url": "https://example.com/ref.mp4" } },  // role defaults to reference_video
  { "type": "audio_url", "audio_url": { "url": "https://example.com/ref.mp3" } }   // role defaults to reference_audio
]

An image's role is first_frame, last_frame, or reference_image:

  • A single image without a role is treated as the first frame.
  • Multiple images must set roles.
  • When a video or audio reference is present, images must be reference_image.
  • Frame mode takes at most 2 images: one must be first_frame, two must be one first_frame and one last_frame, and it cannot be mixed with references.
  • A Seedance 2.0 audio reference must be paired with an image or video; 2.5 accepts audio-only input.

Images and audio may be base64 Data URLs; video may not. Seedance 2.0 also accepts a ready asset://asset-id.

Reference media specs

These rules apply to Seedance 2.0 and 2.5, China and overseas, not to every video model.

Every reference is downloaded and checked at submit; a failing one returns an immediate 400 (no code; match on message) and incurs no task cost. Media that passes can still fail later on content review.

ItemImageVideoAudio
Count limit2.0: 9; 2.5: 302.0: 3; 2.5: 102.0: 3; 2.5: 10
Formatsjpg / jpeg / png / webp / bmp / tif / tiff / gif / heic / heifmp4 / mov (container must be MP4/ISO-BMFF)wav / mp3
Size< 30 MiB≤ 200 MiB≤ 15 MiB
Dimensions300-6000 px per side300-6000 px per side; total pixels 409,600-8,295,044-
Aspect ratio0.4-2.50.4-2.5-
Duration-2.0: 2-15s; 2.5: 2-30s2.0: 2-15s; 2.5: 2-30s
Frame rate-24-60 FPS-

Frame mode takes at most 2 images. The combined video and audio totals fall under the same cap as a single clip and are counted separately, not added together: on 2.0 all reference videos together must be ≤ 15 seconds, all reference audio together also ≤ 15 seconds, and each clip ≥ 2 seconds.

The output duration and reference-media durations are independent limits. 1 MiB = 1,048,576 bytes.

Media URL must be a publicly reachable http(s) address:

  • Private / loopback / link-local addresses and URLs with credentials are rejected.
  • At most 3 redirects are followed.
  • Each item must download and parse within 2 minutes.
  • Data URLs must be data:<MIME>;base64,….

Asset library (Seedance 2.0 only)

The asset library takes an existing public media URL and returns an asset ID, which you reference as asset://asset-id in Seedance 2.0 generation. Ordinary references can also use direct URLs without registration.

Upload. Save the returned data.Id; acceptance does not mean readiness.

curl https://api.hop-base.com/v1/sd/assets \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "URL": "https://example.com/your-image.jpg",
    "Name": "character_front",
    "AssetType": "Image"
  }'
{
  "data": {
    "Id": "assetEXAMPLE"
  }
}

Wait until ready. Query with the same group key roughly every 5 seconds, with a timeout. data.Status of Active means ready (completed / succeeded are also accepted, case-insensitively).

curl https://api.hop-base.com/v1/sd/assets/assetEXAMPLE \
  -H "Authorization: Bearer sk-your-key"
{
  "data": {
    "Id": "assetEXAMPLE",
    "Status": "Active",
    "AssetType": "Image"
  }
}

Wait while processing. Handle upload or moderation failures instead of submitting generation or polling forever.

Reference. Prefix the complete data.Id with asset:// and put it in generation content; do not substitute any URL from the query response.

curl https://api.hop-base.com/v1/video/generate \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "dreamina-seedance-2-0-260128",
  "content": [
    {
      "type": "text",
      "text": "The subject waves gently at the camera"
    },
    {
      "type": "image_url",
      "image_url": {
        "url": "asset://assetEXAMPLE"
      },
      "role": "reference_image"
    }
  ],
  "duration": 5,
  "resolution": "720p",
  "ratio": "16:9"
}'

Upload request fields:

FieldRequiredType & limitsDefaultDescription
URL (or url)Requiredpublic HTTP(S) URL; no base64 or multipart—Host local files first
AssetType (or asset_type)RequiredImage / Video / Audio, case-insensitive—Media type of the asset; checked against "Reference media specs"
NameOptionalstring—Label for your own reference; not used in generation
Duration (or duration / duration_seconds)Optionalinteger seconds—The real duration is still checked

The upload downloads and checks the media against the 2.0 rules in "Reference media specs", so video and audio must run 2–15 seconds. Upload 400s carry error.code (for example invalid_asset_duration).

Adjust the content item to the media type:

  • Video: type: video_url, video_url.url: asset://…, and role: reference_video.
  • Audio: audio_url / reference_audio.
  • For a first-frame image use role: first_frame, and for a last frame last_frame; do not mix first/last frames with multimodal references.

Do not rewrite asset IDs or reuse them across groups or users. Generation still checks readiness, type, counts, and specifications; registration bypasses neither the 2.0 limits nor content moderation.

Response

Submit and single-task query responses are wrapped in task; do not read a top-level id / outputs.

Submit response

A successful submit returns 200 with a task.id such as vt… for later status queries. The submit response carries only id, model, status (pending or processing), outputs (always empty), error, created_at, and completed_at; get results by querying.

{
  "task": {
    "id": "vtEXAMPLE",
    "model": "dreamina-seedance-2-5-260628",
    "status": "pending",
    "outputs": [],
    "error": null,
    "created_at": "2026-09-23T08:00:00Z",
    "completed_at": null
  }
}

Task query fields

FieldDescription
task.idHopBase task ID, vt…
task.statusOne of pending / processing / completed / failed
task.outputsOutput URLs, an array of strings, not {url} objects
task.duration_secondsClip length; for auto-duration tasks, read after completion
task.last_frame_urlOptional, only when a last frame exists; re-signed on every query
task.usage.completion_tokensBillable token count; tokens, not a dollar amount
task.error.messageFailure reason in English, no code field
task.completed_atnull until finished
usage.cost / usage.cost_cny / usage.cost_usdActual charge once the task ends; see Video overview

task.status is always one of these four values. Read task.outputs only on completed: a task reports completed only after its result links are ready, so outputs is never empty then. On pending / processing, keep polling; every 5 seconds is recommended.

480p and 720p generation usually takes 2-5 minutes; 1080p and 4K take longer. Output URLs support browser playback and Range requests and expire 30 days after completion.

In progress

{
  "task": {
    "id": "vtEXAMPLE",
    "model": "dreamina-seedance-2-5-260628",
    "status": "processing",
    "outputs": [],
    "error": null,
    "created_at": "2026-09-23T08:00:00Z",
    "completed_at": null
  }
}

Succeeded

Below is an excerpt of a completed task (HTTP 200); IDs, URLs, and usage are illustrative:

{
  "task": {
    "id": "vtEXAMPLE",                       // HopBase task ID
    "model": "dreamina-seedance-2-5-260628",
    "status": "completed",
    "duration_seconds": 5,                   // for auto-duration tasks, read after completion
    "outputs": ["https://api.hop-base.com/example-signed-video.mp4"],  // array of strings, not {url} objects
    "last_frame_url": "https://api.hop-base.com/example-signed-last-frame.jpg",  // optional, only when a last frame exists
    "usage": { "completion_tokens": 1000, "total_tokens": 1000 },  // optional; tokens, not a dollar amount
    "error": null,
    "created_at": "2026-09-23T08:00:00Z",
    "completed_at": "2026-09-23T08:03:10Z"   // null until finished
  },
  "usage": { "cost": 3.4, "currency": "CNY", "cost_cny": 3.4, "cost_usd": 0.5 }
}

Failed

A failed generation still returns HTTP 200 on query, with status failed and the reason in task.error.message. Failed tasks are not billed.

{
  "task": {
    "id": "vtEXAMPLE",
    "status": "failed",
    "outputs": [],
    "error": { "message": "<English failure reason>" }
  }
}

The message is English with no code field. Links are replaced by [URL_REDACTED], and request IDs and internal error codes are removed; when no reason is available it is a generic English fallback.

Task list

GET /v1/video/tasks accepts ?page=1&limit=20 and returns {"tasks": [...], "total": 1, "totalPages": 1}, where each element is a task object. limit defaults to 20 (maximum 100), and only API-submitted tasks are listed.

Minimal example

# 1. Submit
curl https://api.hop-base.com/v1/video/generate \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dreamina-seedance-2-5-260628",
    "content": [
      { "type": "text", "text": "An orange cat runs across sunlit grass as the camera follows" }
    ],
    "duration": 5,
    "resolution": "720p",
    "ratio": "16:9",
    "generate_audio": false,
    "watermark": false
  }'

# 2. Poll with the returned task.id; every 5 seconds is recommended
curl https://api.hop-base.com/v1/video/tasks/vt-your-task-id \
  -H "Authorization: Bearer sk-your-key"

Notes

Seedance 2.5 task modes

Seedance 2.5 has no explicit task-mode parameter. When a request carries a reference_video, Seedance classifies it as ordinary generation, video extension, or video editing based on the prompt text. A continuation-style prompt ("continue this clip", "extend the shot") is treated as video extension.

ModeMust send
Video editingduration: -1 and ratio: "adaptive"
Video extension, first/last-frameratio: "adaptive"
These rules are not checked at submit.

The submit still returns 200 and the task only turns failed during polling, with no charge. When a reference video is present and the prompt could read as continuing the source clip, send ratio: "adaptive".

The failure message reads like identified your task as video extension based on your prompt. Seedance 2.0 has no extension or editing mode and is unaffected.

Real-person reference images

Real-person reference images.

An image with a real person passed directly (URL or Data URL) may be rejected at submit: a synchronous 4xx with error.code input_sensitive and a message explaining the fix. On Seedance 2.0, use the asset library; 2.5 has no asset library and cannot use real-person references yet.

Seedance 2.0: upload the same image to the asset library (above) and reference it as asset://asset-id once ready. If you need a real-person reference, switch to 2.0 with the asset library. Registration does not bypass other content review.

  • A task still unfinished 24 hours after creation is failed automatically and not billed.
  • Video tasks cannot be cancelled; do not resubmit after a successful submit, because every resubmission is another billed task.
  • Output URLs are signed URLs on api.hop-base.com, valid for 30 days after completion; querying again does not extend them, and an expired URL returns 410.

Moving from the overseas group to the China group

The China group also accepts the overseas dreamina-* IDs above as compatibility aliases (4K is still rejected). Existing clients moving from overseas to China only swap the key — base_url, API paths, request parameters, and polling logic stay the same.

After switching, call GET /v1/models with the new key to pick the complete model ID. Tasks submitted earlier remain queryable with their original task IDs.

Common errors and fixes

Three shapes copied from other APIs are rejected outright:

What you sentFix
A top-level prompt alonePut the prompt in content[].text
image_url as a stringSend an object {"url": …}
type as image / input_imageUse image_url / video_url / audio_url

Submit-time parameter errors

These errors return 400 synchronously; no task is created and nothing is billed. The body is {"error":{"message":"…","type":"invalid_request_error"}} with no code field, so match on message (numbers and indexes vary):

# Types and values
duration must be an integer                    # same for priority / execution_expires_after
watermark must be a boolean                    # same for generate_audio / return_last_frame
Seedance 2.0 duration must be an integer in 4-15 or -1, got 20
Seedance 2.5 duration must be an integer in 4-30 or -1, got 40
model dreamina-seedance-2-0-hc does not support parameter seed   # rejected field; names the model you requested
model dreamina-seedance-2-0-hc does not support ratio 2:1
model dreamina-seedance-2-0-fast-hc does not support resolution 1080p
request body must not exceed 64MB
priority must be within 0-9, got 10
execution_expires_after must be within 3600-259200 seconds
callback_url must be a valid http(s) URL
safety_identifier must be an ASCII string of 1-64 characters

# content structure
missing content                                # only a top-level prompt was sent
content[0].image_url must be an object         # image_url sent as a string
content[0].type does not support image         # type sent as image / input_image
content[0].text must not be empty
multi-image scenarios must specify first_frame/last_frame or reference_image roles
images in a multimodal reference scenario must set role=reference_image
first/last frame image-to-video cannot be mixed with the multimodal reference scenario
Seedance 2.0 supports at most 9 reference images

# Model and group
domestic doubao-seedance-2-0-fast-260128-a only supports 480p, 720p, got 1080p
model seedream-5-0-pro is an image generation model, use POST /v1/images/generations instead

Two cases are not these 400s:

ErrorFix
404 The current group does not support the requested model: <model ID>The model ID is not in your key's group (e.g. a doubao-* ID with an overseas key); use a key from the group that serves the model
Ends with only supports 480p or 720p, got 1080pOverseas 2.5 asked for 1080p and your group does not support it; nothing is downgraded, so use 720p or a group that supports 1080p

The 404 comes before the checks above; read valid IDs from GET /v1/models.

Reference media errors

content[1] is the item's index in content:

content[1] media URL returned HTTP 403        # the host refused the download (hotlink protection, expired signature…)
content[1] unable to fetch media file, make sure the URL is publicly accessible
content[1] media URL hostname could not be resolved
content[1] media URL must point to a public address, not a private or reserved one
content[1] too many redirects for media URL
content[1] unable to parse media metadata of the video asset   # corrupt file or wrong format
content[1] media data URL must be base64-encoded
content[1] image data URL does not support MIME type image/svg+xml
    # allowed: image/jpeg png webp bmp tiff gif heic heif; audio/wav audio/mpeg
content[1] reference image width and height must be within 300-6000 px, got 200x200
content[1] video asset duration must be within 2-15 seconds, got 16.000 seconds
total reference video duration must not exceed 15 seconds, got 18.000 seconds

If a reference cannot be downloaded and parsed within 2 minutes, the submit returns 503 with code upstream_timeout:

media validation timed out, please retry later

This is a temporary service-side condition, not a problem with your media. Retry the same request later.

Asset-library reference errors are also synchronous 400s without a code:

content[1] reference asset is not ready yet, current status is Processing  # keep querying; submit once Active
content[1] requires a image asset, got Video       # AssetType does not match image_url / video_url / audio_url
content[1] references a retired Seedance 2.5 EP asset; ...  # asset25-* is retired; pass the original public URL
... cannot be mixed in one task                    # reference assets from one upload batch, or pass public URLs

Task failure reasons

OutputVideoSensitiveContentDetected / OutputAudioSensitiveContentDetected  # output failed review; PolicyViolation = copyright
rejected by content moderation                                             # the generated video, prompt, or reference media failed moderation
InputImageSensitiveContentDetected, other Input…Sensitive…                  # input media failed review, incl. real-person privacy
InvalidParameter / is not valid / missing required / identified your task as  # invalid parameter or task mode
task no longer exists                                                        # the task no longer exists
task expired / timed out / did not finish within 24 hours                     # the task timed out

Review and parameter failures (the first four) fail again if resubmitted unchanged: change the prompt, media, or parameter first. The last two can be resubmitted as is.

Billing

Seedance bills by video tokens; task.usage.completion_tokens is the billable token count. Failed tasks and submit-time 400s are not billed.

A submit reserves balance for the estimated cost, released when the task ends. With duration: -1, 2.5 reserves for 30 seconds and 2.0 for 15; when balance is tight, send an explicit duration to reserve less. Balance rules and the usage.cost fields are in Video overview; official prices per model are in the table above and on the model cards, and each request's actual charge is on the Usage page in the console.

Next steps