Skip to content

Kling

Kling is a video generation model series covering four distinct capabilities — text-to-video, image-to-video, motion control, and omni video. You never name a capability directly: the mode is decided automatically from the model you call and the materials you attach (see How the mode is chosen).

POST https://llm.siraya.ai/v1/videos/generations
GET https://llm.siraya.ai/v1/videos/{video_id}

Synchronous by default, asynchronous on request

By default the request waits for the render and returns the finished video URL. Set async: true to get an id back immediately and poll GET /v1/videos/{video_id} until status is completed or failed — recommended for motion-control and omni-video tasks, which take longer. Pass a callbackUrl to be notified instead of polling. See Asynchronous generation.

Supported Models

Model ID Description
kling-2.5-turbo Fast text-to-video and image-to-video, 720p/1080p
kling-2.6 Text-to-video, image-to-video, and motion control, 720p/1080p
kling-3.0 Highest-fidelity tier — text-to-video, image-to-video, and motion control, up to 4k
kling-3.0-turbo Faster 3.0 tier; the only model that ships native audio by default
kling-3.0-omni Omni video — multi-material reference and video-editing style tasks, up to 4k
kling-o1 Omni video, 720p/1080p, silent output only

Capabilities by model

✅ supported · — not supported.

Model Text→video Image→video Motion control Omni video Resolutions Native audio
kling-2.5-turbo 720p, 1080p native, off
kling-2.6 720p, 1080p native (1080p only), off
kling-3.0 720p, 1080p, 4k native, off
kling-3.0-turbo 720p, 1080p native (default), off
kling-3.0-omni 720p, 1080p, 4k native, off
kling-o1 720p, 1080p off only

kling-2.6 refuses audio: "native" specifically at 720p — use 1080p, or "off". kling-o1 refuses audio: "native" at every resolution. See Audio support.

How the mode is chosen

Your request contains… Runs as
a prompt only text_to_video
a first_frame (and optionally a last_frame) image_to_video
an image entry and a video entry, on a model that supports motion control motion_control
any request to kling-3.0-omni or kling-o1 omni_video

The mode the request actually ran as is reported back in vendor_data.mode.

Authorization string Required
Your API Key (e.g., Bearer <API_KEY>).

Body

All Kling parameters are sent flat, at the top level of the request body — there is no settings or options wrapper.

model string Required
The model ID — one of the six above (e.g., kling-3.0, kling-2.6).
prompt string Required
A text description of the video content. Up to 2500 characters recommended. Required unless you supply it as a prompt entry inside contents instead.
contents array
Every material beyond plain text — first/last frame, motion reference, omni-video references — as a list of typed entries. See contents.
duration integer Default: 5
Video length in seconds, 315 (model-dependent). Not accepted on motion control, and ignored when a base_video is being edited — the output length follows the source material instead. See Behavior worth knowing.
resolution string Default: 720p
720p, 1080p, or 4k. Only kling-3.0 and kling-3.0-omni reach 4k — see Capabilities by model.
aspect_ratio string Default: 16:9
16:9, 9:16, or 1:1. Accepted but silently ignored once a material sets the frame (image-to-video, motion control, and omni video with a first_frame) — see Behavior worth knowing.
audio string Default: off
native (model-generated audio track) or off. Defaults to off on every model except kling-3.0-turbo, which defaults to native. Per-model restrictions apply — see Audio support.
character_orientation string Required for motion control
image or video — which material anchors the character's orientation. Only meaningful on motion-control requests, where it is required.
multi_shot boolean Default: false
When true, multi-shot syntax in the prompt is parsed as a shot list — e.g. "shot 1, 3s, a door opens; shot 2, 2s, a close-up of the handle".
seed integer
Random seed for reproducibility. Any integer.
watermark_info object Default: disabled
{ "enabled": true | false }. When true, each entry in vendor_data.outputs gains a watermark_url alongside url. Sent flat at the top level, even though it lives under options in Kling's own API.
elements array Not supported yet
Kling's own motion-control API accepts an elements array for extra subject/element references alongside the character image. This platform does not support elements yet — a motion-control request must be built from the image + video materials in contents only. See Motion control.
async boolean Default: false
When false, the request waits for generation to finish and returns the completed video URL. When true, it returns immediately with a video id you poll for status — recommended for motion-control and omni-video tasks, which take longer. See Asynchronous generation.
callbackUrl string
Only used when async is true. A URL the router will POST to once generation completes (or fails), so you don't have to poll.
curl https://llm.siraya.ai/v1/videos/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <API_KEY>" \
  -d '{
    "model": "kling-3.0",
    "prompt": "A paper boat drifting on a calm river",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9"
  }'
