Video model aliases from config that fail at boot, not at submit
Map your own names like hero-clip to Sume model ids in config, then check each against GET /v1/video-router/models at startup so a retired id stops the deploy.

Keep a small config file that maps your product's names to Sume model ids and per-alias defaults, and at process start fetch GET /v1/video-router/models and verify every alias. An id missing from the catalog, or a duration outside capabilities.duration_seconds, raises before you accept traffic. That is cheaper than a failed submit, and your callers keep one job shape whatever the model underneath.
What the catalog provides
The catalog returns data.models[]. Each item has an id, a capabilities object with resolutions, aspect_ratios and duration_seconds {min, max}, plus pricing and constraints. The id enum in the schema lists these twelve models.
| Field | Use |
|---|---|
id | Must equal the alias target |
capabilities.duration_seconds.min / .max | Check your default duration |
capabilities.resolutions | Check your default resolution |
capabilities.aspect_ratios | Check your default aspect ratio |
gated | When true the model is omitted from public listings until GA |
Boot check
The aliases below use seedance-2.5, which the Video Router docs describe as 4 to 30 seconds at 480p, 720p and 1080p. The check runs on every boot, so a catalog change shows up in the next deploy.
import asyncio, json, os, sys, urllib.request
ALIASES = {
"hero-clip": {"model": "seedance-2.5", "duration": 8, "resolution": "720p", "aspect_ratio": "9:16"},
}
def catalog():
req = urllib.request.Request("https://api.sume.com/v1/video-router/models",
headers={"x-api-key": os.environ["SUME_API_KEY"]})
with urllib.request.urlopen(req, timeout=30) as r:
return {m["id"]: m for m in json.load(r)["data"]["models"]}
def problems(models):
out = []
for name, a in ALIASES.items():
m = models.get(a["model"])
if not m:
out.append(f"{name}: model {a['model']} not in catalog"); continue
cap = m["capabilities"]
d = cap["duration_seconds"]
if not d["min"] <= a["duration"] <= d["max"]:
out.append(f"{name}: duration {a['duration']} outside {d['min']}-{d['max']}")
if a["resolution"] not in cap["resolutions"]:
out.append(f"{name}: resolution {a['resolution']} not in {cap['resolutions']}")
if a["aspect_ratio"] not in cap["aspect_ratios"]:
out.append(f"{name}: aspect {a['aspect_ratio']} not in {cap['aspect_ratios']}")
return out
async def main():
bad = problems(await asyncio.to_thread(catalog))
if bad:
sys.exit("model config invalid:\n" + "\n".join(bad))
print("model aliases ok")
asyncio.run(main())What happens on a retirement
Fail the deploy on a problem, not just log it. A dropped model should be a config change you make on purpose: edit the alias to a different id and redeploy. Only the alias map changes, so the code that submits and polls stays the same.
Also note
POST /v1/video-1.0/generate is documented as retiring soon and remains an alias for the Video Router Auto pipe. New code should use /v1/video-router/generate with a catalog model, as above.
Sources
Related posts
More in Developers
- Container snapshot restore: resume a Sume job from its job_id
Cloudflare Containers can snapshot a running container. Save the Sume job_id in it, and after a restore read the job's status_url instead of resubmitting.
- Copilot CLI dynamic workflows: let them call the Sume CLI
GitHub added dynamic workflows to Copilot CLI on Oct 1, 2026. Give it the Sume CLI skill pack and the hosted MCP endpoint, and keep paid calls behind a gate.
- createSumeClient timeout is 10 minutes per request: tune it for polls
The Sume SDK client waits up to 10 minutes on each HTTP request, so one hung status poll can stall waitForJob for 10 minutes. Use a short-timeout client.
- CrewAI conversational flows: confirm cost before a Sume render
In a CrewAI chat flow, have the step call Sume with dry_run first and ask the user to confirm the cost.
Written by Sume