Tutorial
Kling AI Image-to-Video API in Python
Copy a working Python task runner, choose the current Omni or Turbo model ID, and verify schema and live pricing before you generate.
Use the Kling AI image-to-video API in Python through HiAPI's async task endpoint. The quick start below uses the current callable kling-3.0-omni/image-to-video model ID, polls the task to a terminal state, and downloads the generated MP4.
For exact fields, keep the Kling 3.0 Omni image-to-video API docs open. Use the current Omni model page to inspect the model and Playground, and check live Kling API pricing before a production run.
Quick start: run Kling image-to-video in Python
Install requests with python -m pip install requests, set HIAPI_API_KEY in your environment, and replace IMAGE_URL with a public JPEG, PNG, or WebP URL. The complete script is the first copyable code block:
import os
import time
from pathlib import Path
import requests
API_BASE = "https://api.hiapi.ai/v1"
API_KEY = os.environ["HIAPI_API_KEY"]
IMAGE_URL = "https://cdn.example.com/first-frame.jpg"
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {
"model": "kling-3.0-omni/image-to-video",
"input": {
"image_urls": [IMAGE_URL],
"prompt": "The camera slowly pushes in as leaves move in a light breeze",
"duration": 5,
"resolution": "1080p",
"sound": False,
},
}
created = requests.post(
f"{API_BASE}/tasks",
headers=HEADERS,
json=payload,
timeout=30,
)
created.raise_for_status()
task_id = created.json()["data"]["taskId"]
deadline = time.time() + 900
while time.time() < deadline:
response = requests.get(
f"{API_BASE}/tasks/{task_id}",
headers=HEADERS,
timeout=30,
)
response.raise_for_status()
task = response.json()["data"]
if task["status"] == "success":
output_url = task["output"][0]["url"]
break
if task["status"] == "fail":
raise RuntimeError(task.get("error") or f"Task {task_id} failed")
time.sleep(8)
else:
raise TimeoutError(f"Task {task_id} did not finish within 15 minutes")
with requests.get(output_url, stream=True, timeout=180) as download:
download.raise_for_status()
with Path("kling-output.mp4").open("wb") as video:
for chunk in download.iter_content(1024 * 1024):
if chunk:
video.write(chunk)
print("Saved kling-output.mp4")
The create request returns a taskId; it does not wait for the video. The script polls GET /v1/tasks/{taskId}, stops on success or fail, and downloads the first output promptly because result URLs expire.
Open the Kling Omni model and try this payload.
Choose the current Kling image-to-video model
| Model ID | Use it when | Input and output contract |
|---|---|---|
kling-3.0-omni/image-to-video |
You need first/last-frame control, optional native sound, or 4K | One or two public image URLs; 3-15 seconds; 720p, 1080p, or 4K |
kling-3.0-turbo/image-to-video |
One starting frame and a smaller 720p/1080p schema fit the job | Exactly one public image URL; required prompt; 3-15 seconds; 720p or 1080p |
Omni's full field reference is in the Omni I2V docs. Turbo has a separate Turbo I2V schema reference. Both use the same /v1/tasks create and polling workflow, so keep one runner and swap only model and input.
Model-accurate request bodies
Omni with first and last frames
Send one URL for a first frame or two URLs in [first, last] order:
{
"model": "kling-3.0-omni/image-to-video",
"input": {
"image_urls": [
"https://cdn.example.com/first-frame.jpg",
"https://cdn.example.com/last-frame.jpg"
],
"prompt": "The camera arcs around the subject as the light changes from dawn to noon",
"duration": 8,
"resolution": "1080p",
"sound": true
}
}
Omni accepts one or two image_urls. Its prompt is optional, duration is an integer from 3 through 15, resolution is 720p, 1080p, or 4K, and sound is optional.
Turbo with one starting frame
{
"model": "kling-3.0-turbo/image-to-video",
"input": {
"prompt": "The subject turns toward the camera while leaves move in a light breeze",
"image_urls": ["https://cdn.example.com/first-frame.jpg"],
"duration": 8,
"resolution": "1080p"
}
}
Turbo requires a prompt and exactly one image_urls entry. Do not send Omni-only fields such as sound, and do not add text-to-video fields such as aspect_ratio; the source image defines the frame.
Kling AI pricing: use the live tier, not a copied price
Kling AI pricing on HiAPI is usage based. Both current image-to-video models are billed per generated second, with the exact rate selected by model and resolution; Omni also has different audio-on tiers. A longer clip, a higher resolution, or native audio can change the task cost.
Rates can change, so this guide does not freeze a dollar table. Check the live model pricing table immediately before budgeting or submitting a large batch.
Is Kling AI free?
No: Kling image-to-video API generation is not an unlimited free API on HiAPI. A successful task consumes balance at the live rate for the selected model, duration, resolution, and audio setting. Account promotions or starter rewards may change and may have conditions, so do not treat them as a guaranteed Kling free tier; verify the current offer and your balance in the account before submitting a task.
Production checks that prevent failed or duplicate tasks
- Use a directly downloadable HTTPS image URL. Localhost, login-protected pages, HTML share pages, and expired signed URLs can fail after task creation.
- Store
taskIdbefore retrying a worker. Retrying the create call can create and bill a second task. - Treat
successandfailas terminal states. In production, use a top-levelcallback.urland keep polling as a reconciliation fallback. - Download
output[].urlpromptly and copy long-lived results into storage you control. - Validate the selected model's schema before sending. Unknown fields are rejected by strict model contracts.
Common errors
- HTTP 400: the request did not match the schema, so inspect the named field, enum value, array length, and JSON type.
- HTTP 401: the bearer key is missing, invalid, or cannot use the selected model.
- Task reaches
fail: creation passed validation, but the renderer could not fetch the input or complete generation. Log thetaskIdand returned error separately from the create response. - Output URL expired: the render may have succeeded; the temporary pickup URL was not downloaded in time.
FAQ
Which Kling image-to-video model should I use in Python?
Use kling-3.0-omni/image-to-video for one- or two-frame control, optional native sound, or 4K. Use kling-3.0-turbo/image-to-video when one starting frame and 720p/1080p output meet the requirement. The Python create, poll, and download code stays the same.
What is the current Kling AI image-to-video model ID?
The current callable IDs covered here are kling-3.0-omni/image-to-video and kling-3.0-turbo/image-to-video. Send either ID in the top-level model field of POST /v1/tasks.
How many images can Kling image-to-video accept?
Omni accepts one image for the first frame or two in [first, last] order. Turbo accepts exactly one starting-frame image.
How much does the Kling AI API cost?
It is billed per generated second. The exact live rate depends on the model and resolution, plus the audio setting for Omni. Use the live pricing page instead of copying a static price from this guide.
Is Kling AI free to use through the API?
No unlimited Kling API free tier is promised. Generation uses account balance at the live task rate. Check the account for any current, conditional starter offer rather than assuming a fixed free allowance.
Why did my task fail after the create request succeeded?
The JSON passed initial validation, but the renderer may have been unable to fetch the image or finish generation. Confirm that the image is public and unexpired, then inspect the terminal error for the stored taskId.
How do I get the generated video?
Read data.taskId from the create response. Poll GET /v1/tasks/{taskId} for local scripts or use callback.url in production. On success, download data.output[0].url before it expires.
Continue with the complete Kling Omni API reference, then open the current model page when you are ready to test the request.
Related articles
View all articles →-
Tutorial
How to Call hailuo-2.3-fast/image-to-video via the HiAPI API: curl and Python
A first working request for the fast, low-cost image-to-video tier — from model ID to downloaded MP4
9 min read -
Tutorial
How to Use hailuo-2.3/text-to-video via the HiAPI API: curl, Python, and a Working Request
11 min read -
Tutorial
Kandinsky 6.0 Pro Text-to-Video on HiAPI: curl and Python Tutorial
A request-first walkthrough: build the prompt-to-clip call, submit it, poll for completion, and download the result
11 min read