Seedance 2.5 in 16:9, 9:16 and 1:1: one idempotency key per ratio

Fan one prompt out to three aspect ratios on /v1/videos, derive a separate Idempotency-Key for each ratio, and rerun the script without paying twice.

4 min readSume
All posts

To render one Seedance 2.5 prompt in several aspect ratios, send one POST /v1/videos per ratio and build each Idempotency-Key from a base id plus the ratio. A rerun of the same script then returns the original jobs, because a replay with the same key and body returns the first job instead of starting a second one.

Check the ratios against the model's catalog entry first, since each model reports its own supported_aspect_ratios.

Why one key per ratio?

One key means one operation. If you reuse a single key across three different bodies, the second call fails with 409 idempotency_conflict, and if you mint a random key per attempt, a crash-and-rerun bills the clip again. A derived key such as launch-42-9x16 fixes both.

Idempotency-Key behaviour on submit (Sume docs, read 2026-10-09)
SituationResult
Same key, same bodyThe original job comes back
Same key, different body409 idempotency_conflict
New key, same bodyA new paid job
No keyNot replay-safe

What does the script look like?

The call uses the default async path, so the script only prints the polling URLs.

import os, requests

BASE = "https://api.sume.com/v1"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
want = ["16:9", "9:16", "1:1"]

models = requests.get(f"{BASE}/videos/models", headers=H, timeout=30).json()["data"]
m = next(x for x in models if x["id"] == "seedance-2.5")
ratios = [x for x in want if x in m["supported_aspect_ratios"]]

for ratio in ratios:
    key = f"{os.environ['CAMPAIGN']}-{ratio.replace(':', 'x')}"
    r = requests.post(f"{BASE}/videos", timeout=30,
        headers={**H, "Idempotency-Key": key},
        json={"model": "seedance-2.5", "duration": 8,
              "resolution": "720p", "aspect_ratio": ratio,
              "prompt": "A ceramic mug on a desk, slow push-in"})
    print(ratio, r.status_code, r.json().get("polling_url"))

How do I confirm the three jobs afterwards?

Print the ratio next to the polling URL, as the script does, and keep that output. Rerun the script: the same URLs coming back for the same ratios proves the replay worked, and a new URL means a new paid job. Map ratio to job by that printed label, not by list position.

What changes the key's meaning?

Any edit to the body, even the prompt text, makes the old key a conflict. Bake a version into the key (for example launch-42-v2-9x16) when you change the prompt on purpose, and keep the old key for the old spend.

Will three jobs run at once?

Only up to your plan's concurrency. The rest wait as queued, which is normal, and a full queue returns 429 queue_full. Check the headroom before a larger fan-out.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume