Hailuo 2.3 Standard Image to Video
The iterate-cheaply tier of the same model
- image_url
- video
- url
- all_urls_json
- task_id
- raw_json
- credits_consumed
- credits_left
If the Pro node is the one you ship with, this is the one you iterate with. Same model family, same interface, lower tier - the classic draft/final split, except the draft costs money too, just less of it. Wire it next to Hailuo 2.3 Pro, queue ten takes here, and only send the keeper up the ladder.
How it works
It's an API node, not a local model. Your still image is uploaded to KIE, a task is created on /api/v1/jobs/createTask, the node polls until the job reports success, downloads the MP4, and returns it as a ComfyUI VIDEO. Nothing touches your GPU, nothing lands in models/, and your prompt plus your image leave the machine - same privacy math as every other hosted-model node in the ecosystem, and the reason the local-first crowd reads this whole category with a raised eyebrow.
Why you'd still do it: Hailuo has no downloadable weights. There's no path to running it locally at any VRAM, so the choice isn't "local vs cloud," it's "hosted or nothing." Use it for the shots that need motion quality you can't coax out of Wan 2.2, and keep it off the critical path where a local model will do.
Inputs that matter
prompt (required, up to 5000 characters) is about motion, not appearance. Describe the action, the camera, and the pace; the image has already settled what things look like.
image_url (required) is the IMAGE socket - any node that outputs an image plugs in here, and the pack handles the upload.
resolution (768P default, or 1080P) and duration (6 or 10) are the two cost dials. They interact: 10-second output is not available at 1080P, per the node's own help text. Longer and sharper is not an option; pick one.
nsfw_checker defaults to false, which disables KIE's own filtering - the results come straight from the model. That is not a licence, and it's not a guarantee of anything.
timeout_seconds (default 1200, range 30–7200, in 30-second steps) is the polling budget. Drop it to a few hundred seconds if you're running a batch and would rather fail fast than wait twenty minutes per clip. callback_url stays empty for normal ComfyUI use.
There's no seed, so you can't reproduce a clip you liked - save the file and keep going.
Outputs
video for downstream nodes. Then url, all_urls_json, task_id, raw_json, and credits_consumed / credits_left as floats, so you can log spend per take instead of guessing. The node displays the same numbers as a "Credits spent • Credits left" receipt after each run.
Generated files are archived to ComfyUI/output/KIE-Results/videos/.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/felipederosilva/ComfyUI-KIE-Nodes-Next
cd ComfyUI-KIE-Nodes-Next
pip install -r requirements.txt
Restart, then set the key once under Settings → KIE.ai Nodes Next → Connection. The pack validates the key against KIE before saving, shows only a masked fingerprint afterwards, and keeps the full key out of your workflow JSON. Servers and Docker can use KIE_API_KEY instead, and that variable takes priority over anything saved in the UI - remember it when you rotate keys.
The whole pack is four small Python dependencies (requests, Pillow, numpy, PyYAML) and no model downloads. There's a one-click Windows installer in dist/ if you don't want to touch a shell.
Troubleshooting
"KIE model ID has not been resolved yet. Refresh the live catalog once." The pack generates its nodes from KIE's documentation; if the first catalog sync didn't complete, that node can't submit. Run the Catalog Sync node and reload the page.
A rerun of the exact same graph submits nothing - ComfyUI cached the node's output, so no second charge. To actually re-roll, change the prompt or the input image.
Timeout errors aren't free. The job continues on KIE's side and the credits are spent. Pull task_id from the message and check it with the Task Status utility node.
1080P + 10 seconds fails after upload. Not a bug, a documented exclusion. Also check the image itself: KIE wants at least 300px on the short side, under 10MB, and an aspect ratio no wider than about 2.5:1.
One more practical note. Because there's no seed, "same prompt, same image, run it again" is a different clip - which is exactly what you want while hunting for a good take, and exactly what you don't want when a client asks for the version they approved on Tuesday. Save the MP4s.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | Two armored medieval knights clash in an intense duel at sunset, cinematic lighting. Metal armor reflects warm golden light from the sun and the glowing swords. Sparks explode as the swords collide. Dynamic camera movement, shallow depth of field, dramatic slow motion. The scene takes place in an open desert battlefield, dust in the air, warm orange sun behind them, epic atmosphere. Highly detailed armor textures, realistic reflections, volumetric lighting, cinematic quality. | Text prompt describing the desired video animation (Max length: 5000 characters) |
| image_url | IMAGE | — | |
| durationopt | COMBO | 6 | The duration of the video in seconds. 10 seconds videos are not supported for 1080p resolution. |
| resolutionopt | COMBO | 768P | The resolution of the generated video. |
| nsfw_checkeropt | BOOLEAN | false | Defaults to false. You can set it to false based on your needs. If set to false, our content filtering will be disabled, and all results will be returned directly by the model itself. Note: There is no guarantee that everything can be filtered out; if you are not satisfied with the results, you will need to make your own arrangements. |
| timeout_secondsopt | INT | 120030–7200 | — |
| callback_urlopt | STRING | Optional KIE callback URL. Leave empty for normal ComfyUI use. |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| url | STRING | — |
| all_urls_json | STRING | — |
| task_id | STRING | — |
| raw_json | STRING | — |
| credits_consumed | FLOAT | — |
| credits_left | FLOAT | — |