BytePlus Create Image Asset
Register a face once, reuse it in every Seedance shot
- image
- asset_id
- group_id
- asset_uri
- info
Everybody building a character with an API video model hits the same wall eventually: the model has no memory. Shot 1 looks like your character, shot 3 looks like her cousin. Reference conditioning is the fix - but Seedance 2.0/2.5 will only take a reference as a URL or as an asset, and local files aren't URLs. This node is how a picture on your disk becomes something Seedance can point at.
It uploads an image to your BytePlus private asset library and hands back an asset_id. Once it exists, every later workflow can reference it without touching the image again. That's a genuinely different workflow shape from "load the PNG again and hope the node uploads it the same way."
How it works
BytePlus's CreateAsset API takes an HTTPS URL, so connected images get uploaded to Comfy.org storage first (that needs a Comfy.org login; a public image_url skips the upload entirely). The image then lands in an asset group, BytePlus processes it, and the node waits - up to ten minutes - until the asset reports Active. Only then is it something Seedance will accept.
Re-running with the same image reuses the existing asset rather than duplicating it, which is the behaviour you want if you left this node wired into a character workflow that you run daily.
Inputs and outputs
image(optional) is the picture to register.image_urlis the escape hatch: a public HTTPS link that goes straight to CreateAsset with no Comfy.org round trip. One or the other, not both.group_idandgroup_namedecide which pile the asset joins. Leavegroup_idempty and the node finds or creates the virtual-portrait (AIGC) group namedgroup_name(defaultComfyUI Virtual Portraits). Use one group per person - that's how the IDs stay sane.asset_nameis just a label.project_nameis the ModelArk project holding the library.wait_until_activeis the one I'd leave on; turning it off gets you an ID back sooner, but if you try to use it before it's Active the generation fails and you'll blame the wrong node.- Outputs:
asset_id,group_id,asset_uri(asset://<asset_id>, for inputs that take URIs) andinfo, the raw asset JSON. Wireasset_idinto anasset_Ninput on BytePlus Seedance 2.5 Reference to Video, or intofirst_frame_asset_id/last_frame_asset_idon the first-last-frame node.
BytePlus's own limits on the uploaded image are worth knowing before you blame the node: min edge 300 px, max edge 6000 px, aspect ratio between 2:5 and 5:2.
Install and credentials
cd ComfyUI/custom_nodes
git clone https://github.com/byteplus-sa/ComfyUI-BytePlus-ModelArk
pip install -r ComfyUI-BytePlus-ModelArk/requirements.txt
Restart ComfyUI afterwards (ComfyUI 0.31.0 or newer), or install from Manager by searching BytePlus ModelArk. You need three things switched on: the ModelArk API key in Settings → BytePlus, IAM AK/SK with asset-library permission, and Dreamina Seedance Advanced Creation Rights on the account. In user/.env that's BYTEPLUS_API_KEY, BYTEPLUS_ACCESS_KEY and BYTEPLUS_SECRET_KEY.
Where people get burned
The Comfy.org login requirement is the classic stumble. Connect an image and the node tries to upload it to Comfy.org storage; no login, no upload, no asset. If you'd rather not log in, host the image somewhere public and use image_url instead.
Then there's the identity of the thing you're registering. This library is for authorized media - your own virtual portraits, or real people who passed BytePlus's console-side verification (a QR-code flow with no API, so this node can't start it). Verified real people live in a LivenessFace group; create that in the ModelArk console and paste its group_id here. If you just want a generic reference image for asset_N, you don't need this node at all - Seedance's asset_N inputs accept plain HTTPS links.
One more: CreateAsset is rate-limited per account tier (3, 120 or 300 requests/minute on Entry, Advanced and Premium), so a loop that registers a hundred frames will get throttled long before it finishes. Registering one good portrait per character is the intended use.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| group_id | STRING | Reuse an existing asset group ID to add more assets of the same person: a virtual portrait (AIGC) group, or a verified real person's LivenessFace group. Leave empty to find or create the virtual portrait (AIGC) group named group_name. Real-person verification is a QR-code flow in the ModelArk console (BytePlus has no API for it), so unlike ComfyUI core's node this node does not start it: verify the person in the console, then paste the group ID here. | |
| image_url | STRING | Public HTTPS URL of the image, used instead of the image input: sent straight to CreateAsset without a Comfy.org upload. | |
| group_name | STRING | ComfyUI Virtual Portraits | Used when group_id is empty: the virtual portrait (AIGC) group, matched by exact name and created if missing. Use one group per person. |
| asset_name | STRING | ComfyUI portrait | Name of the new asset. |
| project_name | STRING | default | ModelArk project that holds the asset library. |
| wait_until_active | BOOLEAN | true | Wait (up to 10 min) until the asset is Active and can be used in Seedance. |
| imageopt | IMAGE | Image to register as a personal asset. Leave unconnected to use image_url instead. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| asset_id | STRING | — |
| group_id | STRING | — |
| asset_uri | STRING | asset://<asset_id>, for inputs that take URIs. |
| info | STRING | The asset as JSON. |