Seedance video generation uses an asynchronous task model. A create-task request returns only a task ID, and the video does not appear in the response. The integrator has to query the status, handle failures, and copy the result to storage before the link expires.

If you write code with the synchronous mindset of Chat Completions, you will usually time out at the first step. This article follows the order of a real deployment and explains the base URL, authentication, submission, polling, download, callbacks, and idempotency.

Note: Seedance, ByteDance, Doubao, Volcano Engine, and Volcano Ark are names and trademarks of their respective owners. This article is for technical explanation only and does not imply any partnership, agency, or endorsement relationship. Endpoint paths, model names, and prices are subject to the official or on-site documentation.

1. Integration parameters: base URL, model, and authentication

The official Volcano Ark data-plane base URL is https://ark.cn-beijing.volces.com/api/v3, and the path for creating a video task is /contents/generations/tasks. Authentication uses Authorization: Bearer $ARK_API_KEY, and the request body is JSON.

The model field accepts either a model ID or an endpoint ID. The difference lies in authentication: with an API key, both are usually accepted; with AK/SK signing, you generally must supply an endpoint ID and cannot pass a model ID directly. This is one of the most common traps during migration and debugging.

Before integrating, confirm three things: whether the model is enabled, whether the account quota is sufficient, and whether the current channel supports the duration and resolution you intend to use. Gateway users should first read the on-site documentation to confirm that the video channel and task fields match the official interface.

Operation Method and path Notes
Create task POST /contents/generations/tasks Returns a task ID, not a video
Query task GET /contents/generations/tasks/{id} Returns status and result
List tasks GET /contents/generations/tasks Batch reconciliation and compensation
Cancel task Cancellation or deletion endpoint per documentation Usually only effective for queued tasks

Support for cancellation, deletion, and list queries varies by platform, so check the documentation before integrating. Do not append /api/v3 twice to the base URL, or you will get a path error.

2. Submitting a task: what one POST must carry

Below is a common task creation request. The fields are examples only:

export ARK_API_KEY="your-api-key"
export BASE_URL="https://ark.cn-beijing.volces.com/api/v3"

curl -sS -X POST "$BASE_URL/contents/generations/tasks" \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-1-0-pro-250528",
    "content": [
      {"type": "text", "text": "A harbor at dawn, container cranes, slow aerial orbit, realistic style"},
      {"type": "image_url", "image_url": {"url": "https://example.com/first-frame.jpg"}, "role": "first_frame"}
    ],
    "duration": 5,
    "ratio": "16:9",
    "resolution": "720p",
    "watermark": false,
    "callback_url": "https://api.example.com/callbacks/seedance"
  }'

Several fields deserve attention:

  • content is an array. Text, first-frame images, reference images, and reference videos each use different type and role values.
  • The allowed ranges for duration, ratio, and resolution change with the model version. Do not copy them directly from another provider's documentation.
  • watermark controls whether the output carries a watermark. Confirm platform rules before commercial use.
  • callback_url receives task completion notifications, and whether it is supported depends on the actual platform.
  • Fields such as seed, camera_fixed, and return_last_frame are not supported by every model.

After a successful submission, write the task ID from the response to your database immediately and bind it to the business order number. Polling, retries, reconciliation, and cost allocation all depend on this ID.

3. Polling: state machine and backoff strategy

Querying a task requires only the task ID:

curl -sS "$BASE_URL/contents/generations/tasks/$TASK_ID" \
  -H "Authorization: Bearer $ARK_API_KEY"

Common states and how to handle them:

status Meaning Recommended action
queued Waiting in queue Keep waiting; cancel if necessary
running Generating Keep polling; do not resubmit
succeeded Succeeded Read the result and copy it to storage immediately
failed Failed Record the error code and decide whether a retry is appropriate
expired Terminated by timeout Adjust the timeout or parameters, then resubmit
cancelled Cancelled Confirm whether the business cancelled it intentionally

Do not poll once per second at a fixed interval. Start at 5 seconds and back off to 10, then 20 seconds, capping around 30 seconds, and add a small amount of random jitter so multiple instances do not hit the upstream at the same moment. Set an overall timeout appropriate to the business, for example 10 minutes. When it expires, mark the task for manual review rather than waiting indefinitely.

Task records are usually queryable only for a limited period; official documentation gives a figure of about 7 days. Beyond that window, historical status can only come from your own task table, so persist every state change promptly.

4. Downloading and storing results

After a task succeeds, the response includes a video URL. That URL usually expires; official documentation puts the validity at about 24 hours, and some models limit the number of downloads. Do not hand it to a frontend or a customer as if it were a permanent CDN address.

The correct pattern is to download immediately on success, copy the file to your own object storage, and record the task ID, business order number, object path, file size, and checksum. Only then write the internal address into your business database. This way, even after the upstream link expires, historical orders can still be replayed and delivered.

The download step must also account for large files, resumable transfers, concurrency limits, and retry on failure. If the response also returns a first-frame image or audio, store each field separately instead of saving only the video.

5. Webhook or polling

Both approaches can deliver results. The difference is latency and operational cost:

Approach Advantages Disadvantages Suitable for
Webhook Low latency, fewer wasted queries Requires a public endpoint, signature verification, and replay protection Production async tasks
Polling Simple to implement, no public endpoint required Adds latency and extra requests Internal tools, testing, fallback
Hybrid Callback first, polling as fallback Requires state deduplication Most production systems

The more robust production pattern is callback plus reconciliation: callbacks provide low latency, while a scheduled job scans records that have stayed out of a terminal state for too long and acts as the safety net. The callback endpoint must verify signatures and be idempotent. It must not insert a record or trigger downstream work twice just because a notification arrived. Lost callbacks are not rare, so they cannot be the only notification mechanism.

6. Idempotency and duplicate submissions

Video tasks are expensive and slow, so duplicate submissions cost far more than they do for text APIs. Control this at four levels:

  • Generate a business idempotency key before submission, such as the order number plus a version, and check the database before submitting.
  • Put a unique index on the task ID and business order number so the database blocks duplicate records.
  • A request timeout does not mean the task failed. Look up the idempotency key, or query the task list, and confirm nothing was created before retrying.
  • Retry only 429, 5xx, and network errors. Do not blindly retry 400 parameter errors or content moderation rejections.

Record the reason for cancellations and resubmissions as well. Otherwise one business order may produce several videos, which raises costs and makes reconciliation difficult. Run a daily reconciliation job that compares task status, billing, and output artifacts.

7. Common errors and troubleshooting

  • 401 AuthenticationError: the key is missing or invalid, the request header is malformed, or the base URL does not match the key.
  • 403 AccessDenied, AccountOverdueError: insufficient permission, an account in arrears, or a service that is not enabled.
  • 404 ModelNotOpen, UnsupportedModel: the model is not enabled, or its name is misspelled.
  • 400 SensitiveContentDetected: the prompt or source material triggered content review. Replace the material instead of retrying repeatedly.
  • 400 InvalidParameter: a field name, duration, ratio, or resolution is outside the allowed range.
  • 429 RateLimitExceeded: reduce concurrency and apply exponential backoff; request a higher quota if needed.
  • failed or expired: read error.code and error.message to distinguish parameter problems, moderation rejection, and upstream outages.

Error code strings may change as the platform evolves, so rely on the actual response and the error code documentation. Logging the raw error code, request ID, and redacted request parameters together significantly shortens diagnosis time.

8. Migration checklist

When moving from the official interface to a gateway, or from one gateway to another platform, confirm each item below:

  1. The base URL and authentication method are replaced as a set, not just the key.
  2. Whether model takes a model ID or an endpoint ID, and whether that matches the current authentication method.
  3. Request field names, duration, ratio, and resolution are within the new channel's supported range.
  4. The status enumeration covers queued, running, succeeded, failed, expired, and cancelled.
  5. The result link's validity period, download limit, and copy-to-storage logic have been verified.
  6. The callback address is publicly reachable, with signature verification and idempotent handling in place.
  7. Idempotency keys, the task table, reconciliation jobs, and alerts are live.
  8. Rate limits, timeouts, retries, and concurrency caps have been load-tested.

After migration, run a small batch first and compare success rate, average latency, and cost per video before scaling up. Do not switch all traffic over without a reconciliation mechanism.

FAQ

Does the Seedance API return a video synchronously?

Usually not. Creating a task returns only a task ID. You need to poll or wait for a callback, then download the video after success. Designing around a synchronous interface leads to timeouts and duplicate submissions.

How long are task IDs and results retained?

According to official documentation, task records are usually queryable for about 7 days, and result video links are valid for about 24 hours. Long-term retention requires copying results to your own object storage.

What polling interval is appropriate?

Start at 5 seconds and back off gradually to 15 or 30 seconds, with an overall timeout. Fixed high-frequency polling wastes requests and is more likely to trigger rate limiting.

Does it support Webhook callbacks?

The official create-task endpoint provides a callback_url field, but delivery depends on network conditions and platform policy. Whether a gateway supports callbacks should be confirmed in its documentation, and production systems should keep polling as a fallback.

Are failed tasks billed?

Rules differ by platform and failure type. Before integrating, confirm how moderation rejections, timeouts, and cancellations are billed, and verify with a small batch against your invoice.

Next steps

First run one task with the shortest duration and a lower resolution, then fill in the task table, polling, storage, and reconciliation. If you need a unified entry point, register with the ZSQH AI Gateway and confirm the Seedance channel and billing method on the model pricing page.

Related reading: