- Draft. Send your normal request with
draft: true. You get a 480p video and adraft_task_id. - Final. Send the
draft_task_idback with the samemodel. You get the 1080p video. No prompt needed.
Supported model:
bytedance-seedance-2-5-text-to-video
Base URL: https://hub.oxen.ai/api. Authenticate every request with Authorization: Bearer $OXEN_API_KEY.
Draft mode works on both the queue (POST /ai/queue) and the sync endpoint (POST /ai/videos/generate). It is also available in the Oxen.ai UI: render a draft, then click to render the final.
We recommend the async queue workflow. Seedance generations may take a long time, and your HTTP connection may time out in sync mode.
Seedance 2.5 - Text to Video API reference
Full parameter table, request builder, and sample code for the underlying model.
Quickstart (async queue, recommended)
We recommend the async queue for draft mode. Seedance generations can take several minutes, and in sync mode your HTTP connection may time out before the video is ready. Enqueue returns ageneration_id right away; poll (or listen for the completion event) until the generation finishes.
1. Enqueue a draft
Adddraft: true to a normal request. Any resolution you send is overridden to 480p.
2. Poll the draft
status moves from queued to processing and videos stays empty until the generation has a result. Once status is succeeded, read the draft ID from videos[0]:
media_generation_completed event instead of polling, it carries the same videos list beside its url.
3. Enqueue the final
4. Poll the final
PollGET /ai/queue/{generation_id} as before. The succeeded final lists its video with only a url. Its top-level draft_task_id names the draft it came from, so you can link the two in your own records.
Sync flow
The sync endpoint holds the connection open and returns the finished video. It is fine for quick experiments, but for anything else prefer the async queue above, since a long Seedance render can outlast your HTTP connection.1. Render a draft
Adddraft: true to a normal request. Any resolution you send is overridden to 480p.
videos[0].draft_task_id and videos[0].draft_expires_at with the draft. You need the ID to render the final.
2. Render the final
Send thedraft_task_id back exactly as you received it, with the same model. Leave out prompt, duration, and other settings.
url:
Reference
Request parameters
Both endpoints accept these fields in the JSON body.
Settings like aspect ratio, audio, and seed are set on the draft and locked for the final. The final ignores them if resent, along with any
prompt. The queue generation record still echoes whatever you sent, so do not read the final’s settings back from it. Read them from the draft.
Response fields
Every endpoint lists media the same way: avideos array of items with a stored url, plus any fields you can act on.
Endpoints
Rules, billing, and errors
Rules
- Drafts expire after 7 days. Render the final before
draft_expires_at. After that, render a new draft. - One draft, many finals. A draft ID stays valid until it expires, so you can re-render the final if you need to.
- The final is locked to the draft. To change the prompt, media, duration, aspect ratio, audio, or seed, render a new draft.
- Use the same model. Send the final to the model that produced the draft.
Billing
Drafts and finals are each billed as a normal video at their resolution. A draft costs the same as any 480p render. A final costs the same as any 1080p render, using the duration and audio of the finished video. The cost estimate for a final shows a range from silent to with-audio, since the final inherits the draft’s audio setting. Pass the draft’sduration on the final request to tighten the estimate. It does not change the render.
Every render, sync or queued, appears on your requests page and in your usage totals.
Errors
The sync endpoint returns an HTTP 400 with the error in the body. The queue accepts the request and reports the same error on the generation once it runs:status is failed, videos is empty, and error_message explains why.
Sync error body for an unknown draft ID:
Integration guide
This section is written so a coding agent can implement draft mode from it directly. Point Claude Code or a similar tool at this page and ask it to add draft mode to your Seedance 2.5 integration.Checklist
- Add a
draftoption to your Seedance 2.5 request builder that sets"draft": true. - Read
draft_task_idanddraft_expires_atfromvideos[0]on the sync response, the succeeded queue generation, or themedia_generation_completedevent. - Persist both fields next to the draft’s video URL and prompt.
- Add a “render final” action that sends only
modelanddraft_task_id. - Hide or disable that action once
draft_expires_athas passed. - Lock prompt and settings in your UI for finals. Editing them means a new draft.
- Link each final to its draft using the final generation’s top-level
draft_task_id. - Read media from
videos[]. Treat an emptyvideoslist as not ready.
Reference implementation (Python)
A minimal client covering both paths. It uses onlyrequests.