Nodes/ComfyUI-ImmichUploader/Immich Upload (Image/File)
ComfyUI Node

Immich Upload (Image/File)

Your generations, straight into your own Google Photos

By PatrickBorkowicz·Created 11 months ago·Updated 11 months ago· 1
Immich Upload (Image/File)
  • images
  • asset_ids_json
base_urlhttp://127.0.0.1:2283/api
api_key
save_image_formatpng
save_quality95
file_paths
album_id
album_name

If you self-host Immich - the open-source Google Photos alternative - you already know the pain this node solves. Your ComfyUI output folder grows by the day, timestamp filenames pile up, and finding that one generation from three weeks ago means spelunking. Meanwhile your real photo library lives in Immich, with search, face recognition, and albums. This node is the bridge: it takes the images still in your graph (or the MP4 you just rendered to disk) and uploads them straight to Immich, optionally into an album you pick or one it creates for you.

It's a Save/Network node, the "save" step of your workflow aimed at a server instead of a folder. And here's the thing - barely anyone in the ComfyUI community talks about it. In r/comfyui and r/StableDiffusion, Immich shows up a handful of times, mostly people discovering it works surprisingly well as a gallery for AI output folders (point Immich's "external library" at your output dir and it scans everything). This node flips that model: instead of Immich finding your files, ComfyUI hands them over, metadata and all. If you're an Immich user, this is the save step you didn't know you were missing. If you're not, nothing here will change your life - this is a node with exactly one audience, and it's fine with that.

How it works

Plain REST calls, no extra server, no password sharing. You give it the Immich API base URL and an API key (Immich → your user menu → API Keys), and the node talks to the /assets endpoint with an x-api-key header. The default http://127.0.0.1:2283/api assumes Immich runs on the same machine as ComfyUI; if it's on another box, point it at that host's IP or hostname - the node even normalizes a bare host:port to the /api path for you.

It dedupes the way the Immich CLI does: every upload carries a deviceAssetId built from filename plus file modification time, so re-running a workflow won't duplicate the same asset. Images from your graph get written to a temp file (that's what save_image_format and save_quality control) and uploaded; file paths get streamed straight through. Finally, if you gave it an album name, it searches your albums and creates one if it's missing, then adds the fresh asset IDs to it.

The inputs that matter

Only two are required: base_url and api_key. Everything else is optional.

  • images - your IMAGE tensor. Wire it straight out of whatever KSampler/VaeDecode chain you're running.
  • save_image_format / save_quality - png, jpeg, or webp; quality 1–100, default 95. Quality only applies to jpeg/webp - PNG is lossless, so that slider is dead weight there.
  • file_paths - newline-separated absolute paths for things like the MP4 a video workflow wrote to disk. One per line. The file must exist on the machine running ComfyUI, or the node throws.
  • album_id / album_name - ID wins if both are set; name is matched case-insensitively and created if absent.

Output is a single asset_ids_json string (JSON of the uploaded asset IDs plus the album ID). Drop it into a text-display node if you want to confirm what landed.

Installing it

Standard fare, no model downloads, no heavy dependencies - just requests (and pillow, which ComfyUI usually ships with):

cd ComfyUI/custom_nodes
git clone https://github.com/PatrickBorkowicz/ComfyUI-ImmichUploader
# then restart ComfyUI

Or search "Immich Uploader" in ComfyUI Manager and click install. On Windows with the embedded Python, the README has you pip-install requests into that environment explicitly:

<path-to>\ComfyUI\python_embeded\python.exe -m pip install requests

Where people get burned

The two real traps: forgetting the API key (the node hard-fails with a clear error if it's blank - it won't fall back to a password) and pointing base_url at the wrong host so your ComfyUI box can't reach the Immich server. Check those before you blame the node. Also note it's case-insensitive on album name, and if you leave album_name blank, nothing gets album'd - you just get loose assets in your library, which is fine if that's what you want.

This is an admirably boring node, in the good way. It uploads, it dedupes, it albums, and it gets out of your way. Exactly what you want from the save step.

CategorySave/Network

Inputs (8)

NameTypeDefaultDescription
base_urlSTRINGhttp://127.0.0.1:2283/api
api_keySTRING
imagesoptIMAGE
save_image_formatoptCOMBOpng3 options: png, jpeg, webp
save_qualityoptINT951–100
file_pathsoptSTRING
album_idoptSTRING
album_nameoptSTRING

Outputs (1)

NameTypeDescription
asset_ids_jsonSTRING