Seedance 2.5 API in Python: a 30-second clip with an audio reference
Submit a 30-second Seedance 2.5 job on Sume with requests: an image and an audio reference in input_references, polling, download, and limits to check.

To call Seedance 2.5 by API on Sume, POST model: "seedance-2.5" to /v1/videos with duration up to 30, put reference files in input_references, and poll the job. This post pairs one image with one audio file so the clip follows your music.
Seedance 2.5 on Sume runs 4 to 30 seconds at 480p, 720p and 1080p, and the catalog row accepts image, video and audio references.
The script
Save as seedance.py. It needs pip install requests and SUME_API_KEY in the environment. The loop sleeps ten seconds between polls; a 30-second job can take a while, so a webhook is better in production.
import os, time, requests
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
BASE = "https://api.sume.com/v1/videos"
body = {
"model": "seedance-2.5",
"prompt": "A drummer plays in a sunlit loft, the camera circles slowly",
"duration": 30,
"resolution": "720p",
"aspect_ratio": "16:9",
"input_references": [
{"type": "image_url", "image_url": {"url": "https://example.com/drummer.png"}},
{"type": "audio_url", "audio_url": {"url": "https://example.com/groove.mp3"}},
],
}
job = requests.post(BASE, headers=H, json=body, timeout=60).json()
while True:
s = requests.get(job["polling_url"], headers=H, timeout=60).json()
if s["status"] in ("completed", "failed", "cancelled"):
break
time.sleep(10)
if s["status"] != "completed":
raise SystemExit(s.get("error") or s["status"])
open("seedance.mp4", "wb").write(requests.get(s["unsigned_urls"][0], headers=H, timeout=300).content)
print("cost", s["usage"]["cost"])What the vendor and the catalog say
ByteDance Seed describes Seedance 2.5 as an audio-video joint generation model that creates videos up to 30 seconds in a single generation, with an option to extend twice (read 2026-10-07). Sume does not expose the extension step, so a Sume job is one generation of 4 to 30 seconds.
| Field | Value |
|---|---|
| Duration | 4 to 30 seconds |
| Resolutions | 480p, 720p, 1080p |
| References | Image, video and audio URLs through input_references |
| Billing basis | Per 1,000 video tokens; read pricing_skus from GET /v1/videos/models |
| bitrate_mode | Not accepted on this row |
Reference rules and cost
Reference videos on Seedance models are billed with a priced allowance: the pricing code assumes 15 seconds of reference video at 60 percent of the clip rate, so budget for it when you add one. The audio reference in this example is not a video, but check GET /v1/videos/models for the accepted types before you rely on a combination.
Because pricing is by token, the safest way to know the cost of a 30-second job is the usage.cost on a finished run, plus the reserve that Sume holds at submit. If the reserve exceeds your balance, the submit returns 402 insufficient_credits.
- Send
Idempotency-Keyso a retried submit returns the same job. - No
seed: a rerun is a new take. - Use
seedance-2-miniorseedance-2-fastfor 4 to 15 second drafts.
Sources
Related posts
More in Developers
- Seedance 2.5 estimate vs usage.cost: reconcile a job in Node
Compute the Seedance 2.5 price from width, height and seconds, submit one job to Sume, and compare it with usage.cost on the poll. A runnable Node 18 script.
- Semantic Kernel .NET defaults to gpt-image-1: it fails Oct 23
The .NET OpenAI connector in Semantic Kernel defaults to gpt-image-1, which OpenAI removes Oct 23, 2026. What breaks, and a C# call to Sume that does not.
- SHA-256 the batch body into the Sume idempotency key for bulk chunks
Derive each bulk chunk's Idempotency-Key from a hash of its items so replays reuse the queue and edited rows get a new key instead of a 409 conflict.
- Turn a shot list into Gemini Omni requests: Python on Sume
Submit every line of a shot list as its own Omni job with stable Idempotency-Keys, then poll them in one pass. Runnable Python and the cost of a 3-shot list.
Written by Sume