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.

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
| Problem | Caught by preflight | Where else it shows |
|---|---|---|
| Unknown model id | Yes | 404 model_not_found at submit |
| Duration out of range | Yes | Rejected at submit |
| 720p on minimax-h3 | Yes, if 768p is the listed value | Rejected at submit |
| size, seed, provider.options | No, not in this check | 400 unsupported_parameter |
| Insufficient balance | No | Reserve 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
- Pre-flight tool access: tools_list on Sume's MCP
Notion added a tool that reveals connection-scoped capabilities before requests. Sume's MCP does the same job with tools_list, tools_schema and mcp_health.
- Prism mock server from Sume's openapi.json: test without spending
Download api.sume.com/reference/json, run prism mock -d on port 4010 and point your client at it. What a mock proves and what it cannot.
- Prisma upsert on a unique job_id for Sume webhook retries
Dedupe Sume job webhooks with a Prisma model keyed on job_id and an upsert that updates nothing, after verifyWebhook. TypeScript route handler for Next.js.
- Programmatic tool calling 270 s timeout vs Sume's 55 s script_run cap
Claude times out a pending programmatic tool call after about 4 minutes. Sume's script_run stops at 55 seconds. How to size slow video jobs around both.
Written by Sume