Check duration, resolution, ratio against /v1/videos/models in Node

A Sora-era request will not fit every Sume model. A Node script reads GET /v1/videos/models and lists what the model rejects before you pay for a job.

5 min readSume
All posts

Sume's GET /v1/videos/models returns, for each model, supported_durations, supported_resolutions, supported_aspect_ratios, supported_frame_images and supported_input_references, so a request can be checked against the model before it is submitted. The Node script below does that for one model and prints every mismatch. Run it in CI or in a pre-submit hook on a ported Sora client.

The docs are direct that limits are different for each model: gemini-omni-flash-1.1 takes 3 to 10 seconds, seedance-2.5 takes 4 to 30, wan-3.0 takes 2 to 30. A duration that worked on one backend can fail on the next, and the catalog is the place to find out which.

The script

It needs Node 18 or later for fetch, and reads the key from the environment. It treats an empty list as no constraint so models without a duration or ratio (such as edit-only ones) do not report false failures.

const MODELS_URL = "https://api.sume.com/v1/videos/models";

async function main() {
  const key = process.env.SUME_API_KEY;
  if (!key) throw new Error("SUME_API_KEY is not set");
  const res = await fetch(MODELS_URL, { headers: { Authorization: `Bearer ${key}` } });
  if (!res.ok) throw new Error(`models request failed: ${res.status}`);
  const { data } = await res.json();
  const req = { model: "gemini-omni-flash-1.1", duration: 12,
                resolution: "720p", aspect_ratio: "9:16" };
  const m = data.find((x) => x.id === req.model);
  if (!m) throw new Error(`unknown model ${req.model}`);
  const problems = [];
  const check = (field, list, value) => {
    if (list && list.length && !list.includes(value)) {
      problems.push(`${field} ${value} not in [${list.join(", ")}]`);
    }
  };
  check("duration", m.supported_durations, req.duration);
  check("resolution", m.supported_resolutions, req.resolution);
  check("aspect_ratio", m.supported_aspect_ratios, req.aspect_ratio);
  console.log(problems.length ? problems.join("\n") : "request fits the catalog");
}

main().catch((e) => { console.error(e.message); process.exit(1); });

What the example does

With duration: 12 against gemini-omni-flash-1.1, the script reports that 12 is outside the 3 to 10 second list, and nothing is submitted. Change the model to seedance-2.5 and 12 passes. The point is not the specific verdict, which comes from live data, but that the check costs one free GET.

Fields to know when you port

Sora-style request fields and where Sume checks them (read 2026-10-07)
Old-style ideaSume fieldChecked against
Length in secondsduration (integer)supported_durations
Output sizeresolution + aspect_ratiosupported_resolutions, supported_aspect_ratios
Exact pixel sizesizeNot accepted: 400 unsupported_parameter on v1 models
Starting imageframe_images with frame_typesupported_frame_images
Style referencesinput_referencessupported_input_references
Audio on or offgenerate_audiogenerate_audio flag per model

Keep it honest

A catalog check does not replace reading the error field on a failed job. Reference images must be public HTTPS URLs in supported formats, and prompts can be refused by a model's guidelines; neither shows up in the catalog. What the check removes is the cheap class of failure: a number that was never going to fit.

Cache the response briefly rather than fetching it per request, and re-read it when you add a model to a fallback list.

Wire it into a build

Run the script as a CI step with a read-only key kept in the environment, and fail the build when the problem list is non-empty. If you keep a fallback model, loop the same check over each model in the chain, so a config change that breaks the second backend fails before it reaches production.

Extend req to match what your app really sends. A request that adds frame_images can also be checked: confirm each frame_type you use appears in supported_frame_images, and each reference type appears in supported_input_references. The docs say a model accepts a reference type only if the list includes it, so this is a direct test, not a guess.

One more field is worth reading: generate_audio. If your pipeline needs a silent clip and the model reports no way to control it, the check should flag that rather than let a track appear in your output.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume