How to use the Kling 3.0 API: key, request, polling, frames and multi-shot
Use the Kling 3.0 API step by step: create a key, send a video task, poll it for the video URL, start from a first and last frame, and build multi-shot clips.
Read as MarkdownTo use the Kling 3.0 API, create an API key, POST one JSON body with the model ID kling-3-0 and your prompt, and poll the task it returns until the video URL is ready. One endpoint covers text to video, first and last frame video, multi-shot clips and element references; the fields in the body decide which.
This guide walks through each step with working code, then shows frames, multi-shot clips, elements and the requests that are refused before anything is charged.
What do you need before the first request?
- An API key. Create one on the API keys page and keep it on your server. Never put it in browser code.
- Credits. Add a balance on the billing page. Credits never expire, and failed tasks are not charged.
- The model ID
kling-3-0.
export SEEDROUTER_API_KEY="your-key"How do you send a Kling 3.0 request?
POST the task to /v1/videos/generations:
curl https://api.seedrouter.ai/v1/videos/generations \
-H "Authorization: Bearer $SEEDROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3-0",
"prompt": "A red paper boat drifting on a calm pond at sunrise, soft mist on the water, slow push-in, no text, no logos.",
"mode": "std",
"duration": 5,
"aspect_ratio": "16:9"
}'The response is a task, not a video:
{"id": "task_...", "model": "kling-3-0", "status": "processing", "created_at": 1789689600}Every field except model and prompt has a default:
| Field | Default | Values |
|---|---|---|
mode | pro | std (720p), pro (1080p), 4K |
duration | 5 | 3–15 seconds |
aspect_ratio | 16:9 | 16:9, 9:16, 1:1 |
sound | false | true generates native sound |
The schema is strict: an unknown field is refused with HTTP 400 before a task is created, so a typo never turns into a paid clip with the setting silently ignored.
How do you get the video?
Poll GET /v1/tasks/{id} every 10–20 seconds until status is completed or failed. In our tests a 3-second std clip finished in about two minutes and a 5-second pro clip with sound in about two and a half.
import os
import time
import requests
API = "https://api.seedrouter.ai/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"}
task = requests.post(
f"{API}/videos/generations",
headers=HEADERS,
json={
"model": "kling-3-0",
"prompt": "A red paper boat drifting on a calm pond at sunrise, slow push-in, no text, no logos.",
"mode": "std",
"duration": 5,
},
timeout=60,
)
task.raise_for_status()
task_id = task.json()["id"]
while True:
result = requests.get(f"{API}/tasks/{task_id}", headers=HEADERS, timeout=60).json()
if result["status"] in ("completed", "failed"):
break
time.sleep(15)
if result["status"] == "completed":
print(result["output"]["video_url"])
else:
print(result["error"])A finished task looks like this:
{
"id": "task_...",
"model": "kling-3-0",
"status": "completed",
"output": {"video_url": "https://static.seedrouter.ai/media/tasks/task_example/0.mp4"}
}std came back as 1280 × 720 and pro as 1920 × 1080, both MP4 (H.264); with sound on the file carries a stereo audio track. Download the file to your own storage: hosted links are not permanent. A network timeout while polling does not mean the generation failed, so keep the task ID and check it again instead of submitting a new task.
How do you start from a first and last frame?
Pass one or two image URLs in image_urls. The first image opens the clip; a second one is where it ends. Without images the clip is made from the prompt alone.
{
"model": "kling-3-0",
"prompt": "The camera glides from the empty street to the lit shop window",
"image_urls": ["https://example.com/start.png", "https://example.com/end.png"],
"mode": "pro",
"duration": 6
}Images must be public HTTP(S) URLs, JPG or PNG. Base64 data is refused; upload the file to your own storage first.
How do you make a multi-shot clip?
Set multi_shots to true and describe each shot in multi_prompt, up to five shots of 1–12 seconds each. The shot durations must add up to 3–15 seconds, and that sum is the clip length you are billed for; duration is not used.
{
"model": "kling-3-0",
"mode": "pro",
"sound": true,
"multi_shots": true,
"multi_prompt": [
{"prompt": "Wide shot of a small open kitchen, a chef tosses vegetables in a wok, flames rising, warm light.", "duration": 3},
{"prompt": "Close-up of the wok, vegetables flipping through the flames, oil sizzling, steam drifting.", "duration": 3}
]
}This is the clip that request produced in our test, one 6-second video cut from a wide shot to a close-up:
Kling 3.0, pro (1080p), multi-shot 3 + 3 seconds, with sound.
How do you keep a person or product consistent?
Add it to kling_elements: a name, a short description and 2–4 image URLs of the subject, up to three elements per request. Mention the element by name in the prompt.
{
"model": "kling-3-0",
"prompt": "@hero slowly turns toward the camera in soft window light",
"kling_elements": [
{
"name": "hero",
"description": "a young woman with short black hair and a yellow raincoat",
"element_input_urls": ["https://example.com/hero-front.png", "https://example.com/hero-side.png"]
}
]
}Which requests are refused before anything is charged?
These come back as HTTP 400 at submission, with no task created and nothing charged:
| Request | Why |
|---|---|
| A multi-shot clip whose shots add up to less than 3 or more than 15 seconds | Kling 3.0 makes clips of 3–15 seconds |
An element without a description | Every element needs one |
More than 2 image_urls, more than 5 shots or more than 3 elements | Outside the model's limits |
mode: "4k" in lowercase | The value is 4K |
| Base64 images, or any field not in the table above | Media go in as URLs; the schema is strict |
A task that is accepted and then fails, for example on the model's content policy, returns status: "failed" with an error code and is not charged. The error catalog lists the codes.
How does this differ from Kling's own API?
Kling's developer API uses its own field names, and its legacy and current versions differ from each other.[1][2] If you are moving an integration, map the fields:
| SeedRouter | Kling legacy API |
|---|---|
model: "kling-3-0" | model_name: "kling-v3" |
sound: true / false | sound: "on" / "off" |
duration: 5 (integer) | duration: "5" (string) |
mode: "4K" | mode: "4k" |
image_urls: [first, last] | image and image_tail |
multi_shots + multi_prompt: [{prompt, duration}] | multi_shot + shot_type: "customize" + multi_prompt: [{index, prompt, duration}] |
kling_elements: [{name, description, element_input_urls}] | element_list: [{element_id}], created in advance |
SeedRouter delivers results as a task you poll; callback_url is not offered.
Can a coding agent run it for you?
Yes. The Kling 3.0 page has a ready prompt for Claude Code, Codex or Cursor that reads the key from your environment, shows you the request and its cost, waits for your approval, then submits, polls and downloads the clip. The same page has a playground that sends the exact body your code would.
Kling 3.0 API questions
Is there an official Kling 3.0 API?
Yes. Kling publishes a developer API with its own keys, unit-based billing and request format.[1][3] SeedRouter is a separate way to call Kling 3.0 with one key and one balance shared with other models.
How much does the Kling 3.0 API cost?
It is billed per second of video, by mode and by whether sound is on. The Kling 3.0 API pricing guide works through clip costs, and the model page shows the current rates.
Can I cancel a task?
No. Once accepted, a task runs to completion or failure. Failed tasks are not charged.
References
- Kling AI. Kling 3.0: Text to Video (API reference, legacy version). Retrieved October 6, 2026 from kling.ai.
- Kling AI. Kling 3.0: Image to Video (API reference, legacy version). Retrieved October 6, 2026 from kling.ai.
- Kling AI. Pricing: Video (developer API). Retrieved October 6, 2026 from kling.ai.



