Pick the highest resolution a Sume video model lists (Python)

Sume's catalog row is now the one resolution list for both video endpoints. A short Python helper reads supported_resolutions and steps down instead of failing.

5 min readSume
All posts

Read supported_resolutions from GET /v1/videos/models, then send the highest one at or below the size you want. Since commit fab7d59af (#11356) that list is the single source for the Video Router rule and for /v1/videos, so a value taken from it is not refused for resolution on either endpoint.

Why a hard-coded list now goes stale

Three rows moved in that commit. seedance-2-fast and seedance-2-mini dropped 1080p, kling-3 now lists only 1080p (a 720p request is still accepted as an alias and renders 1080p), and minimax-h3 gained 2K and 4K. A client with a copy-pasted table from last week is wrong on all three. The docs state that the catalog row lists only what the model really renders and that a test pins the docs table to it.

The commit also removed the per-model resolution allowlist that used to sit in refineVideoRouterModelLimits, so there is no second list to disagree with the first.

The helper

The response shape is the documented one on docs.sume.com/models/videos: a data array whose items carry id and supported_resolutions. The ranking below covers the tokens the catalog lists, from 360p up to 4K; the models endpoint lists 4K in uppercase.

import os
import requests

RANK = {"360p": 360, "480p": 480, "720p": 720, "768p": 768,
        "1080p": 1080, "2K": 1440, "4K": 2160}


def pick_resolution(model_id, wanted):
    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()
    row = next(m for m in r.json()["data"] if m["id"] == model_id)
    listed = [x for x in row["supported_resolutions"] if x in RANK]
    fits = [x for x in listed if RANK[x] <= RANK[wanted]]
    if not fits:
        raise ValueError(f"{model_id} lists {listed}, none at or below {wanted}")
    return max(fits, key=RANK.get)


if __name__ == "__main__":
    print(pick_resolution("seedance-2-fast", "1080p"))

What it returns on the changed rows

Calling the helper with a 1080p wish gives the values below, from the catalog rows at that commit. A row that lists no resolution at or below the wish raises instead of guessing.

pick_resolution(model, "1080p") against the catalog rows at fab7d59af, apps/api/src/video-router/catalog.ts
Model idListedHelper returns
seedance-2-fast480p, 720p720p
seedance-2-mini480p, 720p720p
seedance-2480p, 720p, 1080p1080p
kling-31080p1080p
minimax-h3480p, 768p, 2K, 4K768p

Limits of the approach

If you do send an unlisted value, the Video Router refusal names the list: "1080p is not supported by model seedance-2-fast. It renders 480p, 720p." That message comes from refineVideoRouterResolution in apps/api/src/schemas.ts.

  • Stepping down changes the price. Read pricing_skus from the same row if a cost cap matters.
  • The helper does not check duration, aspect ratio or references; each model has its own envelope, and the docs say to read the catalog instead of assuming one.
  • Stepping down is wrong for a deliverable with a fixed size. Raise the error to the caller there, or choose a different model id.

Related posts

More in Developers

All Developers posts

Written by Sume