Seedance 2.5 Draft API
Draft mode lets you preview a 480p video before generating a 1080p final video from its task ID. The two steps create two independent task IDs, each queried and billed separately.
Models and endpoints
| Item | Description |
|---|---|
| Model name | seedance-2.5 or doubao-seedance-2-5-260628; use the exact name enabled for your account |
| Create a draft or final video | POST /api/v3/contents/generations/tasks |
| Query a task | GET /api/v3/contents/generations/tasks/{id} |
| Production base URL used here | https://api.exchangetoken.ai |
| Authentication | Authorization: Bearer <YOUR_API_KEY> |
Your account needs access to a Seedance 2.5 channel that supports draft mode. Use the same API key and exact model name for both steps.
These examples use seedance-2.5. If your account uses the versioned model name, replace model in both create requests.
Step 1: Create a draft
Set these environment variables:
export ET_BASE='https://api.exchangetoken.ai'
export ET_TOKEN='sk-xxxxxx'Create request:
curl -sS "$ET_BASE/api/v3/contents/generations/tasks" \
-H "Authorization: Bearer $ET_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"content": [
{"type": "text", "text": "A fox walks slowly through a forest as the camera follows steadily"}
],
"duration": 5,
"ratio": "16:9",
"resolution": "480p",
"output_format": "mp4",
"draft": true
}'Example create response:
{"id": "sg_vid_draft_example"}Save the actual returned id. This platform draft task ID is used for querying and creating the final video.
| Field | Type | Description |
|---|---|---|
model | string | Exact Seedance 2.5 model name enabled for your account |
content | object[] | Prompt and any image, video, or audio inputs supported by the model |
draft | boolean | Must be true |
resolution | string | Only 480p; the platform supplies 480p if omitted |
duration, ratio, generate_audio, seed | Depends on field | Set during draft creation; omit when creating the final video |
output_format | string | mp4 or mov; the official default is mp4, subject to channel support |
Step 2: Query and preview the draft
Replace the variable with the actual ID returned in Step 1:
export DRAFT_TASK_ID='sg_vid_draft_example'
curl -sS "$ET_BASE/api/v3/contents/generations/tasks/$DRAFT_TASK_ID" \
-H "Authorization: Bearer $ET_TOKEN"Continue polling while the status is queued or running, for example every 10 seconds. The draft must reach succeeded before you can use it to generate a final video.
Example success response:
{
"id": "sg_vid_draft_example",
"status": "succeeded",
"content": {"video_url": "https://example.com/draft.mp4"},
"resolution": "480p"
}Preview or download the draft from the actual content.video_url. Result URLs expire, so save the video promptly. Stop polling on failed, cancelled, or expired, then inspect the failure or create a new draft.
Step 3: Generate a final video from the draft
Once you approve the draft, pass its platform ID in content.draft_task.id:
curl -sS "$ET_BASE/api/v3/contents/generations/tasks" \
-H "Authorization: Bearer $ET_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"seedance-2.5\",
\"content\": [
{\"type\": \"draft_task\", \"draft_task\": {\"id\": \"$DRAFT_TASK_ID\"}}
],
\"resolution\": \"1080p\",
\"output_format\": \"mp4\"
}"The response returns a new final video task ID:
{"id": "sg_vid_final_example"}Final video constraints:
contentmust contain exactly onedraft_taskreferencing a successful draft.- Use the Exchange Token
sg_vid_...ID, rather than a supplier task ID. resolutionmust be1080p; the platform supplies1080pif omitted.- Omit
draftor set it tofalse. - Omit
duration,ratio,seed,generate_audio, andomni_reference_task_type. Do not add text, images, video, or audio; the generation settings are reused from the draft. - Output options such as
output_format,return_last_frame, andwatermarkmay be set again if supported by the channel. Omitted output options use model defaults rather than the draft's values. - Draft tasks are valid for 7 days from creation. Create a new draft after expiry.
- The final video uses the draft's original channel and remains subject to account permissions, quota, and rate limits. Cross-channel fallback and
fixchan/fallbackrouting overrides are unavailable for this workflow.
Output format
Both examples explicitly set output_format: "mp4". Use mov if needed, and specify the desired format again when generating the final video.
Step 4: Query the final video
Use the new ID returned in Step 3:
export FINAL_TASK_ID='sg_vid_final_example'
curl -sS "$ET_BASE/api/v3/contents/generations/tasks/$FINAL_TASK_ID" \
-H "Authorization: Bearer $ET_TOKEN"Wait for status=succeeded, then retrieve the final video from this response's content.video_url. The draft ID queries the draft; the final ID queries the final video.
Billing
The draft and final video are two generation tasks, billed independently using each task's billable token usage. Creating only a draft incurs only the draft charge. Creating the final video incurs an additional charge.
| Original draft input | Draft pricing | Final video pricing |
|---|---|---|
| No reference video | No-video-input category, 480p output rate | No-video-input category, 1080p output rate |
| Includes reference video | Video-input category, 480p output rate | Video-input category, 1080p output rate |
The final video inherits the draft's original input billing category. The draft video itself does not add input-video duration. Each task uses the account, model, and channel prices applicable when that task is submitted, together with its actual billable usage.
Querying the same task again does not incur another generation charge. Repeating a create request creates a new task; save the returned ID and use the query endpoint to track it.
Common errors
Errors use {"error":{"type":"...","message":"..."}}.
| HTTP status | error.type | Action |
|---|---|---|
400 | invalid_request | Check resolution, forbidden parameters, draft success, exact model name, and the 7-day validity period |
404 | task_not_found | Check the platform task ID and use the API key that created the draft |
409 | draft_channel_changed | The original channel account, project, endpoint, or model mapping changed, or its identity cannot be verified; create a new draft |
429 | rate_limited | User or channel rate limit reached; retry later |
503 | no_channel / async_task_unavailable | Original channel or task service unavailable; retry later or contact support |
