Deploy check: does your video model id and duration exist on Sume?
A Python preflight that reads GET /v1/videos/models and fails the deploy when VIDEO_MODEL is not a catalog id or the duration is outside supported_durations.

The cheapest guard against a leftover sora-2 in your config is a preflight that reads GET /v1/videos/models and compares your VIDEO_MODEL and VIDEO_DURATION against the catalog before the deploy goes out. A model id that is not in the catalog, and is not sume/auto, comes back as 404 model_not_found at submit time, and a duration outside the model's supported_durations is rejected by Sume's catalog-driven checks.
OpenAI's deprecations page, read 2026-10-08, lists sora-2, sora-2-pro and their dated snapshots as removed on September 24, 2026, so the old values should never pass this check.
What the catalog row tells you
Each row of the response is a VideoModel. The fields below are the ones a preflight can use; the rest describe pricing and passthrough parameters.
| Field | Use in the preflight |
|---|---|
| id | must equal your VIDEO_MODEL |
| supported_durations | must contain your duration, as an integer |
| supported_resolutions | must contain your resolution value |
| supported_aspect_ratios | must contain your aspect ratio |
| supported_frame_images | needs first_frame if you pin a first frame |
| pricing_skus | Sume billable rates, provider list x 1.25 |
The preflight
Run it in CI or as a pre-start step with SUME_API_KEY set. It exits non-zero with the catalog ids so the fix is obvious. sume/auto is accepted without a lookup, since Sume picks the model.
import json, os, urllib.request
def main():
req = urllib.request.Request(
"https://api.sume.com/v1/videos/models",
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"]})
models = {m["id"]: m for m in json.load(urllib.request.urlopen(req))["data"]}
wanted = os.environ.get("VIDEO_MODEL", "sume/auto")
seconds = int(os.environ.get("VIDEO_DURATION", "8"))
if wanted == "sume/auto":
print("sume/auto: Sume picks the model")
return
model = models.get(wanted)
if model is None:
raise SystemExit(wanted + " is not in the catalog: " + ", ".join(sorted(models)))
if seconds not in model["supported_durations"]:
raise SystemExit("duration %d not supported; use one of %s"
% (seconds, model["supported_durations"]))
print("ok", wanted, seconds)
main()Limits of the check
The catalog can change between your deploy and a later request, and one id, higgsfield-genjutsu, appears only when its provider is configured, so do not hard-code the id list. Treat a failed preflight as a stop, and a passed one as a hint, not a guarantee; keep the 404 and 400 branches in your request code too.
The post on choosing a model by clip length covers the choice itself, and the retired id list covers finding the old values.
Sources
Related posts
More in Developers
- detach_source_has_no_audio: check probe.has_audio first
Audio detach fails with detach_source_has_no_audio on silent video. Probe has_audio with a free frames-false video inspect first. Refusal codes listed.
- Docs page to explainer video: chunk the script under the TTS cap
Split a long document into voice-over chunks under Sume's 20,000-character TTS request limit and price them at $0.0475 per 1,000 characters. Runnable Python.
- Does Seedance audio cost extra on Sume? generate_audio and the price
Seedance prices on Sume are per video token and carry no separate audio line. What generate_audio does, what it defaults to, and the 10 s price either way.
- Draft on Grok Imagine, finish on Seedance 2.5: two calls, one prompt
A Python flow that renders a prompt on grok-imagine-video-1.5 for $0.125, then re-sends the approved text to seedance-2.5 at 1080p for $14.22.
Written by Sume