Nodes/Save Image With Callback/Save Image With Callback
ComfyUI Node

Save Image With Callback

Save an image, then ping a webhook — the ComfyUI SaveImage that calls back

By WUYUDING2583·Created 2 years ago·Updated 2 years ago· 2
Save Image With Callback
  • images
    filename_prefixComfyUI

    Save Image With Callback is the boring ComfyUI SaveImage node you already know - only when the PNG is written, it also POSTs a little JSON to a URL of your choosing. No API key, no cloud service, no queue to manage. It saves the image exactly like the core node, and then it calls your webhook. That's the whole trick, and it's honest about it.

    Where this earns its keep: you're running ComfyUI as a headless generation backend and you want to know the moment a batch lands - to move a file to object storage, fire a notification, kick off a post-processing pipeline, or log that a job finished. Polling /history works, but a callback is simpler and instant. It's the ComfyUI equivalent of a "job done" webhook, and it weighs about 100 lines.

    The catch: it only fires when you drive it from the API

    Here's the part the README buries. The callback data doesn't come from any node input you can see in the graph - it rides in through extra_pnginfo, one of the hidden inputs every SaveImage-style node carries. When you run a workflow from the ComfyUI web UI, that hidden input is populated from the workflow's embedded metadata, which for a fresh workflow is empty. Nothing to send, no callback.

    So to actually trigger it you run the workflow through the HTTP API and attach the callback payload to the request, exactly like the README shows:

    {
        "prompt": prompt_data,
        "extra_data": {
            "extra_pnginfo": {
                "callback_data": {
                    "callback_url": "https://your-callback-url.example/hook",
                    "custom_field1": "value1"
                }
            }
        }
    }
    

    Export your workflow as API (the drop-down menu on the toolbar), take that JSON as prompt, and add the extra_data block. The ComfyUI runtime hands extra_pnginfo to the node's hidden input, the node finds callback_data, reads callback_url, and POSTs. If you never touch the API, this node behaves like a stock SaveImage with a debug banner in the console.

    The inputs that matter

    There are only two visible inputs, and they're the same ones you already set on core SaveImage:

    • images - the IMAGE tensor to write out.
    • filename_prefix - defaults to ComfyUI; supports the formatting tags like %date:yyyy-MM-dd% and %Empty Latent Image.width% for dynamic names.

    That's it. It's an output node with no return values - wire it in wherever you'd put SaveImage.

    What actually gets sent

    When the file is saved, it fires one POST per image in the batch (not one per run - generate four images and you get four requests). The JSON body is:

    {
      "filename": "ComfyUI_00001_.png",
      "full_path": "/home/user/ComfyUI/output/ComfyUI_00001_.png",
      "type": "output",
      "callback_data": { ... your custom fields ... }
    }
    

    Two things worth knowing. First, full_path is the literal filesystem path on the ComfyUI machine - if your webhook endpoint is public and remote, that's information you're volunteering; don't point this at a service you don't trust. Second, the request is fire-and-forget: if the POST fails, the exception is swallowed and printed to the ComfyUI console as Failed to send webhook: .... There's no retry, no queue, no delivery guarantee. Fine for notifications, wrong tool for anything where a dropped webhook is a real problem.

    Installing it

    Either search "Save Image With Callback" in ComfyUI Manager, or the manual route:

    cd ComfyUI/custom_nodes
    git clone https://github.com/WUYUDING2583/ComfyUI-Save-Image-Callback
    

    Then restart ComfyUI. Good news on the dependency front: there's no requirements.txt at all. The code imports requests, which ComfyUI itself already ships, so there's nothing extra to install - rarer than it should be in this ecosystem, and worth appreciating given how much custom-node setup time goes to dependency hell.

    The one caution

    A custom node that sends data to a URL is exactly the shape of thing that made this community nervous after the LLMVISION incident - but the whole pack is a single small Python file with no external dependencies, so it takes about a minute to read the whole thing and see exactly what it sends. Still: use an HTTPS callback_url, and don't pass secrets through callback_data unless the receiver is yours. It's a tidy, auditable little node. If you outgrow it - you need retries, auth headers, or batching - you'll write your own five-line output node instead, and this one will have shown you the pattern.

    Categoryimage

    Inputs (2)

    NameTypeDefaultDescription
    imagesIMAGEThe images to save.
    filename_prefixSTRINGComfyUIThe prefix for the file to save. This may include formatting information such as %date:yyyy-MM-dd% or %Empty Latent Image.width% to include values from nodes.

    Outputs (0)

    No outputs