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:
- A request for an odd length may produce a different length than you intended. Do not assume; read back the result.
- Cost control is a request-side decision. Ask for the shortest clip that shows what you need, because you pay at creation whether or not you keep the output.
- Some models bill a fixed length regardless of what you request, per the API reference. Do not use a longer request to "buy" extra seconds on such a model.
- Which durations a given Kling tier or host accepts is not something to memorise from this page. Check the model page for the tier and host you use, and test with a short request before building a pipeline around a specific length.
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
| Goal | Choice | Why |
|---|---|---|
| Vertical short-form | 9:16 | Generate natively instead of cropping a landscape clip and losing the subject. |
| Feed or grid placements | 1:1 | Check the tier supports it; otherwise crop from a wider master. |
| Cinematic or desktop | 16:9 | A conventional default; confirm the tier supports it on the model page. |
| Prompt iteration | Short duration, lowest sensible tier | Tiers are separate model ids, so promote an approved prompt later. |
| Final delivery | Higher tier, the duration you need | Every 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.
| Model | Cheapest host | Priciest host | Cheapest is | Hosts |
|---|---|---|---|---|
| kling-o3 (720p) | SandBase $0.0588 / second | Tencent TokenHub $0.084 / second | 30% lower | 4 |
| kling-v3 (2160p) | SandBase $0.294 / second | Tencent TokenHub $0.42 / second | 30% lower | 8 |
| kling-v2.6 (std) | WaveSpeedAI $0.042 / second | Kling $0.062 / second | 32% lower | 2 |
| kling-motion-control (std) | Atlas Cloud $0.1071 / second | Novita $0.1575 / second | 32% lower | 2 |
| kling-v3-turbo (1080p) | Pika $0.112 / second | Tencent TokenHub $0.14 / second | 20% lower | 5 |
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:
- 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.
- 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
- Wrong orientation: the combination was ignored. Try the other tier, drop
resolutionand send onlyaspect_ratio, or crop in post. - Shorter or longer than expected: duration was snapped. Request the nearest supported value from the model page.
- Still wrong on one host: pin a host with
model/hostas a soft preference, orprovider.onlywithallow_fallbacks: falsefor a hard pin, and compare. Hosts of the same checkpoint can differ in what they offer.
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
- Kling v3.0 Std vs Pro vs 4K — Which Tier Should You Use?
- Kling Image-to-Video API: Animate a Start Image (Code)
- Kling Motion Control API: Reference Video + Character Image
- Kling O3 (Omni) vs Kling v3: Which Model Should You Call?
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 →