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
- Derive the Idempotency-Key from a SHA-256 of the request in Python
A key built from the path and a canonical body hash makes a retry return the original Sume job and a changed prompt a new one, with no 409 to handle.
- Detach 16 kHz mono audio from a 25-minute video: 2 ranges, 2 cents
A 25-minute video exceeds audio detach's 900-second output cap, so request two 750-second ranges at 16 kHz mono: two jobs at $0.01 each, about 24 MB per wav.
- 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.
- detach_source_has_no_audio: the free probe that prevents it on Sume
Sume audio detach fails with detach_source_has_no_audio on a video with no sound track. A frames-off video inspect reads probe.has_audio first. Codes inside.
Written by Sume