Skip to navigation

Kling 3

Generate 3–15 second videos at the std or pro tier from text or one or two frames, with multi-shot storyboards and reusable elements; billed per second.

  • Asynchronous: the create call returns a task ID; the video arrives when the task succeeds.
  • Three ways in: text only, a first frame, or a first and last frame. This model takes no reference images, videos or audio.
  • resolution is a tier: std renders at 720p and pro (the default) at 1080p.
  • Multi-shot: up to five shots, each with its own prompt and length, from one first-frame image. The shot lengths must add up to duration.
  • Elements: up to three named subjects you define once with elements.
  • Billed per second of video at the tier you choose. A failed task costs nothing.
POST/v1/videos/tasksTry it

Opens this model in the API Explorer. Enter your BeatAPI API key to create a task: the call is real and is billed to your own balance.

Endpoint and authentication

POST https://api.beatapi.io/v1/videos/tasks

Authorization string Required

Your BeatAPI API key, sent as Bearer <BEATAPI_API_KEY>. Create keys in the Dashboard. Keep keys on your server; never ship them in a browser or mobile app.

Send the body as JSON with Content-Type: application/json. Idempotency-Key is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with Idempotent-Replayed: true; the same key with a different body returns 409 idempotency_conflict. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.

How a request works

1

Create the task

POST the parameters below to the endpoint. A 201 means the task was accepted and its price reserved from your balance; the work runs in the background. Save data.id.

2

Wait for it to finish

Call GET /v1/tasks/{task_id} and wait data.poll_after_seconds between calls (5 s for images, 8 s for videos) until status is succeeded or failed. Or register a webhook for task.succeeded and task.failed; keep polling as the fallback, because a task stopped by the processing timeout sends no event.

3

Save the result

On succeeded, download every data.output.media[].url and store the files you need; BeatAPI does not promise how long result URLs stay available. On failed, read data.error_code and data.error_message: the reserved amount was returned to your balance, and data.retryable says whether sending the same request again can succeed.

Input modes

ModeRequired inputsNotes
Text to videomodel, promptSend no images.
First framemodel, prompt, images (1 link)The video starts from the image.
First and last framemodel, prompt, images (2 links)images[0] is the first frame, images[1] the last.
Multi-shotmodel, prompt, images (exactly 1 link), multi_shots: true, multi_promptShot lengths must add up to duration (5 if you leave it out).
Elementsmodel, prompt, elementsCombine with any mode above. Up to three elements.

Request parameters

model string Required

The model to run.

Value: kling-v3

If the value is wrong

  • Missing: "model" is required
  • An image model sent to this endpoint: "model" nano-banana-2 is served by POST /v1/images/tasks, not this endpoint

prompt string Required

What happens in the video: subject, action, camera movement and style.

Length: 1–5000 characters

  • Length is counted in characters (a CJK character counts as one).
  • It is required in every mode, including multi-shot, where each shot also has its own prompt in multi_prompt.

If the value is wrong

  • Missing: "prompt" is required
  • Empty or longer than the limit: "prompt" has an unsupported length

images string[] Optional

A first frame, or a first and a last frame.

Items: 1–2
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • One link: the video starts from this image. Two links: images[0] is the first frame and images[1] the last.
  • Multi-shot (multi_shots: true) takes exactly one image.
  • There are no reference-image fields on this model; pictures of a subject go in elements.

If the value is wrong

  • More than two links: "images" accepts at most 2 items
  • An empty array: "images" requires at least 1 item
  • Not an https:// link: "images[0]" must be a public HTTPS URL
  • multi_shots: true with no image or two images: Kling V3 multi-shot mode requires exactly one image

duration integer OptionalDefault: 5

Length of the video in seconds, a whole number. It is what you are billed for.

Default: 5
Range: 3–15

  • If you leave it out, 5 is used and billed.
  • With multi_shots: true, the duration of the shots in multi_prompt must add up to this number exactly. If you leave duration out, they must add up to 5.

