Seedance 2.5 Edit
ByteDancevideolive~4m 3sEdit a video from a prompt: swap subjects, objects or audio.
avg$2.34/ run
An estimate, trued up after the run. Failed runs cost $0.00.
How this model is billed
Quoted before you run. A failed run costs $0.00.
Typical run ~4m 3s: the measured mean, end to end.
Compare every priceRun Seedance 2.5 Edit
Seedance 2.5 Edit API
Async: the POST answers at once with a request id. Poll it, or take the webhook.
- 01
Submit
Parameters at the top level of the JSON body. Answers 202 with a request id.
curlPOST /v1/models/seedance-2.5-edit curl -X POST https://api.ezflows.io/v1/models/seedance-2.5-edit \ -H "Authorization: Bearer $EZFLOWS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "video": "https://media.ezflows.io/inputs/<account>/<upload-id>.mp4", "prompt": "a wide shot of a desert at dusk", "resolution": "720p" }' # 202 Accepted, at once — it never waits for the model: # {"request_id": "req_8f2a41c9b70e4d15", "status": "queued", # "poll_url": "https://api.ezflows.io/v1/requests/req_8f2a41c9b70e4d15"} - 02
Poll
Same bearer header, every few seconds, until the status is final.
curlGET /v1/requests/:id REQUEST_ID=req_8f2a41c9b70e4d15 # from the POST while :; do BODY=$(curl -s https://api.ezflows.io/v1/requests/$REQUEST_ID \ -H "Authorization: Bearer $EZFLOWS_API_KEY") STATUS=$(echo "$BODY" | jq -r .data.status) case "$STATUS" in succeeded|failed|cancelled) break ;; esac sleep 3 done echo "$BODY" | jq -r '.data.output.artifacts[].url' # media.ezflows.io, kept 90 days - 03
Response
Files are on media.ezflows.io, kept 90 days. A failed run says why and costs nothing.
json200 · succeeded { "data": { "id": "req_8f2a41c9b70e4d15", "model_slug": "seedance-2.5-edit", "status": "succeeded", "http_status": 200, "cost": 2.338065, "auth_method": "api_key", "error": null, "submitted_at": "2026-09-12T18:07:21.114Z", "queue_started_at": "2026-09-12T18:07:21.402Z", "execution_started_at": "2026-09-12T18:07:22.010Z", "first_byte_at": "2026-09-12T18:07:52.871Z", "finished_at": "2026-09-12T18:07:55.203Z", "io_deleted_at": null, "canvas_id": null, "canvas_node_id": null, "client_attempt_id": null, "idempotency_key": null, "input": { "video": "https://media.ezflows.io/inputs/<account>/<upload-id>.mp4", "prompt": "a wide shot of a desert at dusk", "resolution": "720p" }, "output": { "artifacts": [ { "index": 0, "kind": "video", "contentType": "video/mp4", "url": "https://media.ezflows.io/outputs/<account>/req_8f2a41c9b70e4d15/0.mp4" } ] } } } - 04
Webhook
Skip polling: we POST the result to your endpoint, at least once.
- Register
- Create an endpoint under Webhooks in the dashboard; the signing secret is shown once.
- Events
- request.succeeded · request.failed · request.cancelled
- Headers
- ezflows-event-id (dedupe on it) · ezflows-timestamp (unix seconds) · ezflows-signature t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>">
- Verify
- Over the exact bytes received, in constant time; reject anything older than five minutes.
- Respond
- Any 2xx within 10 s. Redirects are not followed.
- Retries
- Five, with backoff: 30 s · 60 s · 2 min · 4 min · 8 min. Disabled after five consecutive dead deliveries.
jsonDelivery body { "id": "82cf46a4-841e-41d6-b3c7-facc937d3252", "type": "request.succeeded", "created_at": "2026-09-12T18:07:55Z", "data": { "id": "req_8f2a41c9b70e4d15", "model_slug": "seedance-2.5-edit", "status": "succeeded", "cost": 2.338065, "output": { "artifacts": [ { "url": "https://media.ezflows.io/…/0.mp4" } ] } } }curlverify.sh # Create the endpoint under Webhooks in the dashboard; the signing secret is shown once. # ezflows-signature: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>"> # body.json = the exact bytes received. Reject anything older than five minutes. EXPECTED=$({ printf '%s.' "$TS"; cat body.json; } \ | openssl dgst -sha256 -hmac "$EZFLOWS_WEBHOOK_SECRET" -r | cut -d' ' -f1) [ "$EXPECTED" = "$V1" ] && echo "valid" || echo "reject"
Parameters 12
| Name | Type | Default | Allowed | Description |
|---|---|---|---|---|
| videorequired | string | — | one video url | The clip to edit (@Video 1): 4-30 seconds, mp4 or mov, 480p-4k, up to 200MB. The output keeps its aspect ratio and length. Real human faces are blocked by the provider's content policy. |
| promptrequired | string | — | — | What to change in @Video 1: add, remove, replace or change something, or edit the audio. Everything you do not mention stays as it is. Cite extra references as '@Image 1', '@Audio 1'. If the prompt names no edit, 'Edit @Video 1:' is prepended. |
| reference_images | string[] | — | up to 30 image urls | Up to 30 reference images (max 30MB each) for character/style consistency. Cite as '@Image 1', '@Image 2' in your prompt. Cannot be used together with first_frame_url. |
| reference_audios | string[] | — | up to 10 audio urls | Up to 10 reference audio files (MP3, 2-30 seconds each, 30 seconds combined, max 15MB each). Cite as '@Audio 1' in your prompt. Audio-only reference is supported on seedance-2.5. |
| resolution | enum | 720p | 480p · 720p · 1080p | Output resolution. seedance-2.5 supports 480p, 720p and 1080p (24fps). Use 480p for drafts and fast iteration, 720p for final renders, 1080p for the highest fidelity (10-bit colour). Higher resolution costs more (token-based). |
| auto_resize | boolean | true | — | Automatically resizes an input image that falls outside the provider's accepted range (300-6000px per side, aspect ratio 0.4-2.5, 30MB) so the request succeeds instead of being rejected. Aspect ratio is preserved: oversized images are downscaled, undersized ones upscaled, and out-of-band ratios padded rather than cropped. On by default - set it to false to have the provider reject out-of-range images instead. When a resize happens the response carries an X-Input-Normalized header naming the field and the before/after dimensions. |
| bitrate_mode | enum | standard | standard · high | Output video encoding bitrate. 'standard' gives smaller files and faster downloads; 'high' produces ~5-6x higher bitrate for better visual fidelity and fewer compression artifacts (larger files). Does not affect price. |
| generate_audio | boolean | true | — | true keeps the clip's soundtrack (a silent clip gets generated sound; an audio edit in the prompt changes it). false delivers the video with no audio track at all, not the original audio. |
| output_codec | enum | auto | auto · h264 | Codec of the delivered file. 'auto' returns the model's own encode untouched - for seedance-2.5 at 1080p that is 10-bit HEVC, the highest-fidelity master, which Chrome and Firefox on Windows cannot decode and will play as audio over a blank frame. 'h264' re-encodes it to H.264 High 8-bit yuv420p, which plays everywhere, at the cost of one additional generation of compression and half the bit depth; pick it for browser embeds and previews, and leave it on 'auto' when the file goes into an edit or grade. Output that is already H.264 (720p, 480p, the 2.0 series) is never re-encoded either way. Adds a few seconds when it applies, and does not affect price. |
| output_format | enum | mp4 | mp4 · mov | mp4 = best compatibility. mov (H.264 + yuv444p + PCM) = higher color fidelity; recommended for video editing/extension round-trips. |
| return_last_frame | boolean | false | — | Returns the final video frame as a separate image, delivered in the response as `video.last_frame_url`. Chain shots by feeding that URL into the next generation's `first_frame_url`. Note this is an output: it is distinct from the `last_frame_url` input parameter, which is an image you supply to steer how the clip ends. |
| seed | integer | -1 | -1–2147483647 | Reproducibility seed. Use -1 for random output, set a fixed value to iterate on the same scene. |
File inputs (video: one video url · reference_images: up to 30 image urls · reference_audios: up to 10 audio urls) take URLs. Upload the raw file to POST /v1/uploads with its own Content-Type and pass the url it returns. Inputs are kept 90 days.
Sign in to see your runs of Seedance 2.5 Edit: status, cost, timings and outputs.
Sign inSign in to see what you spend on Seedance 2.5 Edit, and how often runs succeed.
Sign in