Skip to main content
Draft mode lets you preview a Seedance 2.5 video at 480p, then finalize the exact same shot at 1080p or 4k with one more request. The final reuses the draft’s prompt, media, and settings, so what you approved is what you get. It is a good way to save money while you are iterating on your motion, dialogue, and shot details before committing to a full-resolution generation. The flow has two calls:
  1. Draft. Send your normal request with draft: true. You get a 480p video and a draft_task_id.
  2. Final. Send the draft_task_id back with the same model. You get the 1080p video, or the 4k video if you also send "resolution": "4k". No prompt needed.
Supported models: every Seedance 2.5 model. The examples on this page use text-to-video. For image-to-video or reference-to-video, swap in that model ID and add its image, video, or audio inputs to the draft request as you normally would. The final still sends only model and draft_task_id (plus resolution for 4k); the media is reused from the draft. 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 and pick 1080p or 4k.
We recommend the async queue workflow. Seedance generations may take a long time, and your HTTP connection may time out in sync mode.
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 a generation_id right away; poll (or listen for the completion event) until the generation finishes.

1. Enqueue a draft

Add draft: true to a normal request. Any resolution you send is overridden to 480p.
Response:

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]:
If you consume the media_generation_completed event instead of polling, it carries the same videos list beside its url.

3. Enqueue the final

Response:
The final renders at 1080p. To render it at 4k instead, add "resolution": "4k"; see Render the final in 4k.

4. Poll the final

Poll GET /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

Add draft: true to a normal request. Any resolution you send is overridden to 480p.
The response lists the video with its draft ID and expiry:
Store 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 the draft_task_id back exactly as you received it, with the same model. Leave out prompt, duration, and other settings.
The final is 1080p (or 4k, if you sent "resolution": "4k") at the draft’s duration and audio setting. Its item carries only a url:

Render the final in 4k

A final renders at 1080p unless you ask for 4k. Add "resolution": "4k" to the final request; everything else stays the same. The draft itself is still a 480p preview, so you can check the shot cheaply and only pay for 4k once you like it.
The 4k final (3840×2160 at 16:9) keeps the draft’s aspect ratio, duration, audio setting, and seed, so it is the same shot at four times the pixels of 1080p. Like 1080p, it uses 10-bit color and H.265/HEVC encoding.
  • Only 1080p and 4k are valid for a final. Any other resolution (such as 720p), or none at all, renders the final at 1080p.
  • The same draft can render both. A draft ID stays valid for 7 days, so you can render a 1080p final first and a 4k final later, or the reverse.
  • It costs more. A 4k final is billed as a normal 4k render of the draft’s length. See the model’s page for its per-second price at each resolution.

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: a videos 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 or 4k render, whichever you asked for, 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’s duration 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 draft option to your Seedance 2.5 request builder that sets "draft": true.
  • Read draft_task_id and draft_expires_at from videos[0] on the sync response, the succeeded queue generation, or the media_generation_completed event.
  • Persist both fields next to the draft’s video URL and prompt.
  • Add a “render final” action that sends only model and draft_task_id, plus "resolution": "4k" when the user wants 4k.
  • Hide or disable that action once draft_expires_at has 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 empty videos list as not ready.

Reference implementation (Python)

A minimal client covering both paths. It uses only requests. Set MODEL to whichever Seedance 2.5 model you use, and pass that model’s media inputs to the draft through settings.

Prompt for your coding agent