Create a Kling image-to-video task by model
Create a Kling video from a source image with a model-specific route, then retrieve the video by task ID.
curl https://api.cometapi.com/image-to-video/kling-3.0-turbo \
-X POST \
-H "Authorization: Bearer $COMETAPI_KEY" \
-H "Content-Type: application/json" \
--data-raw '{
"contents": [
{
"type": "prompt",
"text": "The camera slowly moves closer to the scene."
},
{
"type": "first_frame",
"url": "https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg"
}
],
"settings": {
"resolution": "720p",
"duration": 5
}
}'import os
import requests
response = requests.post(
"https://api.cometapi.com/image-to-video/kling-3.0-turbo",
headers={"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]},
json={
"contents": [
{
"type": "prompt",
"text": "The camera slowly moves closer to the scene.",
},
{
"type": "first_frame",
"url": "https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg",
},
],
"settings": {
"resolution": "720p",
"duration": 5
},
},
)
response.raise_for_status()
print(response.json()["data"]["id"])
const response = await fetch(
"https://api.cometapi.com/image-to-video/kling-3.0-turbo",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.COMETAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
contents: [
{ type: "prompt", text: "The camera slowly moves closer to the scene." },
{
type: "first_frame",
url: "https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg",
},
],
settings: {
resolution: "720p",
duration: 5,
},
}),
},
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log((await response.json()).data.id);
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cometapi.com/image-to-video/{model}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'contents' => [
[
'type' => 'prompt',
'text' => 'The camera slowly moves closer to the scene.'
],
[
'type' => 'first_frame',
'url' => 'https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cometapi.com/image-to-video/{model}"
payload := strings.NewReader("{\n \"contents\": [\n {\n \"type\": \"prompt\",\n \"text\": \"The camera slowly moves closer to the scene.\"\n },\n {\n \"type\": \"first_frame\",\n \"url\": \"https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cometapi.com/image-to-video/{model}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"contents\": [\n {\n \"type\": \"prompt\",\n \"text\": \"The camera slowly moves closer to the scene.\"\n },\n {\n \"type\": \"first_frame\",\n \"url\": \"https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cometapi.com/image-to-video/{model}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"contents\": [\n {\n \"type\": \"prompt\",\n \"text\": \"The camera slowly moves closer to the scene.\"\n },\n {\n \"type\": \"first_frame\",\n \"url\": \"https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"message": "SUCCEED",
"data": {
"id": "example-task-id",
"status": "submitted"
}
}POST /image-to-video/{model} to create a video task. You can add a prompt to describe the motion. The response contains an id that you use to retrieve the result.
Choose a model
Put the model ID in the URL. Do not add a model field to the JSON body.| Model ID | Resolution | Duration | Audio |
|---|---|---|---|
kling-3.0-turbo | 720p, 1080p | Integer from 3 to 15 seconds | Omit audio |
kling-3.0 | 720p, 1080p, 4k | Integer from 3 to 15 seconds | native or off |
kling-2.6 | 720p, 1080p | 5 or 10 seconds | native or off; use 1080p with native |
kling-2.5-turbo | 720p, 1080p | 5 or 10 seconds | Omit audio |
kling-3.0-turbo accepts a first_frame only. kling-2.5-turbo,
kling-3.0, and kling-2.6 also support a last_frame; include a
first_frame with it. For kling-2.5-turbo and kling-2.6, the
first-and-last-frame combination requires 1080p.
Request parameters
Put each input incontents. A prompt entry uses text; a frame entry uses url. For an image, supply a publicly accessible URL or Base64-encoded JPG or PNG data.
| Field | Type | Required | Description |
|---|---|---|---|
Path model | string | Yes | Model ID in the URL. Choose an ID from the table above; do not add it to the request body. |
contents | array | Yes | Input entries. Include a first_frame image; add a prompt entry or a model-supported last_frame image when needed. |
contents[].type | string | Yes | prompt, first_frame, or last_frame. Include a first_frame when you use last_frame; the selected model determines whether last_frame is available. |
contents[].text | string | For a prompt entry | Text that describes the motion. |
contents[].url | string | For a frame entry | Public image URL or Base64-encoded JPG or PNG data. |
settings.resolution | string | No | Output resolution from the selected model’s row above. Defaults to 720p. |
settings.duration | integer | No | Video length in seconds from the selected model’s row above. Defaults to 5. |
settings.multi_shot | boolean | No | For kling-3.0 only, the official default is true. Set true for multiple shots or false for one shot, and set the value explicitly when you use this field. |
settings.audio | string | No | For kling-3.0 or kling-2.6, set native for generated audio or off for no generated audio. Set the value explicitly when you use this field. |
options.callback_url | string | No | Public URL that receives task updates. |
options.external_task_id | string | No | Your identifier for matching the task to your application. |
options.watermark_info | object | No | Watermark configuration for the output. |
{
"contents": [
{
"type": "prompt",
"text": "The camera slowly moves closer to the scene."
},
{
"type": "first_frame",
"url": "https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg"
}
],
"settings": {
"resolution": "720p",
"duration": 5
}
}
https://api.cometapi.com/image-to-video/kling-3.0-turbo with your CometAPI API key. The OpenAPI code panel provides Shell, Python, and JavaScript requests with the same body.
Retrieve the video
The create response has this shape:{
"code": 0,
"message": "SUCCEED",
"data": {
"id": "example-task-id",
"status": "submitted"
}
}
data.id. Use Get a Kling task with that ID until the task reaches a terminal status. Read the video URL from the task’s outputs array.Authorizations
Authenticate with your CometAPI API key.
Path Parameters
Kling model ID. kling-3.0 supports 4k resolution. The 2.x models accept 5- or 10-second duration.
kling-3.0-turbo, kling-3.0, kling-2.6, kling-2.5-turbo Body
Image-to-video request fields exposed by the CometAPI route. The model ID is a path parameter, not a body field.
Image and text inputs exposed by the CometAPI route. Include a first_frame image. Add a prompt entry or a model-supported last_frame image when needed.
1Show child attributes
Show child attributes
Video generation settings exposed by the CometAPI route. The model ID in the URL determines which values are accepted.
Show child attributes
Show child attributes
Optional task fields exposed by the CometAPI route.
Show child attributes
Show child attributes
Response
The task was created. Use data.id to retrieve its status and video output.
curl https://api.cometapi.com/image-to-video/kling-3.0-turbo \
-X POST \
-H "Authorization: Bearer $COMETAPI_KEY" \
-H "Content-Type: application/json" \
--data-raw '{
"contents": [
{
"type": "prompt",
"text": "The camera slowly moves closer to the scene."
},
{
"type": "first_frame",
"url": "https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg"
}
],
"settings": {
"resolution": "720p",
"duration": 5
}
}'import os
import requests
response = requests.post(
"https://api.cometapi.com/image-to-video/kling-3.0-turbo",
headers={"Authorization": "Bearer " + os.environ["COMETAPI_KEY"]},
json={
"contents": [
{
"type": "prompt",
"text": "The camera slowly moves closer to the scene.",
},
{
"type": "first_frame",
"url": "https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg",
},
],
"settings": {
"resolution": "720p",
"duration": 5
},
},
)
response.raise_for_status()
print(response.json()["data"]["id"])
const response = await fetch(
"https://api.cometapi.com/image-to-video/kling-3.0-turbo",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.COMETAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
contents: [
{ type: "prompt", text: "The camera slowly moves closer to the scene." },
{
type: "first_frame",
url: "https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg",
},
],
settings: {
resolution: "720p",
duration: 5,
},
}),
},
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log((await response.json()).data.id);
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cometapi.com/image-to-video/{model}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'contents' => [
[
'type' => 'prompt',
'text' => 'The camera slowly moves closer to the scene.'
],
[
'type' => 'first_frame',
'url' => 'https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cometapi.com/image-to-video/{model}"
payload := strings.NewReader("{\n \"contents\": [\n {\n \"type\": \"prompt\",\n \"text\": \"The camera slowly moves closer to the scene.\"\n },\n {\n \"type\": \"first_frame\",\n \"url\": \"https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cometapi.com/image-to-video/{model}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"contents\": [\n {\n \"type\": \"prompt\",\n \"text\": \"The camera slowly moves closer to the scene.\"\n },\n {\n \"type\": \"first_frame\",\n \"url\": \"https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cometapi.com/image-to-video/{model}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"contents\": [\n {\n \"type\": \"prompt\",\n \"text\": \"The camera slowly moves closer to the scene.\"\n },\n {\n \"type\": \"first_frame\",\n \"url\": \"https://raw.githubusercontent.com/ultralytics/yolov5/402e17ddf820996f51a191cbb798376e1144f069/data/images/zidane.jpg\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"message": "SUCCEED",
"data": {
"id": "example-task-id",
"status": "submitted"
}
}