Clip-type route table in Python: Sora use cases to Sume models
A 30-line Python route table maps ads, demos and teasers to a Sume model, size and length, refuses a length the model cannot make, and prints the dollar cost.

Keep a small route table in code that maps each clip type to a Sume model, resolution, aspect ratio and length, and a limits table that refuses a length the model cannot make. The script below prices 600 ads, 250 demos and 150 teasers and prints $600.00, $420.00 and $94.50. It stops with an error if you route a 12-second demo to a model that stops at 10 seconds.
After OpenAI removed the Videos API and the sora-2 family on 2026-09-24, with no replacement listed, a library tends to need several models, not one. A table in code makes that choice reviewable.
The table and the checker
The limits are from the Sume catalog: wan-3.0 takes 2 to 30 seconds, gemini-omni-flash-1.1 takes 3 to 10 and kling-3 takes 4 to 15. The cents are billable prices for each model, resolution and length in the same catalog. Only four combinations are listed here; add the ones your library uses.
LIMITS = {"wan-3.0": (2, 30), "gemini-omni-flash-1.1": (3, 10), "kling-3": (4, 15)}
CENTS = {
("wan-3.0", "720p", 8): 100,
("wan-3.0", "1080p", 12): 300,
("gemini-omni-flash-1.1", "720p", 5): 63,
("kling-3", "1080p", 12): 168,
}
ROUTES = {
"ad": ("wan-3.0", "720p", "9:16", 8),
"demo": ("kling-3", "1080p", "16:9", 12),
"teaser": ("gemini-omni-flash-1.1", "720p", "9:16", 5),
}
def plan(kind, count):
model, res, aspect, secs = ROUTES[kind]
lo, hi = LIMITS[model]
if not lo <= secs <= hi:
raise ValueError(f"{model} takes {lo}-{hi} s, not {secs}")
cents = CENTS[(model, res, secs)] * count
return {"model": model, "resolution": res, "aspect_ratio": aspect,
"duration": secs, "dollars": cents / 100}
for kind, n in (("ad", 600), ("demo", 250), ("teaser", 150)):
print(kind, plan(kind, n))
try:
ROUTES["demo"] = ("gemini-omni-flash-1.1", "1080p", "16:9", 12)
plan("demo", 1)
except ValueError as err:
print("refused:", err)
What the script prints
The first loop prints one dict per clip type. Ads: 600 clips x 100 cents on wan-3.0 at 720p and 8 seconds, so 60,000 cents or 600.0 dollars. Demos: 250 x 168 cents on kling-3 at 1080p and 12 seconds, silent, so 420.0 dollars. Teasers: 150 x 63 cents on gemini-omni-flash-1.1 at 720p and 5 seconds, so 94.5 dollars. The three lines total $1,114.50.
The last lines reroute the demo to Omni at 12 seconds and call the planner, which raises ValueError and prints refused: gemini-omni-flash-1.1 takes 3-10 s, not 12. That is the guard doing its job; a missing price would raise a KeyError in the same way, which is also what you want for an unlisted combination.
Why validate before you submit
A length outside the range of a model is a rejected request, not a clamp. Catching it in your own table means a bad route fails when you edit it, not after you queued 250 jobs and read 250 errors. The same check is the right place to refuse a resolution the model does not have, such as 720p on minimax-h3.
The cost function is also a budget check. Compare the dollars it prints with the balance before you start a run; Sume reserves the cost of each job at submit and fails the submit with 402 insufficient_credits if the balance cannot cover it.
Checking the table against the live catalog
Do not trust a copy of the numbers for long. GET /v1/videos/models returns the supported resolutions, aspect ratios, durations and pricing fields for each model, and the list prices can change. A test that loads the catalog and asserts that every route in the table is valid is a cheap guard to run in CI.
Keep the route table in version control, with the reason for each row in a comment. When a model is retired or its price changes, the diff shows which clip types are affected, which is what OpenAI's removal of the sora-2 models taught many teams to want.
- One row per clip type, not per prompt.
- Include the idempotency key scheme alongside the route.
- Fail the build when a route points at a model id missing from the catalog.
Sources
Related posts
More in Developers
- Video trim end past the clip: trim_clamped_to_source and a short ad
If end is beyond the source, Sume video-trim clamps it and warns trim_clamped_to_source. Ask for 0-20 s of a 15 s clip and you get 15 s, which can break a spot.
- Video upscale hold: omit duration_seconds and Sume reserves 5 s
Sume video upscale reserves from duration_seconds, or 5 seconds when you omit it. Hold table for 5, 15 and 30 seconds at $0.009 per second and the 402 case.
- Vidu Q4 or LTX on Sume? Check the video model list first
Sume does not list Vidu or LTX in its video catalog as of 2026-10-08. Query GET /v1/videos/models and filter by id; a short script and the 12 ids it returns.
- Vidu Q4 Preview result URLs last 24 hours: save the file the same day
Vidu says Q4 Preview output URLs stay valid for 24 hours. Copy the file the day you render it, and see what Sume documents about its job result URL.
Written by Sume