Kling Elements
Lock a character across scenes before you animate
- image
- element_refer_images
- client
- element_id
Character consistency across video scenes is the hardest problem in this space, and Kling's answer is elements: a reusable identity anchor - a character, a style, a scene - that you create once and reference in later generations. This node creates one. You feed it a name, a description, and reference images, and it returns an element_id that the Kling video nodes can consume so your character looks like the same person in scene two as in scene one.
It runs through the WaveSpeed API (the pack's reseller access to Kling), so the flow is: create the element here → keep the element_id → feed it into the Kling i2v/t2v Pro nodes via their element_list input. The element persists server-side; the element_id is your handle to it.
Inputs
- name - required, max 20 characters. The identity label ("Detective Mara").
- description - required, max 100 characters. What makes this element distinctive; this is what generation uses to stay consistent.
- image - a ComfyUI
IMAGEtensor for the front reference. Preferred - takes precedence over the URL when connected. Source should be ≥300px and ≤10MB after encoding. - image_url - fallback when
imageisn't connected. One of the two is required. - element_refer_images - batch of 1–3 extra reference images (different angles), preferred over the URL list.
- element_refer_url_list - JSON array of 1–3 extra reference URLs, used only when the tensor input is unconnected.
- voice_id - optional; binds an existing voice/tone to the element.
- tag_list - optional JSON array of organizing tags.
- seed - cache control only, not sent to the API (the tooltip is explicit): randomize = re-create the element each queue; fixed = reuse the cached
element_id. - client - optional; WaveSpeed key from Settings if unconnected.
Output: element_id - a STRING to keep and feed into Kling video nodes.
Install and gotchas
Part of the ERPK Collection:
cd ComfyUI/custom_nodes
git clone https://github.com/eRepublik-Labs/comfyui-nodes-erpk.git erpk
cd erpk && pip install -r requirements.txt
Restart (or ComfyUI Manager → search erpk), WaveSpeed key in Settings > ERPK > API Keys. Creating an element is a paid API call, and recreating one every queue (randomized seed) is how that bill sneaks up - fix the seed once you're happy, so ComfyUI serves the cached element_id.
Three gotchas to name. One: both name and description are enforced non-empty - the node raises rather than silently accepting a blank identity. Two: a front reference is mandatory in some form, tensor or URL; no image, no element. Three: the reference inputs are "tensor OR URL" pairs, and the pack consistently prefers the tensor - if you're wiring a URL and an image, the image wins, so don't bother with both. If your video output keeps drifting from the character, the description is almost always the culprit - the more concrete it is, the tighter Kling holds the identity.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| name | STRING | Element name (max 20 characters) | |
| description | STRING | Element description (max 100 characters) | |
| imageopt | IMAGE | Front reference image as a ComfyUI IMAGE tensor. Preferred — takes precedence over `image_url` when connected. Source should be ≥300px and ≤10MB after encoding. | |
| image_urlopt | STRING | Front reference image URL. Fallback when the IMAGE input is not connected. | |
| element_refer_imagesopt | IMAGE | Batched IMAGE tensor of 1-3 additional reference images. Preferred over `element_refer_url_list` when connected. | |
| element_refer_url_listopt | STRING | JSON array of 1-3 additional reference image URLs. Used only when `element_refer_images` is not connected. | |
| clientopt | WAVESPEED_AI_API_CLIENT | WaveSpeed API client (optional if API key is configured in Settings) | |
| voice_idopt | STRING | Bind an existing voice/tone to this element | |
| tag_listopt | STRING | JSON array of tags for organizing the element | |
| seedopt | INT | -1-1–2147483647 | Cache control: randomize re-creates the element each queue; a fixed value reuses the cached element_id. This endpoint has no seed parameter, so it is not sent to the API. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| element_id | STRING | — |