Veo Edit Objects (Ace Data Cloud)
Add or erase something, if you can host the mask
- status
- task_id
- video_url
- trace_id
Most video cleanup is a compositor job - paint a mask, track it, hope the tracker doesn't slide. Edit Objects is the "let the model handle it" version: hand Veo a video and either an object to add or a region to erase, and get a re-rendered clip back. It's one of the few genuinely post-production capabilities you can reach from inside a ComfyUI graph.
It's also the node in this pack with the most awkward input, and no amount of goodwill gets around it.
How it works
The node POSTs to /veo/objects with action: insert or action: remove, your video_id, and async: true, then returns a task ID like every other paid node here. Veo re-renders the shot with the edit applied rather than compositing over it, which is why removal doesn't leave the usual smeary patch behind.
Two rules come straight from the API contract, and the client enforces both:
- insert needs a prompt. No prompt, no submission - the error is explicit.
- remove needs a mask URL. For removal, the model needs to be told where, and it takes that as an image mask fetched over public HTTPS.
There's also a rule the author made on purpose: the API accepts base64 masks too, but this node deliberately only accepts a URL, to keep megabytes of mask data out of your workflow file. That's a good call. It's also why your mask has to be somewhere on the internet.
The inputs
- video_id - an original Veo video ID. Extended results are not supported here, so if you've already chained an Extend, this node is off the table for that clip.
- action -
insertorremove, defaultinsert. - prompt - multiline, empty by default. For
insert, this is what you're adding and how it should behave ("a red vintage motorcycle leaning against the wall"). Forremove, it's optional - the mask already says where. - image_mask_url - a public HTTPS URL to the mask image. Required for
remove. Same validation as every other URL in the pack:httpsonly, no credentials in the URL, nolocalhost, no private IPs. The typical mask is a black-and-white image where the region you want changed is marked; you'll paint it in any image editor and upload it.
Outputs are the standard status, task_id, video_url, trace_id. Fresh submission returns pending with an empty video_url - that's success. Take task_id to Veo Retrieve Task, then the resulting video_url into Veo Load Video.
Install and key
ComfyUI Manager → Custom Nodes → search Veo → confirm publisher acedatacloud and package Veo by Ace Data Cloud → install, restart. Manual path:
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/AceDataCloud/VeoComfyUI.git
cd VeoComfyUI && python -m pip install -r requirements.txt
The dependency list is one line - requests. No model downloads, no VRAM, but ComfyUI 0.39.0+ is required for the VIDEO type the pack loads results into. Set the key where the running ComfyUI process can see it, then restart:
export ACEDATACLOUD_API_KEY='paste-your-key-here'
python main.py
Where people get burned
The mask URL is the wall. Everything you'd naturally reach for fails: a path in ComfyUI's output folder, a file:// link, a base64 blob, an http:// host. Ace's servers have to fetch that image themselves, so it's got to be a real public HTTPS link. Host your masks the same place you host reference images for the other nodes and this stops being painful; do it in a pinch and you'll resent it every time.
Then there's the ordering trap. Removal works on originals only, so the sequence matters: generate, clean up the scene, then extend if you need more seconds. Reverse it and you're stuck. And because this is a paid submission node flagged as an output node, it runs on Queue Prompt even with nothing connected downstream - mute it while you're iterating, or you'll pay for the same edit repeatedly. If it's sitting at pending, retrieve the same task ID; don't resubmit.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| video_id | STRING | — | |
| action | COMBO | insert | 2 options: insert, remove |
| prompt | STRING | — | |
| image_mask_url | STRING | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| status | STRING | — |
| task_id | STRING | — |
| video_url | STRING | — |
| trace_id | STRING | — |