Preflight a Sume video request against the catalog in Python

Check model id, duration and resolution against GET /v1/videos/models before submitting, so an unsupported value fails in your code and not at the API.

4 min readSume
All posts

Short answer

Fetch GET /v1/videos/models once, then check three fields on your chosen model before every submit: that the id exists, that your duration is in supported_durations, and that your resolution is in supported_resolutions. Limits differ per model, and the video docs say to use that endpoint before submitting. A local check turns a 400 or a 404 into a clear message in your own logs.

Why this matters in launch weeks

New models arrive with their own limits. wan-3.0 accepts 2 to 30 seconds, seedance-2.5 accepts 4 to 30, minimax-h3 accepts 5 to 15 at 480p or 768p, and gemini-omni-flash-1.1 accepts 3 to 10. A request that is valid for one is invalid for another, and minimax-h3 rejects 720p because its native size is 768p. If you swap a model id in config and forget the matching duration, a preflight catches it before the call.

The preflight

It returns a list of problems and an empty list when the request is fine. The catalog fetch runs in a thread so the function fits an asyncio program.

import asyncio, json, os, urllib.request

def catalog():
    req = urllib.request.Request(
        "https://api.sume.com/v1/videos/models",
        headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"]},
    )
    with urllib.request.urlopen(req) as r:
        return {m["id"]: m for m in json.load(r)["data"]}

def problems(models, model, duration, resolution):
    m = models.get(model)
    if m is None:
        return ["unknown model " + model]
    out = []
    if duration not in m["supported_durations"]:
        out.append(f"duration {duration} not in {m['supported_durations']}")
    if resolution not in m["supported_resolutions"]:
        out.append(f"resolution {resolution} not in {m['supported_resolutions']}")
    return out

async def main():
    models = await asyncio.to_thread(catalog)
    print(problems(models, "minimax-h3", 15, "720p"))

asyncio.run(main())

What it will and will not catch

Preflight coverage against Sume video docs (read 2026-10-04)
ProblemCaught by preflightWhere else it shows
Unknown model idYes404 model_not_found at submit
Duration out of rangeYesRejected at submit
720p on minimax-h3Yes, if 768p is the listed valueRejected at submit
size, seed, provider.optionsNo, not in this check400 unsupported_parameter
Insufficient balanceNoReserve is taken at submit

Extending it

Add supported_aspect_ratios and supported_frame_images checks the same way. For size, seed and a non-empty provider.options, simply do not send them; Sume rejects all three with 400 unsupported_parameter. Cache the catalog for a few minutes rather than fetching on every request, and refresh it when a submit returns 404.

Wiring it in

Call problems right before the submit and raise if the list is not empty, with the list in the message. In tests, assert that every model id in your config passes for the durations and resolutions you actually use. In a batch, run the check once per distinct combination rather than per clip. When the check fails after a catalog change, you learn that day, not when a batch of 200 clips returns errors.

Caveats

The catalog reflects your key's view of the system, and higgsfield-genjutsu appears only when its provider is configured. A passing preflight does not guarantee a quote you can afford; the reserve is taken at submit.

Related posts

More in Developers

All Developers posts

Written by Sume