If the value is wrong

  • Outside the range, not a whole number, or sent as a string: "duration" is outside its supported range
  • Multi-shot lengths that do not add up to duration: Kling V3 shot durations must sum to duration

aspect_ratio string OptionalDefault: 16:9

Shape of the video as width:height.

Allowed values: 16:9, 9:16, 1:1
Default: 16:9

  • The default is 16:9.

If the value is wrong

  • A value not in the list: "aspect_ratio" must be one of: [16:9 9:16 1:1]

resolution string OptionalDefault: pro

The quality tier: std renders at 720p, pro renders at 1080p. pro costs more per second. The names are std and pro, not pixel sizes.

Allowed values: std, pro
Default: pro

  • If you leave it out, pro is used and billed.
  • 4K, 720p and 1080p are not accepted: send std or pro.

If the value is wrong

  • A value not in the list (for example 720p or 4K): "resolution" must be one of: [std pro]

sound boolean Optional

Whether the video has a generated soundtrack.

  • If you leave it out, sound follows multi_shots: on for a multi-shot request, off otherwise. Send true or false to decide for yourself.

If the value is wrong

  • Not true or false: "sound" must be a boolean

multi_shots boolean OptionalDefault: false

Turns on storyboard mode: the video is made of the shots listed in multi_prompt. The default is false.

Default: false

  • Needs exactly one image in images and a multi_prompt whose shot lengths add up to duration. Without multi_shots: true, multi_prompt is refused.
  • Checks run in this order: one image, then multi_prompt present, then the lengths.

If the value is wrong

  • Not true or false: "multi_shots" must be a boolean
  • No image or more than one image: Kling V3 multi-shot mode requires exactly one image
  • multi_prompt missing: Kling V3 multi-shot mode requires multi_prompt
  • Shot lengths do not add up to duration: Kling V3 shot durations must sum to duration

multi_prompt object[] Optional

The shots of a multi-shot video, in order: one to five objects, each with its own prompt and length.

Items: 1–5

  • Each shot is an object with two required fields, and no others are accepted:
  • multi_prompt[].prompt (string, required): what happens in this shot, 1 to 500 characters.
  • multi_prompt[].duration (integer, required): the length of this shot in whole seconds, 1 to 12.
  • The shot lengths must add up to the request’s duration (5 when duration is left out), and that total is at most 15.
  • Only valid with multi_shots: true.

If the value is wrong

  • Sent without multi_shots: true: "multi_prompt" requires multi_shots=true
  • More than five shots: "multi_prompt" accepts at most 5 items
  • An empty array: "multi_prompt" requires at least 1 item
  • A shot without prompt: "prompt" is required in "multi_prompt[0]"
  • A shot without duration: "duration" is required in "multi_prompt[0]"
  • A shot prompt that is empty or over 500 characters: "multi_prompt[0].prompt" has an unsupported length
  • A shot length outside 1 to 12 or not a whole number: "multi_prompt[0].duration" is outside its supported range
  • A key other than prompt and duration: field "name" is not supported in "multi_prompt[0]"
  • Shot lengths do not add up to duration: Kling V3 shot durations must sum to duration

elements object[] Optional

Up to three named subjects (a character, a product, a prop), each defined once with pictures.

Items: ≤ 3

  • An array of at most three objects. Each object accepts these keys and no others:
  • elements[].name (string, required): the element’s name, at least 1 character.
  • elements[].description (string, optional): what the element is. If you leave it out, the name is used as the description.
  • elements[].element_input_urls (array of strings, required): 1 to 4 public HTTPS links that show the element.
  • elements[].element_input_audio_urls (array of strings, optional): exactly one public HTTPS audio link for the element.
  • elements[].start_time and elements[].end_time (integers, optional): times in milliseconds, each a whole number from 0 to 30000. Send both or neither. end_time must be greater than start_time, and end_time - start_time must be from 3000 to 8000 (3 to 8 seconds).
  • The limits on links apply to each element on its own: every entry may have its own four links and one audio link.

If the value is wrong

  • More than three elements: "elements" accepts at most 3 items
  • An element that is not an object: "elements[0]" must be an object
  • An element without name: "name" is required in "elements[0]"
  • An element without element_input_urls: "element_input_urls" is required in "elements[0]"
  • An empty name: "elements[0].name" has an unsupported length
  • More than four links: "elements[0].element_input_urls" accepts at most 4 items
  • An empty element_input_urls array: "elements[0].element_input_urls" requires at least 1 item
  • A link that is not https://: "elements[0].element_input_urls[1]" must be a public HTTPS URL
  • More than one audio link: "elements[0].element_input_audio_urls" accepts at most 1 items
  • start_time or end_time outside 0 to 30000, or not whole: "elements[0].start_time" is outside its supported range
  • A key that an element does not accept: field "color" is not supported in "elements[0]"
  • Only one of start_time and end_time, end_time not after start_time, or a segment shorter than 3 s or longer than 8 s: Kling V3 element segment must provide a 3-8 second start_time/end_time range

Input media limits

The gateway reads every input before the task is created and refuses one outside these limits with a 400 bad_request that names the input. Nothing is charged.

  • The gateway checks only that every image, element link and audio link is a public HTTPS link. It does not measure size, format or dimensions before the task is created, so an input the model cannot use fails the task after submission; the message says what to change and the whole reservation is returned.
  • Have a local file? Upload it with POST /v1/files and pass the returned data.url.

Multi-shot rules

These are checked in this order when the task is created; a request that breaks one is refused with 400 bad_request and costs nothing.

RuleMessage
multi_prompt is sent but multi_shots is not true"multi_prompt" requires multi_shots=true
multi_shots: true without exactly one image in imagesKling V3 multi-shot mode requires exactly one image
multi_shots: true without multi_promptKling V3 multi-shot mode requires multi_prompt
The shot lengths do not add up to duration (5 if left out)Kling V3 shot durations must sum to duration
  • Text-only multi-shot is not available: a multi-shot video always starts from one image.
  • A multi-shot request is billed for duration seconds, which is the sum of its shots.

Fields this model does not accept

Sending one of these is refused before anything is charged, instead of being ignored:

  • reference_images, reference_videos, reference_audios, generate_audio, seed, quality, watermark, task_type, output_format → field "reference_images" is not supported by model kling-v3 (with the field you sent).
  • Any other unknown field → unknown field: <name>.

Request examples

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "kling-v3",
"prompt": "A dramatic product reveal of a glass water bottle, slow orbiting camera, soft studio reflections",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "pro",
"sound": true
}'

Text to video

A 5-second clip at the pro tier (1080p) with sound.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "kling-v3",
"prompt": "A dramatic product reveal of a glass water bottle, slow orbiting camera, soft studio reflections",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "pro",
"sound": true
}'

First frame

The video starts from the image.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "kling-v3",
"prompt": "The bottle slowly rotates on its pedestal while reflections move across the glass",
"images": [
"https://media.beatapi.io/samples/smart-bottle.png"
],
"duration": 5,
"resolution": "pro",
"sound": true
}'

First and last frame

The video moves from the first image to the second, at the cheaper std tier (720p).

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "kling-v3",
"prompt": "The camera moves from the bottle on the table to the singer on a neon stage in one continuous shot",
"images": [
"https://media.beatapi.io/samples/smart-bottle.png",
"https://media.beatapi.io/samples/neon-singer.png"
],
"duration": 5,
"resolution": "std"
}'

Multi-shot

Two 3-second shots from one first-frame image. The shot lengths (3 + 3) equal duration (6).

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "kling-v3",
"prompt": "A two-shot cinematic product reveal",
"images": [
"https://media.beatapi.io/samples/smart-bottle.png"
],
"duration": 6,
"aspect_ratio": "16:9",
"resolution": "pro",
"sound": true,
"multi_shots": true,
"multi_prompt": [
{
"prompt": "Macro detail shot of the bottle with moving reflections",
"duration": 3
},
{
"prompt": "Wide hero reveal of the bottle on a dark pedestal",
"duration": 3
}
]
}'

Reusable element

Defines one named element from two pictures. The element is named product and its description is optional.

curl --request POST \
--url https://api.beatapi.io/v1/videos/tasks \
--header "Authorization: Bearer $BEATAPI_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "kling-v3",
"prompt": "A slow cinematic camera orbit around the product",
"duration": 5,
"resolution": "pro",
"elements": [
{
"name": "product",
"description": "The featured water bottle",
"element_input_urls": [
"https://media.beatapi.io/samples/smart-bottle.png",
"https://media.beatapi.io/samples/neon-singer.png"
]
}
]
}'

Responses

Create a task (201)

The task object. output is null until the task succeeds. Fields marked “while running” disappear once the task finishes.

{
"data": {
"id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"object": "task",
"task_kind": "video",
"capability_id": "kling-v3",
"capability_version": 1,
"media_type": "video",
"model": "kling-v3",
"status": "queued",
"stage": "queued",
"created_at": 1791993600,
"updated_at": 1791993600,
"completed_at": null,
"poll_after_seconds": 8,
"output": null,
"usage": {
"credits_reserved": 0.65,
"credits_settled": 0,
"credits_refunded": 0,
"credits_charged": 0.65,
"billable_duration_seconds": 5
},
"request_id": "req_5f0c2a9e4b7d4e31",
"error_code": null,
"error_message": null
}
}
FieldTypeDescription
data.idstringTask ID: task_ followed by 32 letters and digits. Use it to poll and to match webhook events.
data.objectstringAlways task.
data.task_kindstringimage or video.
data.capability_idstringThe model ID you sent.
data.capability_versionintegerContract version of the model, currently 1.
data.media_typestringimage or video.
data.modelstringThe model ID you sent (same as capability_id).
data.statusstringqueued, processing, succeeded or failed. Only the last two are final.
data.stagestringRepeats status; kept for older clients.
data.created_atintegerWhen the task was created, Unix seconds.
data.updated_atintegerLast change, Unix seconds.
data.completed_atinteger | nullWhen the task finished, Unix seconds; null while it runs.
data.poll_after_secondsintegerWhile running: how long to wait before the next poll (5 for images, 8 for videos).
data.typical_secondsobjectWhile running, when enough recent tasks exist: p50 and p90 completion times in seconds over the last window, from samples tasks.
data.outputobject | nullThe result; null until status is succeeded. See the output fields below.
data.usage.credits_reservednumberUSD held from your balance when the task was created.
data.usage.credits_chargednumberUSD this task costs; 0 on a failed task.
data.usage.credits_settlednumberUSD finally taken; set when the task succeeds, otherwise 0.
data.usage.credits_refundednumberUSD returned to your balance; equals the reservation on a failed task once the refund is recorded.
data.usage.billable_duration_secondsintegerVideo only: the seconds the price is based on. Absent when the model reports no duration.
data.request_idstringRequest ID. Include it when you contact support.
data.error_codestring | nullFailure code; null unless the task failed.
data.error_messagestring | nullWhat went wrong and what to change; null unless the task failed.

Finished task

GET /v1/tasks/{task_id} returns HTTP 200 with status: "succeeded" and the result in data.output.

{
"data": {
"id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"object": "task",
"task_kind": "video",
"capability_id": "kling-v3",
"capability_version": 1,
"media_type": "video",
"model": "kling-v3",
"status": "succeeded",
"stage": "succeeded",
"created_at": 1791993600,
"updated_at": 1791993690,
"completed_at": 1791993690,
"output": {
"media": [
{
"type": "video",
"url": "https://media.beatapi.io/outputs/task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ/0.mp4",
"mime_type": "video/mp4"
}
],
"r2_url": "https://media.beatapi.io/outputs/task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ/0.mp4"
},
"usage": {
"credits_reserved": 0.65,
"credits_settled": 0.65,
"credits_refunded": 0,
"credits_charged": 0.65,
"billable_duration_seconds": 5
},
"request_id": "req_5f0c2a9e4b7d4e31",
"error_code": null,
"error_message": null
}
}

Output fields

FieldTypeDescription
output.mediaobject[]The generated files; one video for this model.
output.media[].typestringAlways video.
output.media[].urlstringHTTPS link to the stored video. Download and keep it; no retention period is promised.
output.media[].mime_typestringThe media type of the file, normally video/mp4.
output.r2_urlstringThe video URL again, for older clients. Read media instead.

Failed task

A failed task is still HTTP 200 on GET /v1/tasks/{task_id}: the failure is in the body. The reservation is returned in full, so nothing is charged.

{
"data": {
"id": "task_7Qm2Xc9LpR4vT8sKa1Nf6YbH3eWdJ0uZ",
"object": "task",
"task_kind": "video",
"capability_id": "kling-v3",
"capability_version": 1,
"media_type": "video",
"model": "kling-v3",
"status": "failed",
"stage": "failed",
"created_at": 1791993600,
"updated_at": 1791993690,
"completed_at": 1791993690,
"output": null,
"usage": {
"credits_reserved": 0.65,
"credits_settled": 0,
"credits_refunded": 0.65,
"credits_charged": 0,
"billable_duration_seconds": 5
},
"retryable": true,
"request_id": "req_5f0c2a9e4b7d4e31",
"error_code": "processing_failed",
"error_message": "The task failed during processing on our side. Retry; a failed task is refunded."
}
}
FieldTypeDescription
data.error_codestringOne of bad_request and content_policy_violation (change the request) or processing_unavailable, processing_timeout, processing_failed and result_transfer_failed (try again later). See Errors.
data.error_messagestringA sentence that names the problem and the fix.
data.retryablebooleanPresent only on a failed task: true when the same request can succeed if you send it again.
data.usageobjectOnce the refund is recorded (normally at the moment the task fails): credits_charged and credits_settled are 0, and credits_refunded equals credits_reserved.

Complete example

Create a task, wait for it with the server’s polling hint, and print the result URLs. Set BEATAPI_API_KEY in your environment and install requests.

import os
import time
import uuid
import requests
API = "https://api.beatapi.io"
HEADERS = {"Authorization": f"Bearer {os.environ['BEATAPI_API_KEY']}"}
def create_task(body: dict) -> dict:
# One Idempotency-Key per logical request: a retry with the same key cannot create a second task.
headers = {**HEADERS, "Idempotency-Key": str(uuid.uuid4())}
for attempt in range(3):
response = requests.post(f"{API}/v1/videos/tasks", headers=headers, json=body, timeout=60)
if response.status_code in (429, 503) and attempt < 2:
time.sleep(int(response.headers.get("Retry-After", 10)))
continue
break
try:
payload = response.json()
except ValueError: # an edge error page is not JSON
response.raise_for_status()
raise
if not response.ok:
error = payload["error"]
raise RuntimeError(f"{response.status_code} {error['code']}: {error['message']} (request_id={error.get('request_id')})")
return payload["data"]
def wait_for_task(task_id: str, timeout_seconds: int = 1800) -> dict:
deadline = time.monotonic() + timeout_seconds
while time.monotonic() < deadline:
response = requests.get(f"{API}/v1/tasks/{task_id}", headers=HEADERS, timeout=30)
if response.status_code == 429 or response.status_code >= 500:
time.sleep(int(response.headers.get("Retry-After", 10)))
continue
response.raise_for_status()
task = response.json()["data"]
if task["status"] in ("succeeded", "failed"):
return task
time.sleep(task.get("poll_after_seconds", 5))
raise TimeoutError(f"task {task_id} is still running; keep polling later")
task = create_task({
"model": "kling-v3",
"prompt": "A dramatic product reveal of a glass water bottle, slow orbiting camera, soft studio reflections",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "pro",
"sound": True
})
print("created", task["id"])
task = wait_for_task(task["id"])
if task["status"] == "failed":
raise SystemExit(f"{task['error_code']}: {task['error_message']}")
for item in task["output"]["media"]:
print(item["url"])

Billing

  • sound does not change the price: it depends on duration and resolution only, so the price rows apply with or without sound.
  • The price is per second of video, at the tier you choose: the list below shows 8-second clips, so divide by 8 for the rate (about 0.11persecondat‘std‘and0.11 per second at `std` and 0.13 at pro).
  • The number of seconds is duration, or 5 when you leave it out; for a multi-shot request it is the sum of the shots, which equals duration. usage.billable_duration_seconds on the task shows it.
  • The price is reserved when the task is created and settled when the video is ready. A failed task, including one refused by moderation after submission, is refunded in full.

Common errors

Error or symptomCauseFix
400 "resolution" must be one of: [std pro]A pixel size such as 720p, 1080p or 4K was sent. This model takes tiers.Send std (renders at 720p) or pro (renders at 1080p).
400 Kling V3 multi-shot mode requires exactly one imagemulti_shots: true with no image, or with two.Send one image in images. There is no text-only multi-shot.
400 Kling V3 shot durations must sum to durationThe multi_prompt lengths do not add up to duration, or to 5 when duration is left out.Make the shot lengths add up to duration exactly, for example 3 + 3 for duration: 6.
400 "multi_prompt" requires multi_shots=truemulti_prompt was sent without multi_shots: true.Add multi_shots: true, or remove multi_prompt.
400 Kling V3 multi-shot mode requires multi_promptmulti_shots: true without multi_prompt.Add multi_prompt with one to five shots.
400 Kling V3 element segment must provide a 3-8 second start_time/end_time rangeAn element has only one of start_time and end_time, end_time is not after start_time, or the segment is shorter than 3 or longer than 8 seconds. Both are in milliseconds.Send both, in milliseconds, with end_time - start_time between 3000 and 8000.
400 "elements[0].element_input_urls" accepts at most 4 itemsMore than four links in one element.Keep up to four links per element; split subjects into separate elements (at most three).
400 field "reference_images" is not supported by model kling-v3This model has no reference fields (also generate_audio, seed, quality).Remove the field. Pictures of a subject go in elements.
400 "duration" is outside its supported rangeNot a whole number from 3 to 15, or sent as a string.Send an integer such as 5.
Task failed with content_policy_violationThe prompt, an input image or the result was refused by moderation.Change the prompt or the images. Retrying unchanged fails again; nothing is charged.
402 insufficient_creditsThe balance is below the reservation for this length and tier.Top up, shorten duration, or use std.

HTTP errors at a glance

Errors before a task exists arrive as a non-2xx response, and nothing is charged. Branch on error.code or error.retryable; message names the problem. The full list and retry policy are on Errors.

{
"error": {
"code": "bad_request",
"message": "\"prompt\" is required",
"retryable": false,
"request_id": "req_5f0c2a9e4b7d4e31"
}
}
HTTP statuserror.codeWhat to do
400bad_request, content_policy_violationFix the request; the message names the field. Do not retry unchanged.
401missing_api_key, invalid_api_key (older clients may see unauthorized)Send a valid key as Authorization: Bearer <key>.
402insufficient_creditsTop up, or raise the key’s quota, then send it again.
403forbiddenThe key or account may not use this model (for example, free credit only covers some models). Do not retry unchanged.
404not_foundOn GET /v1/tasks/{task_id}: the task does not exist for this key’s account. Check the ID.
409idempotency_conflictUse a new Idempotency-Key, or wait for the first request with this key to finish.
429rate_limit_exceededWait Retry-After seconds (also error.retry_after_seconds), then retry.
500internal_errorRetry with backoff; contact support with request_id if it continues.
503processing_unavailable, processing_timeout, processing_failed, result_transfer_failedNothing was charged. Retry with exponential backoff.

Authentication

AuthorizationBearer

Send your API key as Authorization: Bearer <BEATAPI_API_KEY>.

Headers

Idempotency-KeystringOptional<=255 characters

Send the body as JSON with Content-Type: application/json. Idempotency-Key is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with Idempotent-Replayed: true; the same key with a different body returns 409 idempotency_conflict. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.

Request

This endpoint expects an object.
modelenumRequired

The model to run.

Value: kling-v3

If the value is wrong

  • Missing: "model" is required
  • An image model sent to this endpoint: "model" nano-banana-2 is served by POST /v1/images/tasks, not this endpoint
Allowed values:
promptstringRequired1-5000 characters

What happens in the video: subject, action, camera movement and style.

Length: 1–5000 characters

  • Length is counted in characters (a CJK character counts as one).
  • It is required in every mode, including multi-shot, where each shot also has its own prompt in multi_prompt.

If the value is wrong

  • Missing: "prompt" is required
  • Empty or longer than the limit: "prompt" has an unsupported length
aspect_ratioenumOptionalDefaults to 16:9

Shape of the video as width:height.

Allowed values: 16:9, 9:16, 1:1

Default: 16:9

  • The default is 16:9.

If the value is wrong

  • A value not in the list: "aspect_ratio" must be one of: [16:9 9:16 1:1]
Allowed values:
durationintegerOptional3-15Defaults to 5

Length of the video in seconds, a whole number. It is what you are billed for.

Default: 5

Range: 3–15

  • If you leave it out, 5 is used and billed.
  • With multi_shots: true, the duration of the shots in multi_prompt must add up to this number exactly. If you leave duration out, they must add up to 5.

If the value is wrong

  • Outside the range, not a whole number, or sent as a string: "duration" is outside its supported range
  • Multi-shot lengths that do not add up to duration: Kling V3 shot durations must sum to duration
elementslist of objectsOptional

Up to three named subjects (a character, a product, a prop), each defined once with pictures.

Items: ≤ 3

  • An array of at most three objects. Each object accepts these keys and no others:
  • elements[].name (string, required): the element’s name, at least 1 character.
  • elements[].description (string, optional): what the element is. If you leave it out, the name is used as the description.
  • elements[].element_input_urls (array of strings, required): 1 to 4 public HTTPS links that show the element.
  • elements[].element_input_audio_urls (array of strings, optional): exactly one public HTTPS audio link for the element.
  • elements[].start_time and elements[].end_time (integers, optional): times in milliseconds, each a whole number from 0 to 30000. Send both or neither. end_time must be greater than start_time, and end_time - start_time must be from 3000 to 8000 (3 to 8 seconds).
  • The limits on links apply to each element on its own: every entry may have its own four links and one audio link.

If the value is wrong

  • More than three elements: "elements" accepts at most 3 items
  • An element that is not an object: "elements[0]" must be an object
  • An element without name: "name" is required in "elements[0]"
  • An element without element_input_urls: "element_input_urls" is required in "elements[0]"
  • An empty name: "elements[0].name" has an unsupported length
  • More than four links: "elements[0].element_input_urls" accepts at most 4 items
  • An empty element_input_urls array: "elements[0].element_input_urls" requires at least 1 item
  • A link that is not https://: "elements[0].element_input_urls[1]" must be a public HTTPS URL
  • More than one audio link: "elements[0].element_input_audio_urls" accepts at most 1 items
  • start_time or end_time outside 0 to 30000, or not whole: "elements[0].start_time" is outside its supported range
  • A key that an element does not accept: field "color" is not supported in "elements[0]"
  • Only one of start_time and end_time, end_time not after start_time, or a segment shorter than 3 s or longer than 8 s: Kling V3 element segment must provide a 3-8 second start_time/end_time range
imageslist of stringsOptional

A first frame, or a first and a last frame.

Items: 1–2

Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.

  • One link: the video starts from this image. Two links: images[0] is the first frame and images[1] the last.
  • Multi-shot (multi_shots: true) takes exactly one image.
  • There are no reference-image fields on this model; pictures of a subject go in elements.

If the value is wrong

  • More than two links: "images" accepts at most 2 items
  • An empty array: "images" requires at least 1 item
  • Not an https:// link: "images[0]" must be a public HTTPS URL
  • multi_shots: true with no image or two images: Kling V3 multi-shot mode requires exactly one image
multi_promptlist of objectsOptional

The shots of a multi-shot video, in order: one to five objects, each with its own prompt and length.

Items: 1–5

  • Each shot is an object with two required fields, and no others are accepted:
  • multi_prompt[].prompt (string, required): what happens in this shot, 1 to 500 characters.
  • multi_prompt[].duration (integer, required): the length of this shot in whole seconds, 1 to 12.
  • The shot lengths must add up to the request’s duration (5 when duration is left out), and that total is at most 15.
  • Only valid with multi_shots: true.

If the value is wrong

  • Sent without multi_shots: true: "multi_prompt" requires multi_shots=true
  • More than five shots: "multi_prompt" accepts at most 5 items
  • An empty array: "multi_prompt" requires at least 1 item
  • A shot without prompt: "prompt" is required in "multi_prompt[0]"
  • A shot without duration: "duration" is required in "multi_prompt[0]"
  • A shot prompt that is empty or over 500 characters: "multi_prompt[0].prompt" has an unsupported length
  • A shot length outside 1 to 12 or not a whole number: "multi_prompt[0].duration" is outside its supported range
  • A key other than prompt and duration: field "name" is not supported in "multi_prompt[0]"
  • Shot lengths do not add up to duration: Kling V3 shot durations must sum to duration
multi_shotsbooleanOptionalDefaults to false

Turns on storyboard mode: the video is made of the shots listed in multi_prompt. The default is false.

Default: false

  • Needs exactly one image in images and a multi_prompt whose shot lengths add up to duration. Without multi_shots: true, multi_prompt is refused.
  • Checks run in this order: one image, then multi_prompt present, then the lengths.

If the value is wrong

  • Not true or false: "multi_shots" must be a boolean
  • No image or more than one image: Kling V3 multi-shot mode requires exactly one image
  • multi_prompt missing: Kling V3 multi-shot mode requires multi_prompt
  • Shot lengths do not add up to duration: Kling V3 shot durations must sum to duration
resolutionenumOptionalDefaults to pro

The quality tier: std renders at 720p, pro renders at 1080p. pro costs more per second. The names are std and pro, not pixel sizes.

Allowed values: std, pro

Default: pro

  • If you leave it out, pro is used and billed.
  • 4K, 720p and 1080p are not accepted: send std or pro.

If the value is wrong

  • A value not in the list (for example 720p or 4K): "resolution" must be one of: [std pro]
Allowed values:
soundbooleanOptional

Whether the video has a generated soundtrack.

  • If you leave it out, sound follows multi_shots: on for a multi-shot request, off otherwise. Send true or false to decide for yourself.

If the value is wrong

  • Not true or false: "sound" must be a boolean

Response

The task object. output is null until the task succeeds. Fields marked “while running” disappear once the task finishes.

Errors

400
Bad Request Error
401
Unauthorized Error
402
Payment Required Error
403
Forbidden Error
409
Conflict Error
429
Too Many Requests Error
500
Internal Server Error
503
Service Unavailable Error