Route a Kling video job in Python: scene, motion clip or 30 seconds

A small Python router for Sume: performance copies go to Kling motion control, 4-15 s scenes to kling-3, and longer jobs to a catalog id that lists 30 s.

5 min readSume
All posts

A Kling job on Sume goes to one of three places: the motion control route if you hold a reference performance, kling-3 on /v1/videos if it is a 4 to 15 second scene, and a catalog id that lists 30 seconds, such as wan-3.0 or seedance-2.5, if it is longer. A 15-line function makes that choice, so your app never sends a request that the catalog will reject.

The three branches

Each branch follows from a limit that Sume documents. Motion control takes a motion_video_url and a length of 1 to 30 seconds. kling-3 takes 4 to 15 seconds and no reference urls. wan-3.0 takes 2 to 30 seconds, and seedance-2.5 takes 4 to 30.

The function

It returns the path and the model so that you can build the body in the next step. It is a pure function, so you can test it without a key.

def route(seconds: int, has_motion_clip: bool) -> tuple[str, str | None]:
    """Return (path, model) for a Sume Kling-family request."""
    if has_motion_clip:
        if not 1 <= seconds <= 30:
            raise ValueError("motion control takes 1 to 30 s")
        return "/v1/kling/3.0/motion-control", None
    if 4 <= seconds <= 15:
        return "/v1/videos", "kling-3"
    if 15 < seconds <= 30:
        return "/v1/videos", "wan-3.0"
    raise ValueError("split the job or pick another model")

for s, m in ((12, True), (10, False), (28, False)):
    print(s, m, route(s, m))

What each branch costs

Prices are provider list times 1.25, read from Sume's docs. Wan 3.0 is tiered by resolution.

Routes and per-second prices on Sume, USD (read 2026-10-05)
BranchLengthPer second30 s total
Motion control1 to 30 s0.15754.725
kling-3 silent4 to 15 s0.14not reachable in one job
wan-3.0 at 720p2 to 30 s0.1253.75
wan-3.0 at 1080p2 to 30 s0.257.50

Keep the catalog as the truth

Limits change. Before a release, read GET /v1/videos/models and compare supported_durations with the numbers in your function. If a new Kling id such as a 4.0 row shows up with 30 seconds, add a branch for it and keep the old ones as a fallback.

The fallback matters more than the first choice. A router that returns one answer fails when a model is down. Return an ordered list of rows that fit the brief, and try the next one on a retryable error. The fallback chain post shows that pattern in full.

What the router does not decide

The function picks a route from two facts: the length and the presence of a motion clip. It does not choose the resolution, the ratio or the audio setting. Those are fields on the body, and each has its own limits in the catalog row: kling-3 takes 720p or 1080p in 16:9, 9:16 or 1:1, while wan-3.0 has three resolution tiers and its own ratios.

Keep that second step separate. First route, then read the row for the chosen id, then build a body from the allowed values. Splitting the two keeps each function small and testable, and an unsupported ratio becomes a clear error in your code instead of a 400 from the API.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume