Skip to content

Kling: video generation API

Generate Kling video: models, parameters, responses, and errors for text- and image-to-video, subjects, motion control, avatar, and lip sync.

Kling generates video from text, images, videos, and subjects, and also handles motion control, avatar, and lip sync: submit a task, then poll the HopBase task ID for the result.

ItemValue
Base URLhttps://api.hop-base.com/v1
Submit a video taskPOST /v1/video/generate
Poll a taskGET /v1/video/tasks/{task_id}
List tasksGET /v1/video/tasks
Custom subjectsPOST / GET /v1/kling/subjects
Lip-sync face detectionPOST /v1/kling/faces (billed per call)
Key group"Kling Official"

Kling image generation and expansion are asynchronous tasks too: submit with POST /v1/images/generations and poll GET /v1/video/tasks/{task_id}. Models, parameters, responses, and errors are on Kling Image.

Available models

Before sending paid work, confirm the exact model IDs your key returns with GET /v1/models.

Model IDDurationResolutionsAudioOfficial price
kling-v3-turbo3–15 s720p / 1080p / 2k / 4kSingle price tier$0.1176from/ second
kling-v3-omni3–15 s720p / 1080p / 2k / 4kAudio or silent$0.0882from/ second
kling-v33–15 s720p / 1080p / 2k / 4kAudio or silent$0.0882from/ second
kling-o13–10 s720p / 1080p / 2k / 4kSilent only$0.0882from/ second
kling-v2-65 / 10 s720p / 1080p / 2k / 4kAudio or silent$0.0441from/ second
kling-v2-5-turbo5–10 s720p / 1080pSilent only$0.0441from/ second
kling-v2-1, kling-v2-05–10 s720p / 1080p / 2k / 4kSilent only$0.0588from/ second
kling-v1-65–10 s720p / 1080p / 2k / 4kSilent only$0.0588from/ second
kling-v3-motion-controlsource duration720p / 1080p / 2k / 4kNo audio generated$0.1324from/ second
kling-v2-6-motion-controlsource duration720p / 1080pNo audio generated$0.0735from/ second
kling-avataraudio duration720p / 1080pFrom the input audio$0.0588from/ second
kling-lip-syncsource durationDoes not affect the priceFrom the input audio$0.0147/ second

A resolution / audio combination outside this table is rejected at submission with 400. Each model's price tiers and full specs are on its model card, for example kling-v3, kling-v3-omni, and kling-lip-sync.

  • kling-v3-turbo uses Kling's fixed Voice price tier: audio does not change the price, and callers cannot choose a voice.
  • kling-v3-omni with a feature reference video is silent only, at 720p / 1080p / 2k.
  • kling-o1 without reference inputs supports only 5 or 10 seconds.
  • kling-v2-6 with audio starts at 1080p; 720P with audio is not priced.
  • A kling-v1-6 base video edit ignores audio.

Model matrix

Supported inputs per video model:

Model IDReference imagesReference videoSubjectsShots
kling-v3-turboNoNoYesNo
kling-v3-omniUp to 7featureYesYes
kling-v3Up to 6NoYesYes
kling-o1Up to 4featureNoNo
kling-v2-6Up to 4NoNoNo
kling-v2-5-turboUp to 3NoNoNo
kling-v2-1, kling-v2-0NoNoNoNo
kling-v1-6NobaseNoNo
kling-v3-motion-control, kling-v2-6-motion-control1 image + 1 videoScene-specificNoNo
kling-avatar1-5 imagesNoNoNo
kling-lip-syncNoNoNoNo
  • "Reference images" counts only usage: reference, not first/last frames or the total length of images[].
  • On kling-v3-omni, base is not priced, and a silent 4K feature request is not priced.
  • kling-v1-6 base video editing uses multi_elements pricing.

Request parameters

All requests use Authorization: Bearer sk-your-key and Content-Type: application/json. The body is decoded strictly: only the fields listed on this page are accepted. A field outside those lists, an unknown field inside a nested object, or a second JSON value after the body returns 400 before any task is created, and nothing is billed.

ParameterRequiredType & limitsDefaultDescription
modelRequiredAn ID from the model table—Sets the duration, resolution, and input limits
promptRequired without media≤ 2,500 characters—May be empty only when images / videos are supplied
durationOptionalinteger seconds, range per model5Must be omitted for motion control, avatar, and lip sync
resolutionOptional720p / 1080p / 2k / 4k720pCase-insensitive; must be one the model supports
aspect_ratioOptional16:9 / 9:16 / 1:1—Not filled in by the gateway when omitted
audioOptionalbooleanfalseGenerates a soundtrack, only on models the table lists with audio
imagesOptionalarray; each item has exactly one of url / file_id—First/last frames, reference images, person images
videosOptionalarray, at most one item—Reference video, video to edit, motion video
subjectsOptionalarray; each item has a non-empty id—Only kling-v3-turbo, kling-v3, kling-v3-omni
shotsOptionalobject—Storyboard; only kling-v3 and kling-v3-omni
extraOptionalobject—Used only by motion control, avatar, and lip sync
voice_ids—not available yet—A non-empty value returns 400
  • Kling checks the prompt length during the task.
  • Any extra key on an ordinary video model returns 400.
  • Set the video frame with resolution and aspect_ratio; don't send size, response_format, or user from OpenAI habits, n on a video request, or top-level image_url / video_url.

Every video field is listed in the API reference under Submit a video task (choose Kling).

Media locators

Each images[] or videos[] item must contain exactly one of url or file_id:

{ "url": "https://cdn.example.com/file.png" }
{ "file_id": "your-file-id" }

url must be an absolute, publicly reachable http:// or https:// URL. The same rule applies to the image endpoint, face detection, and the avatar extra.sound_file. These are rejected synchronously at submission:

  • Empty strings or relative paths.
  • Non-HTTP(S) schemes such as file:// or ftp://.
  • Private, loopback, or link-local addresses.
  • URLs with embedded credentials.
  • Both url and file_id together.

Text and image to video

Ordinary video models support text-to-video, first/last frames, reference images, reference video, and video editing. Put images in images[] and videos in videos[]; sending only a prompt is text-to-video.

Each image's usage sets its role: first_frame, last_frame, or reference.

{
  "model": "kling-v3-omni",
  "prompt": "<<<element_1>>> and <<<element_2>>> rotate slowly on a clean studio table",
  "duration": 5,
  "resolution": "1080p",
  "images": [
    { "url": "https://cdn.example.com/first.png", "usage": "first_frame" },
    { "file_id": "last-frame-file-id", "usage": "last_frame" },
    { "url": "https://cdn.example.com/reference-a.png", "usage": "reference" }
  ]
}
  • There can be at most one first frame and one last frame.
  • A last frame requires a first frame.
  • A last frame is not supported with more than two reference images.
  • With kling-v2-1, providing both first and last frames restricts resolution to 1080p.
  • Reference-image limits are in the model table and count only usage: reference.

There is at most one videos[] item, and it must carry reference_type:

{
  "videos": [
    {
      "url": "https://cdn.example.com/character-motion.mp4",
      "reference_type": "feature",
      "keep_original_sound": false
    }
  ]
}
  • feature is a reference video, accepted only by kling-v3-omni and kling-o1.
  • base is a video edit, accepted only by the tested and priced kling-v1-6.
  • A base video must be the only media input and cannot be combined with images or subjects.
  • keep_original_sound is a boolean that keeps the source video's audio track.

Subjects and shots

subjects[] uses fixed subject IDs. Subjects are supported by kling-v3-turbo, kling-v3, and kling-v3-omni only.

{
  "subjects": [
    { "id": "subject-92951593344", "name": "cat" },
    { "id": "subject-92951593345", "name": "dog" }
  ]
}
  • Every item requires a non-empty id; name is optional.
  • Items are positional: subjects[0] is <<<element_1>>>, and so on.
  • Every supplied subject must be referenced in the prompt.
  • The prompt must not reference a <<<element_N>>> that doesn't exist.
  • For kling-v3, subjects also require at least one images[] item with usage: "reference".

Shots are supported by kling-v3 and kling-v3-omni only:

{
  "model": "kling-v3-omni",
  "prompt": "A short product story in two shots",
  "duration": 5,
  "shots": {
    "mode": "customize",
    "segments": [
      { "index": 1, "prompt": "The box opens", "duration": 2 },
      { "index": 2, "prompt": "The product is revealed", "duration": 3 }
    ]
  }
}
  • mode is intelligence or customize.
  • Intelligence mode must omit segments; customize mode requires them.
  • There can be at most 6 custom segments, numbered consecutively from 1.
  • Each segment prompt is non-empty and at most 512 characters.
  • Each segment lasts at least one second, and the durations must sum exactly to the request duration.
  • Use structured shots; raw extra.multi_shot, extra.shot_type, and extra.multi_prompt are rejected.

Create a custom subject

POST /v1/kling/subjects creates a custom subject whose ID you can put in subjects[].id. GET on the same path lists existing subjects.

FieldRequiredValues
nameRequired≤ 20 characters
descriptionOptional≤ 100 characters
reference_typeRequiredimage_refer / video_refer
frontal_image_urlRequired with image_referFront-facing image URL
reference_image_urlsRequired with image_refer1–3 URLs
video_urlRequired with video_referVideo URL
voice_idOptional, video_refer onlyVoice to attach to the subject
tag_idsOptionalstring array
  • image_refer builds the subject from images; video_refer builds it from one video.
  • Every URL must be a public HTTP(S) URL under the "Media locators" rules.
  • reference_image_urls may not repeat the front image or each other.
  • video_refer accepts no image fields, and image_refer does not accept video_url.
  • tag_ids groups the subject; each tag is non-empty and unique.

Creation is an asynchronous task: the submit returns 202 with an id (object is kling.subject.task); poll it with GET /v1/video/tasks/{task_id}. The completed result carries element_ids and elements.

Motion control

Motion control makes a person image follow the movement in a video. It requires exactly one video and one person image, and the duration comes from the input media, so duration must be omitted.

{
  "model": "kling-v3-motion-control",
  "prompt": "Follow the dancer's movement",
  "resolution": "1080p",
  "images": [{ "file_id": "person-image-file-id" }],
  "videos": [{ "url": "https://cdn.example.com/dance.mp4", "keep_original_sound": true }],
  "extra": { "character_orientation": "video" }
}
  • The scene fixes each input's role, so the image takes no usage and the video takes no reference_type.
  • videos[].keep_original_sound is a boolean and maps to Kling's keep_original_sound flag.
  • The only additional parameter currently verified is extra.character_orientation (image or video).
  • The output is temporary.

Avatar

Avatar (kling-avatar) makes a person image speak an audio track. The duration comes from the input audio, so duration must be omitted.

  • It requires 1-5 person images and accepts no videos.
  • It requires exactly one of extra.sound_file (an HTTP(S) audio URL) or extra.audio_id.

Lip sync

Lip sync (kling-lip-sync) gives a face in a video new mouth movements, and accepts no images or videos. It takes two steps: detect faces, then submit the task.

First, call face detection with one or more media locators. The body accepts only a videos array, each item with exactly one of url / file_id under the "Media locators" rules.

curl https://api.hop-base.com/v1/kling/faces \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{"videos":[{"file_id":"source-video-file-id"}]}'

Then submit the returned session with one face_choose item:

{
  "model": "kling-lip-sync",
  "extra": {
    "session_id": "face-session-id",
    "face_choose": [
      { "face_id": "face-1", "sound_file": "https://cdn.example.com/voice.mp3" }
    ]
  }
}
  • face_choose must contain exactly one item with a non-empty face_id and sound_file.
  • The source audio/video determines the duration, so duration must be omitted.
  • voice_ids and raw extra.voice_list stay unavailable until a matching Kling capability is confirmed.

Response

Kling task fields sit at the top level of the response; they are not wrapped in task the way Seedance's are.

Submit response

A successful submit returns 202 with the task ID in id, shaped like kt57x<task-id>. Kling image tasks also return 202 with an id in the same shape, and both are polled the same way.

{
  "id": "ktEXAMPLE",
  "object": "video.generation.task",
  "model": "kling-v3",
  "status": "queued",
  "created": 1790000000,
  "billing_bucket": "720p_silent_noref"
}

Task query fields

FieldDescription
idHopBase task ID, kt…
objectvideo.generation.task for video and image tasks, kling.subject.task for custom subjects
statusqueued → processing → completed or failed; only the last two are terminal
progressProgress
outputsOutput URLs once completed, an array of URL strings
usageMetering once completed: bucket plus billed_seconds for video or billed_images for images
usage.cost / usage.cost_usd / usage.currencyThe charge for this task: cost_usd is the USD amount actually deducted from your balance, cost is the same charge in CNY, and currency is always CNY
element_ids / elementsSubjects from a completed custom-subject task
error.codeStable error code on failure; see "Failed" below
error.messageFixed English explanation on failure

Treat any value other than completed and failed as still running. Don't send a billing header when polling.

Once the task finishes, the query's top-level usage also carries cost_usd — the USD amount actually deducted from your balance for this task, 0 for an uncharged failure — cost (the same charge in CNY), and currency (always CNY); see Video overview. The task list (GET /v1/video/tasks) carries the same cost, cost_usd, and currency in the usage of every finished task.

In progress

{
  "id": "ktEXAMPLE",
  "object": "video.generation.task",
  "model": "kling-v3",
  "status": "processing",
  "created": 1790000000
}

Succeeded

A completed task carries the output URLs in outputs:

{
  "id": "ktEXAMPLE",
  "status": "completed",
  "outputs": [
    "https://api.hop-base.com/example-signed-image.png"
  ],
  "usage": { "bucket": "720p_silent_noref", "billed_seconds": 5, "cost": 2.55, "cost_usd": 0.375, "currency": "CNY" }
}

The URLs are served from api.hop-base.com and are signed links valid for 24 hours from the moment the task completes. Querying again returns the same URL without extending it, and an expired link returns 410, so download results within that window.

Failed

A failed task still answers the query with HTTP 200 and status failed. error.code is a stable error code, and error.message explains it in fixed English wording.

{
  "id": "ktEXAMPLE",
  "object": "video.generation.task",
  "model": "kling-v3",
  "status": "failed",
  "created": 1790000000,
  "error": {
    "code": "timeout",
    "message": "task did not reach a billable terminal state within 2 hours; polling stopped"
  }
}

Decide success or failure from status, branch on error.code, and show error.message. Older failed tasks may omit error.code.

Caseerror.code
Prompt or reference media refused by moderationinput_sensitive
Output blocked by moderationoutput_video_sensitive (image: safety_rejected)
Concurrency ceiling reachedrate_limited
Model version retiredunsupported_model
Prompt too long, or parameters or media rejectedinvalid_request
Reference media unreadablereference_input_invalid
Generation failed or stopped before finishinggeneration_failed
Still unfinished 2 hours after creationtimeout
Task ended with no outputno_output

Minimal example

This submits a 5-second 720p text-to-video task and polls it until it ends.

# 1. Submit
curl https://api.hop-base.com/v1/video/generate \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-v3",
    "prompt": "A red ball rolls across a white table",
    "duration": 5,
    "resolution": "720p"
  }'

# 2. Poll with the returned id
curl https://api.hop-base.com/v1/video/tasks/kt57xYOUR_TASK_ID \
  -H "Authorization: Bearer sk-your-key"

Notes

A non-compliant asset fails minutes after submission.

The gateway validates request structure and counts only; resolution, format, size, and duration are enforced by Kling asynchronously during the task. Make sure assets download reliably from the public internet and meet Kling's official specs before submitting.

  • A Kling task, image tasks included, that is still unfinished 2 hours after creation is marked failed and not billed.
  • Tasks cannot be cancelled; for the other rules shared by every video family, see Video overview.
  • Result links are valid for 24 hours from completion and are not extended.
  • Motion control, avatar, and lip sync take their duration from the input media, so duration must be omitted.

Balance reservation

The balance check applies to video submissions, not image.

Submitting a Kling video task checks available balance minus the estimated cost of your in-flight tasks minus this request's own estimate; a shortfall returns 402. Kling image generation reserves nothing and is only blocked once your balance is at or below zero.

A shortfall carries code insufficient_balance, and the estimate is released automatically once the task ends. Lip sync (kling-lip-sync) cannot be estimated in advance and reserves nothing.

Common errors and fixes

A submission error creates no task and bills nothing; error.message explains the cause. A 400 has type invalid_request_error; a 402 has code insufficient_balance.

HTTPCaseWhat to do
400A field, value, or combination is invalidFix what the message names and resubmit
400An image model sent to the video endpointUse the image endpoint
402Not enough balance for the video reservationTop up, or wait for in-flight tasks to end
404Model ID not in the catalogCheck the ID with GET /v1/models
429 / 5xxBusy or temporarily unavailableRetry shortly

The exact error when a field such as size is sent (the face-detection endpoint returns the same one):

{
  "error": {
    "message": "request body does not match the JSON contract: json: unknown field \"size\"",
    "type": "invalid_request_error"
  }
}

The verbatim error.message for the other cases:

# An image model sent to the video endpoint (400)
model "<model ID>" is an image model; use /v1/images/generations

# Video model ID not in the catalog (404)
model "<model ID>" is not in the Kling catalog

# Image model ID not in the catalog (404)
model "<model ID>" is not an image model in this catalog

Media and common parameters

# Media item with neither or both of url / file_id
<images or videos>[<index>] must provide exactly one of url or file_id

# url that is not a public absolute http(s) address
<images or videos>[<index>].url must be a publicly accessible absolute http(s) URL

# No prompt and no media at all (except lip sync)
prompt and input media cannot both be empty

# Negative duration
duration cannot be negative

# duration outside the model range
model <model ID> supports <min> to <max> seconds, got <value>

# kling-o1 without reference inputs and a duration other than 5 or 10
Kling O1 without reference media only supports duration 5 or 10 seconds

# kling-v2-6 with a duration other than 5 or 10
model kling-v2-6 only supports a duration of 5 or 10 seconds, got <value>

# aspect_ratio other than 16:9 / 9:16 / 1:1
aspect_ratio="<value>" is invalid; allowed values: 16:9 / 9:16 / 1:1

# No price tier for the resolution / audio / reference-video combination
model "<model ID>" does not support billing bucket "<tier>" for this request

# Non-empty voice_ids (the message starts with this)
voice_ids is not available yet

# An extra key this model does not accept
extra.<key> is not in the verified parameter contract of model <model ID>

# duration sent to a model whose length comes from the input
duration of model <model ID> is determined by the input media; do not pass duration

First/last frames, reference images, and reference video

# Missing or invalid usage
images[<index>].usage is required for standard Kling video requests
images[<index>].usage="<value>" is invalid; allowed values: first_frame / last_frame / reference

# First- and last-frame rules
at most 1 first-frame image is allowed
at most 1 last-frame image is allowed
a last frame requires a first frame with usage=first_frame
Kling 2.1 first/last-frame generation only supports 1080p
a last frame is not supported with more than 2 reference images (got <count>)

# Reference image counts
with a reference video, reference images + subjects cannot exceed 4, got <total> (<images> images + <subjects> subjects)
without a reference video, reference images + subjects cannot exceed 7, got <total> (<images> images + <subjects> subjects)
model <model ID> supports at most <max> reference images, got <count>
model <model ID> does not support reference-based generation

# Missing or invalid reference_type, or more than 1 video
videos[0].reference_type is required for standard Kling video requests; allowed values: feature / base
videos[<index>].reference_type="<value>" is invalid; allowed values: feature / base
standard Kling video requests accept at most 1 videos input

# Reference video type not supported by the model, or base mixed with images / subjects
model <model ID> has no confirmed feature reference-video capability or price tier
model <model ID> has no confirmed base video-edit price tier
base video edit cannot be combined with images or subjects; only a single video to edit is accepted

# Original-sound parameter inside extra
extra.keep_original_sound cannot be passed through; use videos[].keep_original_sound

Motion control, avatar, and lip sync

# Motion control
motion control requires exactly 1 motion video and 1 character image
motion control images[<index>] does not accept usage; the character image role is fixed by the scene
motion control videos[<index>] does not accept reference_type; the motion video role is fixed by the scene
extra.character_orientation must be image or video

# Avatar
Kling avatar requires at least 1 character image
model <model ID> supports at most 5 character images, got <count>
Kling avatar does not accept videos input
Kling avatar requires exactly one of extra.sound_file or extra.audio_id
extra.sound_file must be a non-empty string
extra.audio_id must be a non-empty string
extra.sound_file must be a publicly accessible http(s) audio URL

# Face detection: invalid JSON or any other field
request body does not match the JSON contract: …

# Face detection: missing or empty videos
videos is required and must contain at least one item

# Lip sync
Kling lip-sync does not accept images or videos; use extra.session_id and extra.face_choose
Kling lip-sync requires a non-empty extra.session_id
Kling lip-sync requires an extra.face_choose array with exactly 1 item
extra.face_choose[0].<key> is not part of the lip-sync contract
extra.face_choose[0].face_id must be a non-empty string or a non-negative integer
extra.face_choose[0].sound_file must be a non-empty string
extra.face_choose[0].sound_file must be a publicly accessible http(s) audio URL
extra.voice_list is reserved; use voice_ids instead (voice selection is not available yet)

Failed tasks

The usual causes are media outside Kling's official specs (resolution, format, size, duration) or a content moderation refusal. Each message says what to do next; after either 2-hour timeout, resubmit. A failed task is never billed.

The verbatim video-task error.message values follow. Image tasks say image generation and reference image; custom subjects say subject creation.

# input_sensitive: prompt refused by moderation
the prompt was rejected by content moderation; rephrase it and submit again

# input_sensitive: reference media refused by moderation
the reference media was rejected by content moderation; replace it and submit again

# input_sensitive: moderation, source not reported
the prompt or reference media was rejected by content moderation; revise it and submit again

# output_video_sensitive / safety_rejected: output blocked by moderation
the generated result was blocked by content moderation; adjust the prompt or reference media and submit again

# rate_limited: concurrency ceiling reached
this model is at its concurrency limit right now; please retry shortly

# unsupported_model: model version retired
this model version is no longer available; switch to another model and submit again

# invalid_request: prompt too long
the prompt is too long for this model (at most 2500 characters); shorten it and submit again

# invalid_request: parameters or media rejected
the request was rejected as invalid by the model; check the parameters and media against the documented limits, then submit again

# reference_input_invalid: reference media unreadable
a reference image or video is missing or could not be read; make sure every URL is publicly reachable and points to a supported file, then submit again

# generation_failed: generation failed (other)
video generation failed; please retry, and contact support with the task ID if it keeps failing

# generation_failed: stopped before finishing
video generation was stopped before it finished; please retry, and contact support with the task ID if it keeps failing

# generation_failed: task could not be tracked (ends with this)
… contact support with the task ID

# timeout: still unfinished 2 hours after creation
task did not reach a billable terminal state within 2 hours; polling stopped

# timeout: custom subject still unfinished after 2 hours
subject task did not reach a terminal state within 2 hours; polling stopped

# no_output: task ended with no output
video generation finished without a usable output; please retry, and contact support with the task ID if it keeps failing

# no_output: custom subject ended without a subject ID
subject creation finished without returning a subject ID; check the media and create it again

Billing

Kling bills video generation per second of output video, at the rate for the model's resolution and its silent / audio / reference-video variant — not by video token. Only a task that completes successfully is billed; a failed task never is.

  • Face detection (POST /v1/kling/faces) is billed per call.
  • Creating a custom subject is currently free.
  • For image billing, see Kling Image.
Lip-sync bills a five-second minimum.

Lip-sync billing is per second with a five-second minimum, so a four-second result is billed as five seconds.

Official list prices are on the pricing page. Your own rate is the one shown in the signed-in model catalog, and each request's actual charge is in your usage record.

Next steps