Kling O3 · Image to Video
Animate one still, and keep an eye on the meter
- image_url
- last_image_url
- video
- task id
The short version
Kling O3 is Kling 3.0 Omni, and it has no weights you can download. That is the whole reason this node exists: it's the only door Kling gets into your graph, and it doesn't care whether you own a GPU. Feed it one image, get back a 3-to-15 second clip with the aspect ratio inherited from your frame, optionally with a native soundtrack and hand-off cuts between shots.
If you've been animating locals - Wan, LTX, whatever's on your disk - think of this as the paid shot. You draft ten versions locally for free, then spend real money on the one that matters. Or you skip the drafting, because some things simply aren't on the open side of the fence.
What it actually does when you hit Run
It doesn't run a model. It builds a request from your widgets, uploads your opening frame to SpicyAPI, asks for a price quote, submits the job, polls it, then downloads the finished MP4 and hands it back as an ordinary ComfyUI VIDEO - the kind Save Video writes to your output folder.
Two implementation details worth knowing, because they're where the friction lives. Your frame is re-encoded as PNG, and if the PNG blows past the 10 MiB upload ceiling the node falls back to JPEG at descending quality before giving up entirely - so a 6000px photograph may get rejected with a "scale it down first" error. Uploads are also cached per account by content hash for twelve hours, so re-running the same graph with a new prompt doesn't re-send the same picture.
The inputs that matter
The only ones you must touch:
- prompt - what happens after the frame. The action, the camera, and if you turned sound on, the sounds. Everything else about the image is already decided by the image.
- image_url - your opening frame. Not a directory name, an actual IMAGE socket; wire
Load Imageinto it. - resolution and duration_seconds (3–15) - these two are the bill. The rate is per second of output (from $0.0672), higher tiers cost more per second, and the node's badge updates live as you change them. A 5-second 720p run and a 15-second 4K run are not in the same tax bracket.
- generate_audio - off by default, and turning it on raises the per-second rate. Native sound (voices, effects, ambience) rather than a separate pass.
The rest: shot_type stays on single unless you want the model cutting for you - multi lets it split your prompt into several shots itself, and customize makes it follow the list you type into multi_prompt, one JSON object per shot with its own duration_seconds and prompt, whose lengths have to add up to duration_seconds. last_image_url is optional and does exactly what it says: pin the ending, which is how you close a loop or land on a specific still.
Outputs are video (wire it to Save Video) and task id, a plain string. Keep the task id when something goes wrong - it identifies the request exactly, on the console and for support.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/spicyapi-ai/comfyui-spicyapi
Restart ComfyUI. There is nothing else to install - no requirements.txt, no pip step, no model download. Then open Settings > SpicyAPI, paste a key from spicyapi.ai/console/keys, and restart once more so your node list is rebuilt from your account. On a headless box, set SPICY_API_KEY in the environment instead. It wants the V3 node API, so a reasonably current ComfyUI (the pack is tested on 0.39) and Python 3.10+.
Where people get burned
You can't re-roll it. There's no seed input on this node, and Kling doesn't expose one. Get a clip you love and you cannot reproduce it - download it and move on. Which also means "just run it again to see" is a purchase, not a preview.
The queue button is not free. With no seed to change and no input changed, ComfyUI's own caching stops a re-queue from costing you anything. Change the prompt by one word and you've bought another generation. Set Max cost per run in the settings panel before you start experimenting; a run quoted above that ceiling stops before anything is charged.
Cancelling doesn't cancel. Hitting cancel stops you waiting; the job keeps running on SpicyAPI, gets charged if it succeeds, and sits in your console for up to 14 days. If you bailed because it looked expensive, it is still expensive.
A combination no deployment serves comes back as code 40004 naming the offending option - usually an exotic resolution/duration/audio mix. 40310 means your email isn't verified yet. Both are in the README's troubleshooting table for a reason. And if you see No SpicyAPI key is set, the key either isn't saved or you're in a different ComfyUI user directory than the one you typed it into.
Reach for this one when you need Kling specifically and you need it in the graph, next to your local tools. It's a metered call to a model you were never allowed to download, and it's honest about the price on the node.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | Describe what happens after the opening frame: the action, the camera and, with sound on, the sounds. | |
| image_url | IMAGE | Opening frame. The clip starts from this image. | |
| resolution | COMBO | 720p | Output resolution. Higher tiers cost more per second. |
| generate_audio | BOOLEAN | false | Generate a native soundtrack (voices, effects, ambience) with the picture. Audio costs more per second. |
| duration_seconds | INT | 53–15 | Output length in whole seconds, from 3 to 15. Billed per second. |
| shot_type | COMBO | single | single keeps one continuous shot; multi lets the model cut the prompt into several shots on its own; customize follows the shot list you give in multi_prompt. |
| multi_prompt | STRING | Shot list for shot_type customize: one entry per shot, in order, each with its own prompt and length in seconds. The lengths must add up to duration_seconds. JSON. A list of objects with "duration_seconds", "prompt". | |
| seed | INT | 00–2147483647 | This model takes no seed, so the number is never sent. Changing it makes ComfyUI run the node again: set 'control after generate' to randomize for a new result on every run; every run is billed. |
| last_image_urlopt | IMAGE | Optional closing frame the clip should end on. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| task id | STRING | The SpicyAPI task id, for the console logs or support. |