import requests

url = "https://llm.siraya.ai/v1/videos/generations"
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <API_KEY>"
}
data = {
    "model": "kling-3.0",
    "prompt": "A paper boat drifting on a calm river",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9"
}

response = requests.post(url, headers=headers, json=data)
print(response.json())

Example Response

{
    "data": [
        {
            "url": "https://resources.siraya.ai/video/generated%2Fsiraya_123.mp4",
            "revised_prompt": ""
        }
    ],
    "created": 1760347750
}

With "async": true, the job is accepted immediately instead:

{
  "id": "video_8fK2mQxR7pLnVwZ3tYbC...",
  "object": "video",
  "status": "processing",
  "model": "kling-3.0"
}

Poll GET /v1/videos/{video_id} with that id until status is completed — see Poll for status.

contents — the materials array

Anything beyond plain text goes in contents, as a list of typed entries. Which entry types a model accepts depends on the mode it is serving:

Entry type Carries Where it's valid
prompt text everywhere
first_frame url image-to-video, omni video
last_frame url image-to-video, omni video
image url motion control (the character)
video url motion control (the motion reference)
refer_image url omni video
feature_video url omni video
base_video url omni video (video-editing style tasks)

Adding a first_frame is all it takes to switch a request to image-to-video:

{
  "model": "kling-2.6",
  "contents": [
    { "type": "prompt", "text": "The scene comes alive" },
    { "type": "first_frame", "url": "https://your-domain.com/still.jpg" }
  ],
  "duration": 5,
  "resolution": "720p"
}

Motion control

Motion control transfers the motion of a reference video onto a character image. It is available on kling-2.6 and kling-3.0 only.

A motion-control request needs three things: an image entry (the character), a video entry (the motion reference), and character_orientation.

{
  "model": "kling-3.0",
  "prompt": "The character performs the reference motion",
  "contents": [
    { "type": "image", "url": "https://your-domain.com/character.jpg" },
    { "type": "video", "url": "https://your-domain.com/motion.mp4" }
  ],
  "character_orientation": "image",
  "resolution": "1080p"
}

elements is not supported yet

Kling's motion control natively accepts an elements array — extra subject/element references layered on top of the character image. That parameter is not available on this platform yet. Build motion-control requests from the image + video materials in contents only; do not send elements. Support is planned — this page will be updated when it lands.

Both materials are required

A motion-control request must include both an image entry and a video entry. Sending the motion reference alone would silently fall back to image-to-video or text-to-video, with the reference motion simply ignored — so this platform rejects that combination outright rather than billing you for a result you didn't ask for.

duration is not accepted on motion control. The output length follows the motion-reference video.

Omni video

Every request to kling-3.0-omni or kling-o1 runs as omni_video, regardless of which materials it carries. Omni video accepts the widest set of materials — first_frame, last_frame, refer_image, feature_video, and base_video (for video-editing style tasks).

