curl --request POST \
--url https://api.bitstudio.ai/v1/images/{id}/video \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "The model turns gently"
}
'import requests
url = "https://api.bitstudio.ai/v1/images/{id}/video"
payload = { "prompt": "The model turns gently" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({prompt: 'The model turns gently'})
};
fetch('https://api.bitstudio.ai/v1/images/{id}/video', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bitstudio.ai/v1/images/{id}/video",
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([
'prompt' => 'The model turns gently'
]),
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.bitstudio.ai/v1/images/{id}/video"
payload := strings.NewReader("{\n \"prompt\": \"The model turns gently\"\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.bitstudio.ai/v1/images/{id}/video")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"The model turns gently\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bitstudio.ai/v1/images/{id}/video")
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 \"prompt\": \"The model turns gently\"\n}"
response = http.request(request)
puts response.read_body{
"jobs": [
{
"id": "11111111-1111-4111-8111-111111111111",
"status": "pending",
"task": "image-to-video",
"created_at": "2026-09-15T12:00:00Z",
"result": null,
"error": null,
"credits_used": 15
}
]
}{
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"error": "<string>",
"cta": true,
"next_action": "<string>"
}Animate an image
Turn a completed image into a video clip.
curl --request POST \
--url https://api.bitstudio.ai/v1/images/{id}/video \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "The model turns gently"
}
'import requests
url = "https://api.bitstudio.ai/v1/images/{id}/video"
payload = { "prompt": "The model turns gently" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({prompt: 'The model turns gently'})
};
fetch('https://api.bitstudio.ai/v1/images/{id}/video', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bitstudio.ai/v1/images/{id}/video",
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([
'prompt' => 'The model turns gently'
]),
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.bitstudio.ai/v1/images/{id}/video"
payload := strings.NewReader("{\n \"prompt\": \"The model turns gently\"\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.bitstudio.ai/v1/images/{id}/video")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"The model turns gently\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bitstudio.ai/v1/images/{id}/video")
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 \"prompt\": \"The model turns gently\"\n}"
response = http.request(request)
puts response.read_body{
"jobs": [
{
"id": "11111111-1111-4111-8111-111111111111",
"status": "pending",
"task": "image-to-video",
"created_at": "2026-09-15T12:00:00Z",
"result": null,
"error": null,
"credits_used": 15
}
]
}{
"code": "<string>",
"message": "<string>",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"error": "<string>",
"cta": true,
"next_action": "<string>"
}prompt. The defaults are model: "kling-2.5" and a five-second duration.
Kling 3 models support clips of 3–15 seconds, saved-asset subjects, audio, and multi-shot options. With multi_prompt, omit the top-level prompt and duration; shot durations must total at most 15 seconds. Optional start and end frames must meet the video input requirements. The result has type: "video" and cannot be passed to an image-only operation.
A successful request returns HTTP 202 with a jobs array. Save each id, then get the job until it finishes. Read the completed media from result.url and its reusable ID from result.id. Use an Idempotency-Key when submitting work that may be retried.Authorizations
Create an API key in Studio → account menu → API Keys. Keep it on your server.
Headers
Use a unique key for each intended creation. Retry the same method, path and JSON with the same key to replay its response for 24 hours after completion. Conflicting requests and unfinished or uncertain outcomes return 409. An uncertain receipt is never automatically rerun.
1 - 128^[!-~]+$Path Parameters
Source resource ID.
Body
- Kling 2.5 (default)
- Kling 3
Video model. Defaults to kling-2.5 when omitted. All successful submissions return jobs.
kling-2.5 "kling-2.5"
Single-shot length in seconds: 5 for kling-2.5; 3–15 for Kling 3. Omit when using multi_prompt.
5 3 <= x <= 155
Generate audio with Kling 3. Must be false or omitted for kling-2.5.
false Scene and motion direction. Omit when using multi_prompt.
Kling 3 shots. Omit prompt and duration when using this array. Each shot requires 3–15 seconds; their total must not exceed 15 seconds. End frames require a single shot.
1 - 5 elementsShow child attributes
Show child attributes
Kling 3 subject references. Each asset must be an accessible model or outfit with an HTTP(S) display_image. Model assets are ordered before outfit assets in provider element numbering.
Show child attributes
Show child attributes
Video output ratio.
16:9, 9:16, 1:1 Additional subject directions for Kling 3 only.
Additional subject directions for Kling 3 only.
Optional end frame. Its dimensions must match the start frame. Mutually exclusive with last_frame_url.
Direct end-frame URL. The same media constraints apply.
Response
Accepted; poll each job.
1Show child attributes
Show child attributes