curl https://api.apipod.ai/v1/videos/generations \
-H "Authorization: Bearer $APIPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}'import os
import requests
payload = {
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}
response = requests.post(
"https://api.apipod.ai/v1/videos/generations",
headers={
"Authorization": f"Bearer {os.environ['APIPOD_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body := []byte(`{
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}`)
req, err := http.NewRequest(http.MethodPost, "https://api.apipod.ai/v1/videos/generations", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("APIPOD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(out))
}use reqwest::Client;
use serde_json::json;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let payload = json!({
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
});
let response = Client::new()
.post("https://api.apipod.ai/v1/videos/generations")
.bearer_auth(env::var("APIPOD_API_KEY")?)
.json(&payload)
.send()
.await?
.error_for_status()?;
println!("{}", response.text().await?);
Ok(())
}const response = await fetch("https://api.apipod.ai/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIPOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}),
});
if (!response.ok) {
throw new Error(`APIPod request failed: ${response.status} ${await response.text()}`);
}
console.log(await response.json());{
"code": 200,
"message": "success",
"data": {
"task_id": "vid_task_01JEXAMPLE"
}
}Kling 3.0 Turbo Image to Video
Kling 3.0 Turbo I2V is APIPod’s first-frame image-to-video mode for Kling 3.0 Turbo, the faster Kling 3.0 tier that always generates native audio.
curl https://api.apipod.ai/v1/videos/generations \
-H "Authorization: Bearer $APIPOD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}'import os
import requests
payload = {
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}
response = requests.post(
"https://api.apipod.ai/v1/videos/generations",
headers={
"Authorization": f"Bearer {os.environ['APIPOD_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json())package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body := []byte(`{
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}`)
req, err := http.NewRequest(http.MethodPost, "https://api.apipod.ai/v1/videos/generations", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("APIPOD_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(out))
}use reqwest::Client;
use serde_json::json;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let payload = json!({
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
});
let response = Client::new()
.post("https://api.apipod.ai/v1/videos/generations")
.bearer_auth(env::var("APIPOD_API_KEY")?)
.json(&payload)
.send()
.await?
.error_for_status()?;
println!("{}", response.text().await?);
Ok(())
}const response = await fetch("https://api.apipod.ai/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.APIPOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"model": "kling-3.0-turbo-i2v",
"prompt": "The barista pours latte art and smiles at the camera.",
"image_urls": [
"https://cdn.example.com/first-frame.jpg"
],
"duration": 5,
"resolution": "1080p"
}),
});
if (!response.ok) {
throw new Error(`APIPod request failed: ${response.status} ${await response.text()}`);
}
console.log(await response.json());{
"code": 200,
"message": "success",
"data": {
"task_id": "vid_task_01JEXAMPLE"
}
}Usage notes
- First frame: pass exactly one image in
image_urls; last frames are not supported. The output aspect ratio follows the image. - Multi-shot: describe up to 6 shots in
multi_prompt({prompt, duration}, up to 512 characters each). Shot durations must add up to exactlyduration(3-15 seconds).multi_shotis not accepted. - Audio: native audio is always generated;
generate_audio: falseis rejected. - Not supported:
negative_prompt(write exclusions into the prompt),audio_urls, andvideo_url(usevideo_urls).
Billing
Billed per second of output video. The per-second rate depends on the resolution (720p or 1080p); native audio is always included. Current prices are shown on the model page.Task flow
The create call returnsdata.task_id. Poll Query video task until status is completed (outputs in data.result) or failed, or pass callback_url to be notified when the task reaches a terminal state.Authorizations
Use your APIPod API key as a Bearer token in the Authorization header.
Body
Public APIPod model ID.
"kling-3.0-turbo-i2v"Exactly one first-frame image URL. Last frames are not supported. first_frame_image is accepted as an alias. The aspect ratio follows the image.
1 elementText prompt describing the motion, up to 2,500 characters. Required unless multi_prompt is provided.
2500Output duration in seconds (3-15). Defaults to 5. With multi_prompt, the shot durations must add up to exactly this value; when omitted it defaults to the sum of the shot durations.
3 <= x <= 15Output resolution. Defaults to 720p. The per-second rate depends on the resolution.
720p, 1080p Shot list for multi-shot generation, up to 6 shots. Each shot is {prompt, duration} with a prompt of up to 512 characters; the shot durations must add up to duration (3-15 seconds).
6Show child attributes
Show child attributes
When true, an additional watermarked copy is generated and the watermarked copy is returned as the result.
HTTPS URL that receives the task's terminal state.
Was this page helpful?