{
  "model": "kling-3.0-omni",
  "prompt": "Keep the subject, restyle the background as a winter street",
  "contents": [
    { "type": "base_video", "url": "https://your-domain.com/original.mp4" },
    { "type": "refer_image", "url": "https://your-domain.com/style.jpg" }
  ],
  "resolution": "1080p"
}
  • aspect_ratio takes effect only when the request carries no first_frame. A refer_image alone does not set the frame, so you still need to specify the ratio.
  • A base_video being edited sets the output length — duration is ignored.

Audio support

Model Default when unset Notes
kling-2.5-turbo off
kling-2.6 off native is refused specifically at 720p — use 1080p
kling-3.0 off
kling-3.0-turbo native The one model that ships sound by default
kling-3.0-omni off
kling-o1 off native is refused at every resolution — off is the only usable value

Poll for status

GET https://llm.siraya.ai/v1/videos/{video_id}
curl https://llm.siraya.ai/v1/videos/<video_id> \
  -H "Authorization: Bearer <API_KEY>"

When you submit with async: true, call the status endpoint with the returned id until status reads completed or failed. A typical generation finishes in well under a minute; motion-control and omni-video tasks with heavier materials take longer. Poll every few seconds and back off on 429. Passing a callbackUrl at submit time removes the need to poll at all.

{
  "id": "video_8fK2mQxR7pLnVwZ3tYbC...",
  "object": "video",
  "status": "completed",
  "seconds": 5,
  "resolution": "720p",
  "ratio": "16:9",
  "model": "kling-3.0",
  "output_url": "https://.../out.mp4?Expires=...&Signature=...",
  "usage": { "completion_tokens": 0, "total_tokens": 0 },
  "vendor_data": {
    "mode": "text_to_video",
    "requested_audio": "native",
    "outputs": [
      {
        "type": "video",
        "id": "925017418714451989",
        "url": "https://.../out.mp4?Expires=...&Signature=...",
        "duration": "5.041"
      }
    ]
  }
}

Response object

Field Type Present Meaning
id string always Opaque — pass it straight to GET /v1/videos/{video_id}; don't parse it
object string always Always video
status string always processing · completed · failed
error object on failure { code, message }
seconds integer completed Duration, rounded to the nearest second
resolution, ratio string completed, may be absent Echo what the request asked for — see Behavior worth knowing
output_url string completed Signed and expiring — don't cache it as a stable link
usage object always Always { 0, 0 } — Kling has no token concept
vendor_data object always Kling-specific fields — see vendor_data

vendor_data

Facts specific to Kling that don't apply to every video model on this platform live here, rather than cluttering the fields every model shares.

Field Values Meaning
mode text_to_video · image_to_video · motion_control · omni_video Which capability the request actually ran as
requested_audio native · off Echoes what you asked for, or the model's default if you didn't set audio
outputs array The produced artifact(s), with Kling's own field names. outputs[0].duration carries the unrounded duration (e.g. "5.041"), and watermark_url appears here when watermark_info.enabled was true

Behavior worth knowing

Resolution and aspect ratio are what you asked for, not always what came out. On image-to-video and motion control, the reference material decides the frame — an aspect_ratio you send is accepted but silently has no effect, and resolution is echoed from the request rather than measured off the result. On omni video, aspect_ratio only takes effect when the request carries no first_frame.

Motion control and base_video ignore duration. Neither accepts a requested duration — the produced length follows the source material instead (the motion-reference video, or the base_video being edited). Expect seconds in the response to reflect that material's real length, not a number you controlled.

Motion control cannot use elements yet. See the Motion control note above.

Errors

A request-time refusal is final — it means the parameters can't work together, not that the service is unavailable. Retrying the same body won't help.

{
  "error": {
    "code": "invalid_request_error",
    "message": "audio mode 'native' is not supported by the current model",
    "type": "invalid_request_error"
  }
}
Status Meaning
400 An unsupported parameter combination — resolution/duration/audio conflicts, a missing required field, or a rejected parameter such as elements
404 Unrecognized model code
200 with status: "processing" Accepted — keep polling