Check a video request against /v1/videos/models before you submit

Duration, resolution, size and seed errors cost a round trip. A short Python validator reads the model catalog and refuses a bad request locally first.

4 min readSume
All posts

Every limit that can reject a Sume video request is published in GET /v1/videos/models: durations, resolutions, aspect ratios, input references and whether seed is accepted. A 20-line validator can read that list and refuse a bad request locally, with a message that names the allowed values. The Sume docs state that size returns 400 unsupported_parameter on every v1 model and that no v1 model accepts seed, so those two checks are worth having even before you read the catalog.

Everything here is from Sume's Video Generation docs, read 2026-10-01.

The validator

It fetches the model list once and checks the request fields against the entry for the chosen model. It returns a list of problems; empty means send it.

import os, requests

def load():
    r = requests.get("https://api.sume.com/v1/videos/models",
        headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}, timeout=30)
    r.raise_for_status()
    return {m["id"]: m for m in r.json()["data"]}

def problems(req, catalog):
    m = catalog.get(req["model"])
    if m is None:
        return [f"unknown model {req['model']}"]
    out = []
    if "size" in req:
        out.append("size is not accepted; use resolution + aspect_ratio")
    if "seed" in req and not m["seed"]:
        out.append("this model rejects seed")
    for key, field in (("duration", "supported_durations"),
                       ("resolution", "supported_resolutions"),
                       ("aspect_ratio", "supported_aspect_ratios")):
        if key in req and req[key] not in m[field]:
            out.append(f"{key}={req[key]} not in {m[field]}")
    return out

cat = load()
print(problems({"model": "gemini-omni-flash-1.1", "duration": 12}, cat))

What does it catch?

The last line asks for 12 seconds from gemini-omni-flash-1.1, whose documented range is 3 to 10, so it prints the allowed list instead of spending a round trip. The same check catches 1080p on a model that tops out at 768p.

From the Sume docs, read 2026-10-01.
Field in the requestCatalog fieldRule
durationsupported_durationsWhole seconds from the list
resolutionsupported_resolutionsFor example 480p, 720p, 768p, 1080p
aspect_ratiosupported_aspect_ratiosFrom the list
sizesupported_sizesnull on every v1 model; request is refused
seedseedfalse on every v1 model; field is rejected

Where should the check live?

Put it at the one place your code builds a request, not in each caller. If an agent or a queue worker submits video jobs, a failed local check should return the message to whoever built the request, so they can fix the field instead of retrying the same body. A rejected request that never leaves your process costs nothing and leaves no job to cancel.

Two refinements are worth adding. First, when the model is sume/auto, there is no catalog entry to check against, so skip the per-model rules and keep only the size and seed checks. Second, treat a catalog fetch failure as a reason to fall back to the server's own validation rather than blocking every submit.

Pair the validator with an Idempotency-Key on the real call. The key makes a retry safe if the network drops after the server accepted the job; the validator prevents the retry from being needed for a predictable reason.

Limits

A local check cannot replace the server's. Input-shape rules, such as the Omni routing by input shape or the H3 Max Recast rule that no shot may exceed 15 seconds, are not fully described by the catalog fields, so keep handling a 400 from the real call. Cache the catalog for minutes, not days, because models are added and retired.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume