# Kling 3.0

Kling 3.0 is Kuaishou's video generation model. One request makes a 3–15 second clip from a prompt, or from a first frame and an optional last frame, at three quality modes (`std`, `pro`, `4K`), with native sound when you ask for it. A clip can also be a sequence of up to five shots, each with its own prompt and length. Send the request, keep the returned task ID, and read the finished video from the task. Images go in as URLs.

## Model IDs

| Model ID    | Inputs                               | Modes              | Length       |
| ----------- | ------------------------------------ | ------------------ | ------------ |
| `kling-3-0` | text, first and last frame, elements | `std`, `pro`, `4K` | 3–15 seconds |

See the [model page](https://seedrouter.ai/models/kling-3-0#pricing) for current prices.

## Quick example

```bash
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": "pro",
    "duration": 5,
    "aspect_ratio": "16:9"
  }'
```

```python
import os
import requests

response = requests.post(
    "https://api.seedrouter.ai/v1/videos/generations",
    headers={"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}"},
    json={
        "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": "pro",
        "duration": 5,
        "aspect_ratio": "16:9",
    },
    timeout=60,
)
response.raise_for_status()
task_id = response.json()["id"]
```

```javascript
const response = await fetch('https://api.seedrouter.ai/v1/videos/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SEEDROUTER_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    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: 'pro',
    duration: 5,
    aspect_ratio: '16:9',
  }),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { id: taskId } = await response.json();
```

```go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "strings"
    "time"
)

func main() {
    body := strings.NewReader(`{
      "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": "pro",
      "duration": 5,
      "aspect_ratio": "16:9"
    }`)
    req, err := http.NewRequest("POST", "https://api.seedrouter.ai/v1/videos/generations", body)
    if err != nil { panic(err) }
    req.Header.Set("Authorization", "Bearer " + os.Getenv("SEEDROUTER_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{Timeout: 60 * time.Second}
    res, err := client.Do(req)
    if err != nil { panic(err) }
    defer res.Body.Close()
    if res.StatusCode != http.StatusOK { panic(res.Status) }
    var task struct { ID string `json:"id"` }
    if err := json.NewDecoder(res.Body).Decode(&task); err != nil { panic(err) }
    fmt.Println(task.ID)
}
```

## Endpoint

```text
POST https://api.seedrouter.ai/v1/videos/generations
```

| Header        | Value                 |
| ------------- | --------------------- |
| Authorization | `Bearer YOUR_API_KEY` |
| Content-Type  | `application/json`    |

The response is a task (`{"id": "task_...", "status": "processing"}`), not the finished video. Poll `GET /v1/tasks/{task_id}` for the result. Keep API keys in server-side code.

## Parameters

| Field            | Type          | Default                    | Notes                                                                                                                                                             |
| ---------------- | ------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`          | string        | required                   | `kling-3-0`                                                                                                                                                       |
| `prompt`         | string        | required for a single shot | Up to 2,500 characters. Optional in multi-shot mode.                                                                                                              |
| `image_urls`     | array of URLs | none                       | Up to 2 images: the first is the first frame, the second the last frame. Without images the clip is text to video.                                                |
| `mode`           | enum          | `pro`                      | `std`, `pro` or `4K` (uppercase K).                                                                                                                               |
| `duration`       | integer       | `5`                        | 3–15 seconds.                                                                                                                                                     |
| `aspect_ratio`   | enum          | `16:9`                     | `16:9`, `9:16` or `1:1`.                                                                                                                                          |
| `sound`          | boolean       | `false`                    | Generate native sound with the video.                                                                                                                             |
| `multi_shots`    | boolean       | `false`                    | Make the clip from the shots in `multi_prompt`.                                                                                                                   |
| `multi_prompt`   | array         | none                       | Up to 5 shots, each `{"prompt", "duration"}`: a prompt of up to 500 characters and a whole number of seconds from 1 to 12. Required when `multi_shots` is `true`. |
| `kling_elements` | array         | none                       | Up to 3 elements, each `{"name", "description", "element_input_urls"}` with 2–4 image URLs.                                                                       |

The schema is strict: unknown fields are rejected rather than ignored. `callback_url` is not available; poll the task instead.

## Multi-shot clips

Set `multi_shots` to `true` and describe each shot in `multi_prompt`. The shot durations must add up to 3–15 seconds; that sum is the clip length, and `duration` is not used. `prompt` can be left out or used for what every shot shares.

```json
{
  "model": "kling-3-0",
  "mode": "pro",
  "multi_shots": true,
  "multi_prompt": [
    {"prompt": "A red paper boat on a calm pond at sunrise, wide shot", "duration": 3},
    {"prompt": "The boat drifts under a small wooden bridge, low angle", "duration": 3}
  ]
}
```

## Elements

An element is a subject the model keeps consistent across the clip: a person, a product or a character. Give it a `name`, a short `description` and 2–4 images of it, then mention it by name in the prompt (for example `@hero`).

```json
{
  "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"]
    }
  ]
}
```

## Media inputs

Every image is a public HTTP(S) URL. Base64 data URIs are not accepted: upload the file to your own storage and pass its URL. Use JPG or PNG images of 10 MB or less.

## Pricing dimensions

Check the [model pricing section](https://seedrouter.ai/models/kling-3-0#pricing) for current rates. Kling 3.0 is billed per second of video, at a rate set by the mode and by whether `sound` is on:

```text
billed seconds = duration                      (single shot)
billed seconds = Σ multi_prompt[].duration     (multi_shots: true)
cost = billed seconds × rate per second
```

The billed seconds are known when the request is accepted, so the amount reserved is the amount charged. View final charges in your account usage history. Failed tasks are not charged.

## Output schema

Submission returns the task:

```json
{"id": "task_...", "model": "kling-3-0", "status": "processing", "created_at": 1789689600}
```

### Get the task

```text
GET https://api.seedrouter.ai/v1/tasks/{task_id}
```

Poll every 10–20 seconds until `status` is `completed` or `failed`. A network timeout while polling does not mean generation failed: keep the task ID and resume checking it. Do not create another task to check progress.

### Completed task

```json
{
  "id": "task_...",
  "model": "kling-3-0",
  "status": "completed",
  "created_at": 1789689600,
  "finished_at": 1789689710,
  "output": {
    "video_url": "https://static.seedrouter.ai/media/tasks/task_example/0.mp4"
  }
}
```

In our tests a 3-second `std` clip came back as MP4 (H.264) at 1280 × 720, and a 5-second `pro` clip with `sound` at 1920 × 1080 with an audio track, each in about two to three minutes.

## Errors

Requests rejected before a task is created return an HTTP error with an `error` object and are not charged. A task that fails after acceptance returns HTTP 200 when queried, with `status: "failed"` and an `error` object.

See the [shared error catalog](https://seedrouter.ai/docs/api/errors) for codes, HTTP statuses, and retry guidance.

```json
{
  "id": "task_...",
  "model": "kling-3-0",
  "status": "failed",
  "error": {
    "code": 60001,
    "message": "The request was rejected by the content policy. Please revise the prompt or input images."
  }
}
```

If submission itself times out, check your tasks before submitting again: the first request may have been accepted.

## Tips

* Describe subject, place, camera move and light in one sentence each; Kling follows camera language such as "slow push-in" and "low angle".
* Draft in `std`, then render the final shot in `pro` or `4K` with the same request.
* Use a first and a last frame to control where a shot starts and ends.
* Split a scene into shots with `multi_prompt` instead of describing several cuts in one prompt.
* Add `no text, no logos` to keep invented marks out.

## Related

* [Kling 3.0 Playground and pricing](https://seedrouter.ai/models/kling-3-0)
* [Download OpenAPI](https://seedrouter.ai/docs/kling-3-0.openapi.json)
* [Copyable Markdown](https://seedrouter.ai/docs/kling-3-0.md)
