Webhook Notifier
Ping Your Server When the Image Is Actually Done
- images
The first thing to know: Webhook Notifier doesn't send your image. Despite the images socket, that IMAGE tensor never leaves your machine - not even a downscaled preview of it. The image connection is a trigger, and the payload is whatever JSON you type into additional_info. Once you've got that straight, it's one of the simplest "tell me when it's done" nodes in the ecosystem.
Why you'd reach for it
ComfyUI has a web API you can poll, but polling is annoying and adding a whole notification pack for one ping is overkill. This node is the minimal version: wire your final image output into it, give it a URL, and you get a POST the moment that image exists. That's the classic setup for a headless render box - you're SSH'd in elsewhere, the queue is grinding, and your Discord channel or a simple endpoint gets the "finished" ping. It's a small thing, but it's the difference between babysitting a terminal and walking away.
How it works
It's an output node (OUTPUT_NODE = True), which means it only executes once everything feeding it has completed. When it runs, notify() parses additional_info as JSON and spawns a background daemon thread that does requests.post(webhook_url, json=payload) with Content-Type: application/json. The main graph returns () instantly - no blocking on the network. The trade-off is baked in: fire-and-forget, no retries, no timeout watchdog. The payload is exactly your additional_info object; the image data is never touched or serialized.
The inputs that matter
Only three, and you'll set two of them:
images- required, IMAGE type. This is the trigger. It must come from an actual image-producing node (Save Image, VAE Decode, KSampler). The data isn't read or sent; the node just needs the connection to exist so it runs after the image is real. This is the built-in guarantee that the render finished - wire a Save Image's IMAGE out here and you're golden.webhook_url- required, defaults tohttps://example.com/webhook. Change it. The pack does not check for the placeholder, so your first run will silently POST to example.com and print "successful: 200".additional_info- optional multiline JSON, the whole payload. Empty or invalid JSON sends{}.
No outputs - it's a terminal node.
Installing it
ComfyUI Manager: search "WebhookNotifier", install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/iSuneast/ComfyUI-WebhookNotifier.git
cd ComfyUI-WebhookNotifier
pip install -r requirements.txt
Then restart ComfyUI. The only dependency in requirements.txt is requests>=2.27.0, which ComfyUI already has, so you can often skip the pip line entirely. No model files, nothing heavy.
Where people get burned
- The
imagesinput is not a preview uplink. People plug in the image expecting it in the payload, then wonder why the receiver got a bare JSON object. It's a trigger with a really good type guarantee. - It only accepts IMAGE. If you want to trigger on a
LATENT, aSTRING, or aVHS_FILENAMESpath, this node will refuse the connection - that's exactly what the sibling Webhook Notifier (Any) exists for, and it's the one to pick when your "done" signal isn't a picture. - Watch the console, not the node. The node surface shows nothing. Debug via prints:
Webhook notification started in background, thenWebhook notification successful: 200orWebhook notification failed: <code> - <response>. No "successful" line means the endpoint was unreachable and the exception was printed instead. - No auth header support. There's no key/token input. If your webhook endpoint needs a bearer token, this node can't send it - choose a receiver that's open, or a fuller webhook pack.
For a beginner, this is the more forgiving sibling: the IMAGE-only socket makes it hard to wire in the wrong place, because the wrong place won't accept the connection. That type-checking is genuinely useful if you're just starting to hook ComfyUI up to the outside world.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| webhook_url | STRING | https://example.com/webhook | — |
| additional_infoopt | STRING | {} | — |
Outputs (0)
No outputs