how-tos

Kling 4.0 API Guide: Your First Video with Python and cURL

PoYo Team
5 min read
Share:

A projectionist threading a film projector, an editorial illustration

The Kling 4.0 API on PoYo uses one model ID, kling-4.0, for text-to-video, first/last-frame generation, visual references, and video editing. Submit a request, retain its task ID, and poll until the task finishes. This guide follows PoYo's current schema, checked on October 24, 2026; another provider's field names are not interchangeable.

Open the Kling 4.0 playground to try the inputs visually, or consult the API documentation.

Generate a first video with cURL

Set POYO_API_KEY in your shell environment, then submit this five-second request. Keep the credential on your server rather than in browser code.

curl --fail-with-body https://api.poyo.ai/api/generate/submit \
  -H "Authorization: Bearer $POYO_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "kling-4.0",
    "input": {
      "prompt": "A paper boat floats beneath a stone bridge. One continuous low tracking shot, soft morning light, gentle water sounds, no speech or on-screen text.",
      "duration": 5,
      "resolution": "720p",
      "aspect_ratio": "16:9"
    }
  }'

Read data.task_id from the JSON response; a successful submission is not a finished video. Replace YOUR_TASK_ID below with that value:

curl --fail-with-body \
  https://api.poyo.ai/api/generate/status/YOUR_TASK_ID \
  -H "Authorization: Bearer $POYO_API_KEY"

The documented statuses are not_started, running, finished, and failed. Once finished, inspect data.files for a video file_url. On failure, inspect error_message and preserve the task ID for diagnosis. Polling an existing task does not require submitting it again.

A bounded Python polling loop

Install requests and run this on your backend. It checks both HTTP and application errors, stops on a failed task, and limits the wait to 30 minutes. A timeout means check the same task later; automatically repeating the submission could create a second billable job.

import os
import time
import requests

base = "https://api.poyo.ai"
session = requests.Session()
session.headers["Authorization"] = "Bearer " + os.environ["POYO_API_KEY"]

def checked(response):
    response.raise_for_status()
    body = response.json()
    if body.get("code") not in (0, 200):
        raise RuntimeError(body.get("message") or "PoYo API error")
    return body["data"]

task = checked(session.post(base + "/api/generate/submit", json={
    "model": "kling-4.0",
    "input": {
        "prompt": "A paper boat floats beneath a stone bridge. Slow tracking shot.",
        "duration": 5,
        "resolution": "720p",
        "aspect_ratio": "16:9",
    },
}, timeout=60))
task_id = task["task_id"]
print("Task:", task_id, flush=True)
deadline = time.monotonic() + 1800
while time.monotonic() < deadline:
    task = checked(session.get(
        base + "/api/generate/status/" + task_id, timeout=60))
    if task["status"] == "failed":
        raise RuntimeError(task.get("error_message") or "Generation failed")
    if task["status"] == "finished":
        videos = [f["file_url"] for f in task.get("files", [])
                  if f.get("file_type") == "video"]
        if not videos:
            raise RuntimeError("Finished task returned no video")
        print(videos[0])
        break
    time.sleep(10)
else:
    raise TimeoutError("Check the saved task ID again: " + task_id)

Choose the correct input mode

GoalFields inside inputImportant constraint
Text-to-videoprompt or multi_promptSupply exactly one
First/last framesimage_urls with one or two ordered URLsOmit aspect_ratio
Reference generationreference_image_urls, reference_video_urls, or kling_elementsAt most one optional first frame
Edit footagevideo_url and promptNo image_urls, multi_prompt, reference_video_urls, or aspect_ratio

The source-video field selects editing even if reference images are also present. For image-to-video, the first image establishes the starting frame; a second image defines the ending frame. Reference images guide identity or style and do not mean the same thing as boundary frames.

Limits worth validating before submission

Generation supports integer durations from 3 to 30 seconds, at 720p or 1080p. A normal prompt is limited to 26,000 characters in this PoYo schema. Each multi_prompt shot accepts up to 512 characters; omitted shot duration defaults to five seconds. Shot durations must total 3–30 seconds, and an explicit top-level duration must equal that total.

References allow up to 10 images, five videos, and seven subjects, within a combined limit of 15 assets. A first frame counts toward both the image and overall limits. Each reference or subject video must be 3–30 seconds; their combined real duration cannot exceed 30 seconds. Do not round durations down to make an oversized input pass validation.

Understand the first bill

A five-second 720p request without video input is 142.5 credits, or $0.7125 at the current listed conversion. A video input changes both the rate and billable duration. See the pricing examples before estimating a reference-video or editing workflow.

The official creator product advertises additional controls, including multiple keyframes. PoYo's schema here exposes up to two boundary frames and per-shot prompts; do not send invented keyframes, seed, negative_prompt, or generate_audio fields to this endpoint. For working examples, continue with the prompt guide and Omni Reference tutorial.

Frequently asked questions

Is the API model ID kling-4-0? No. That is the page slug. The request model ID is kling-4.0.

Can I request 4K here? This PoYo endpoint currently accepts only 720p and 1080p. Check the provider schema rather than copying creator-app marketing specifications.

Can I use a callback? The submit request supports a top-level callback_url. Consult the current documentation for callback handling; the polling example above does not depend on it.

Where do I start? Use a short text-only request first, save its task ID and result, then add one input modality at a time in the playground.

Share: