Move an OpenRouter-style video client to Sume: the 400s to expect
Sume /v1/videos matches the OpenRouter video shape, but size, provider.options and seed return 400. The differences table and a Python asyncio polling client.

A client written for the OpenRouter video generation API works against Sume after you change the base URL and the key, with a few exceptions that fail with a 400. Sume's size returns unsupported_parameter because every v1 model reports supported_sizes: null. A non-empty provider.options returns 400 unsupported_parameter. No v1 model accepts seed. Model ids are bare, such as seedance-2, not org/slug.
This is Sume's own statement on its Video generation page, read 2026-10-09. This post makes no claim about the other side beyond what that page says.
The differences that break a migration
The page lists the differences in one table. These are the rows that change your requests or your handling.
| Area | On Sume |
|---|---|
| Base path | https://api.sume.com/v1/videos, no /api segment |
| Auth | Authorization: Bearer $SUME_API_KEY |
| Model ids | Bare catalog ids; sume/auto lets Sume pick the family |
size | 400 unsupported_parameter; use resolution plus aspect_ratio |
provider.options | Non-empty returns 400 unsupported_parameter |
seed | No v1 model accepts it; the field is rejected |
| Webhooks | Sume's job envelope and x-sume-webhook-signature; send callback_url, HTTPS only |
| Idempotency | Send Idempotency-Key; a replay returns the original job |
| Job lifecycle | The same job is also at /v1/jobs/{id}/status and /result |
A client that runs
The snippet submits, then polls the polling_url from the submit response. It sends a fresh Idempotency-Key once per logical request, outside any retry loop, so a retried submit cannot create a second job. The poll gap is 30 seconds, as the page suggests.
import asyncio
import os
import uuid
import httpx
async def main():
headers = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
body = {"model": "seedance-2", "prompt": "A kettle steaming on a stove, 9:16",
"aspect_ratio": "9:16", "resolution": "720p", "duration": 4}
key = {"Idempotency-Key": str(uuid.uuid4())}
async with httpx.AsyncClient(headers=headers, timeout=60) as c:
sub = await c.post("https://api.sume.com/v1/videos", json=body, headers=key)
sub.raise_for_status()
url = sub.json()["polling_url"]
while True:
job = (await c.get(url)).json()
if job["status"] in ("completed", "failed", "cancelled"):
break
await asyncio.sleep(30)
print(job["status"], job.get("unsigned_urls"), job.get("error"))
asyncio.run(main())Check the model before you submit
Limits differ per model, so ask first. GET /v1/videos/models returns supported_resolutions, supported_aspect_ratios, supported_durations, and whether a model accepts frame images and reference types. For example, the page says seedance-2.5 accepts 4 to 30 seconds and minimax-h3 accepts 5 to 15 seconds at 480p or 768p.
Two last details. The status spelling is cancelled on this surface, not canceled. And usage.cost on a poll is the Sume billable amount: at submit, Sume reserves the provider list price times 1.25. If you have a billing check that compares against another price table, expect a difference.
Run a small contract test before you cut over. Send one request with size, one with a non-empty provider.options, and one with seed, and assert that each comes back as a 400 in your own error handling. Then send one valid request twice with the same Idempotency-Key and confirm that you get one job id, not two. These four checks cover most of the difference table.
If you want the Sume envelope instead of the OpenRouter shape, the older /v1/video-router/generate still works with the same model ids, but the page recommends /v1/videos for new integrations.
Sources
Related posts
More in Developers
- MiniMax H3 disk space: 108 GB for SGLang, 19.5 GiB for INT8
How much disk does MiniMax H3 need? 108 GB for the SGLang route, 61.73 GiB BF16 safetensors, 19.53 GiB INT8. Why the numbers differ and what to budget.
- MiniMax H3 on SGLang: the FSDP corruption warning and what to use
MiniMax's H3 guide warns that FSDP inference has reported data corruption; use TP plus Ulysses. The serve flags, the cross-node rule, one service per variant.
- Music job timed out? Retry with the same key: one $0.125, not two
A Sume music submit that times out can be retried with the same Idempotency-Key and returns the original job. Without a key, a blind retry is a second $0.125.
- Music router 400 negative_prompt_unsupported: the fix and its cost
A non-empty negative_prompt on Sume's music router returns 400 negative_prompt_unsupported. Move the exclusions into prompt; a rejected call is not billed.
Written by Sume