Home › Guides › Duration & aspect ratio

How Kling duration, aspect ratio and resolution behave, and how to verify the result

Updated 2026-10-02

Three request fields decide the shape and cost of a Kling clip: duration_secs, aspect_ratio and resolution. None of them behaves the way a strict API would, and the differences affect your bill and your layout. This page lays out the documented semantics, then turns them into a routine for choosing values and checking what you actually got.

duration_secs: requested, snapped, then billed

You send a number of seconds. VideoRouter snaps it to the nearest value the model actually supports; if you omit it, the default is 4. The charge is made once, at creation, from the requested and snapped duration. A few consequences follow:

Motion Control is the documented exception to "you choose": with the reference in input_video_references the output is a fixed length of about four seconds, and with the reference in input_video_url it matches the reference video's own length, up to 30 seconds. There, trimming the reference clip is how you control duration and cost. See the Motion Control guide.

aspect_ratio and resolution: forgiving, not strict

aspect_ratio takes one of 16:9, 9:16, 1:1, 4:3, 3:4 and 21:9. resolution is a tier string the specific model supports, such as 720p, and it varies per model. The two combine to request a size, for example "resolution": "720p" with "aspect_ratio": "9:16".

The behaviour to internalise: an unsupported combination is silently ignored and the model default is used, never a 400. It behaves exactly as if you had omitted both fields. So a typo in a tier name or a ratio the tier does not offer will not fail; it will quietly give you the default framing. Explicit height and width integers are accepted and override aspect_ratio and resolution, which is useful when you need exact pixels but easy to get wrong for the same reason.

Choosing values in practice

GoalChoiceWhy
Vertical short-form9:16Generate natively instead of cropping a landscape clip and losing the subject.
Feed or grid placements1:1Check the tier supports it; otherwise crop from a wider master.
Cinematic or desktop16:9A conventional default; confirm the tier supports it on the model page.
Prompt iterationShort duration, lowest sensible tierTiers are separate model ids, so promote an approved prompt later.
Final deliveryHigher tier, the duration you needEvery re-render is a new billed job.

Kling v3.0 Std, Pro and 4K are separate ids (kling-v3.0-std, kling-v3.0-pro, kling-v3.0-4k), so "I want higher resolution" often means "I want a different model id" rather than a different resolution value. The tier guide covers that choice.

ModelCheapest hostPriciest hostCheapest isHosts
kling-o3 (720p)SandBase
$0.0588 / second
Tencent TokenHub
$0.084 / second
30% lower4
kling-v3 (2160p)SandBase
$0.294 / second
Tencent TokenHub
$0.42 / second
30% lower8
kling-v2.6 (std)WaveSpeedAI
$0.042 / second
Kling
$0.062 / second
32% lower2
kling-motion-control (std)Atlas Cloud
$0.1071 / second
Novita
$0.1575 / second
32% lower2
kling-v3-turbo (1080p)Pika
$0.112 / second
Tencent TokenHub
$0.14 / second
20% lower5

Per second, before VideoRouter's 2% platform fee. For tiered models each row compares the resolution tier with the widest host-to-host gap. Built 2026-10-02 from the live catalog.

Cost depends on duration multiplied by a per-second rate that differs by tier and host; the live table shows the current spread rather than a single number.

Verifying what was applied

Treat a 202 as "job accepted", not "job as requested". Two checks make the difference:

  1. Read the job. The create and status responses can carry extra fields such as the seconds and size that were used, and which provider served the job. The API reference says the exact extras vary by provider, so log the whole response and look for them rather than depending on a specific field.
  2. Probe the file. After download, run ffprobe. This is the check that cannot lie:
ffprobe -v error -select_streams v:0 \
  -show_entries stream=width,height:format=duration \
  -of default=nw=1 clip.mp4

Compare width, height and duration with what you asked for. In a test suite, assert them and fail the build on a mismatch, because the API itself will not.

import json, subprocess

def probe(path):
    out = subprocess.run(
        ["ffprobe", "-v", "error", "-select_streams", "v:0",
         "-show_entries", "stream=width,height:format=duration", "-of", "json", path],
        capture_output=True, text=True, check=True).stdout
    d = json.loads(out)
    return d["streams"][0]["width"], d["streams"][0]["height"], float(d["format"]["duration"])

w, h, secs = probe("clip.mp4")
assert w < h, "asked for 9:16 but got landscape: ratio was ignored"

When the result is not what you asked for

For the first call, see the curl walkthrough; for failures that do return an error, see the error guide. Create a key to test your own combinations; a short clip on the cheapest tier answers most of these questions.

Frequently asked questions

What happens if I request an unsupported aspect ratio on Kling?

Nothing fails. An unsupported resolution and aspect_ratio combination is ignored and the model default is used, exactly as if you had omitted both. Check the output dimensions with ffprobe.

Does Kling duration_secs have to be an exact supported value?

No. The value is snapped to the nearest duration the model supports, and you are billed once at creation for the snapped duration. Check the model page for which values your tier accepts.

How do I confirm the clip matches my request?

Run ffprobe on the downloaded file for width, height and duration, and log the full job response, which may include the seconds and size actually used.

Keep reading

Using Kling is one part of the job.

VideoRouter puts it next to dozens of other video and image models behind one API key, so you can compare providers, prices and fail over automatically. Compare providers on VideoRouter →