Animate a picture with Kling 3 via API: Python first-frame request

To animate one picture with Kling 3 on Sume, send it as a first_frame in frame_images to POST /v1/videos with model kling-3. Full Python script included.

5 min readSume
All posts

How do I animate a still image with Kling 3 through Sume?

Post the image URL as a first frame. Set model to kling-3, put the picture in frame_images with frame_type set to first_frame, describe the motion in prompt, and poll the returned job until it is completed.

Kling's blog listed a how-to titled "How to Animate a Picture with AI in Four Steps" on September 30, 2026. This post is the API-side version of the same job: one picture, one motion prompt, one clip.

What does the request need?

Five things matter, and the catalog enforces them. The image must be a public HTTPS URL. The duration must be a whole number from 4 to 15. The aspect ratio must be 16:9, 9:16 or 1:1. The resolution must be 720p or 1080p. Audio is optional through generate_audio.

The picture is the first frame, so it fixes the subject, outfit and framing. The prompt should therefore describe only what moves.

kling-3 first-frame request fields (read 2026-10-03)
FieldValue for this jobRule
modelkling-3Bare catalog id, no provider prefix
frame_imagesOne first_frame entryPublic HTTPS image URL
duration5Whole seconds, 4 to 15
resolution720p720p or 1080p
aspect_ratio16:916:9, 9:16 or 1:1
generate_audiofalseOptional boolean

What does the Python script look like?

This version uses async HTTP and polls every 30 seconds, the interval the docs suggest. It stops with a message when the key is missing and prints the content URL when the job completes. Download the file with the same bearer token.

import asyncio, os, sys
import httpx

async def main():
    key = os.environ.get("SUME_API_KEY")
    if not key:
        sys.exit("set SUME_API_KEY")
    body = {
        "model": "kling-3",
        "prompt": "The woman turns to the window and smiles, slow push-in",
        "frame_images": [{
            "type": "image_url",
            "image_url": {"url": "https://example.com/photo.png"},
            "frame_type": "first_frame",
        }],
        "duration": 5, "resolution": "720p", "aspect_ratio": "16:9",
        "generate_audio": False,
    }
    headers = {"Authorization": f"Bearer {key}", "Idempotency-Key": "animate-photo-001"}
    async with httpx.AsyncClient(headers=headers, timeout=60) as c:
        r = await c.post("https://api.sume.com/v1/videos", json=body)
        r.raise_for_status()
        poll = r.json()["polling_url"]
        while True:
            await asyncio.sleep(30)
            s = (await c.get(poll)).json()
            if s["status"] in ("completed", "failed", "canceled"):
                break
    print(s["status"], s.get("unsigned_urls") or s.get("error"))

asyncio.run(main())

What goes wrong most often?

A picture that is not publicly reachable is the usual cause of a failed job, and the docs say reference images must be accessible over public HTTPS. A second cause is sending the picture as input_references: kling-3 takes no references, so that field returns a 400 unsupported_capability, covered in the input_references fix.

A third cause is a mismatched aspect ratio. If the picture is portrait and you ask for 16:9, say so in your plan; pick 9:16 for portrait pictures, since kling-3 offers 16:9, 9:16 and 1:1 only.

When is Kling 3 the wrong tool for this?

If you want to move a person by copying motion from another video, that is a different product, motion control. If you need a clip longer than 15 seconds from one picture, use seedance-2.5, which accepts 4 to 30 seconds. Sume makes no promise about how faithfully any model keeps the picture's details over the full clip, so look at the last frame before you ship it. The reserve on submit is the provider list price times 1.25, and usage.cost on the finished job is the Sume billable amount.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume