Copy a working Python task runner, choose the current Omni or Turbo model ID, and verify schema and live pricing before you generate.
Choose a model, enter your prompt, and see the result.
HiAPI Blog
HiAPI
Generate it with HiAPI
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.
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.
| 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.
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.
{
"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 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.
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.
taskId before retrying a worker. Retrying the create call can create and bill a second task.success and fail as terminal states. In production, use a top-level callback.url and keep polling as a reconciliation fallback.output[].url promptly and copy long-lived results into storage you control.fail: creation passed validation, but the renderer could not fetch the input or complete generation. Log the taskId and returned error separately from the create response.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.
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.
Omni accepts one image for the first frame or two in [first, last] order. Turbo accepts exactly one starting-frame image.
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.
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.
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.
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.