From aba6c2dfc5d9ebe112ca5f5520a037bb7baf1455 Mon Sep 17 00:00:00 2001 From: wei-hai Date: Thu, 23 Jul 2026 09:23:53 -0700 Subject: [PATCH 1/2] docs: document getDownloadUrl() and fix API-key placeholder The README documented toFile() but not getDownloadUrl(), a public output method. Adds a concise 'Downloading outputs' section covering toFile/toBytes, range reads, and getDownloadUrl() (self-authorizing signed URL on cloud, content endpoint on self-hosted). Also corrects the API-key placeholder in the auth table: keys are comfyui-*, not ck_*. Verified live against staging and prod. Co-Authored-By: Claude Opus 4.8 --- README.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7777744..98aabd7 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,8 @@ await job.getOutputs("13")[0].toFile("out.png"); | Surface | Auth | | ------------------------------------------------------------------ | ------------------------------------------ | | Self-hosted proxy (`comfy-api-proxy` in front of your own ComfyUI) | none — do **not** pass `apiKey` | -| Comfy Cloud | `new Comfy(baseUrl, { apiKey: "ck_..." })` | -| Serverless | `new Comfy(baseUrl, { apiKey: "ck_..." })` | +| Comfy Cloud | `new Comfy(baseUrl, { apiKey: "comfyui-..." })` | +| Serverless | `new Comfy(baseUrl, { apiKey: "comfyui-..." })` | The client only attaches the `Authorization` header to requests aimed at its own `baseUrl`'s origin. If the server hands back an absolute URL on a @@ -178,6 +178,32 @@ managing an `AbortController` yourself: await client.run(wf, { timeoutMs: 60_000 }); ``` +## Downloading outputs + +A finished job exposes its results as output handles — `job.outputs`, or +`job.getOutputs(nodeId)` to filter to one node. Each is an asset you can pull +down whichever way suits the caller: + +```ts +const out = job.getOutputs("13")[0]; +await out.toFile("result.png"); // stream to disk +const data = await out.toBytes(); // buffer into memory +await out.toFile("head.png", { range: [0, 1023] }); // range-aware: first 1 KiB only +``` + +`getDownloadUrl()` hands back a fetchable URL instead of streaming the bytes +through your process — give it to a browser, a CDN, or another service: + +```ts +const { url, expiresAt } = await out.getDownloadUrl(); +``` + +On Comfy Cloud / serverless it's a short-lived, **self-authorizing** signed +storage URL: whoever holds it can read the asset until `expiresAt` with no API +key of their own. On a self-hosted proxy it's the content endpoint (normal auth +still applies) and `expiresAt` is `null`. It works on every backend and never +downloads the bytes first. + ## Typed errors Protocol-level failures are raised as one exception class per error code, so From 908d62fb5750cd8911027940fbf83059f5d2b029 Mon Sep 17 00:00:00 2001 From: wei-hai Date: Thu, 23 Jul 2026 09:27:08 -0700 Subject: [PATCH 2/2] docs: apply oxfmt formatting to README Co-Authored-By: Claude Opus 4.8 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 98aabd7..9f473e5 100644 --- a/README.md +++ b/README.md @@ -44,9 +44,9 @@ await job.getOutputs("13")[0].toFile("out.png"); ## Auth, per surface -| Surface | Auth | -| ------------------------------------------------------------------ | ------------------------------------------ | -| Self-hosted proxy (`comfy-api-proxy` in front of your own ComfyUI) | none — do **not** pass `apiKey` | +| Surface | Auth | +| ------------------------------------------------------------------ | ----------------------------------------------- | +| Self-hosted proxy (`comfy-api-proxy` in front of your own ComfyUI) | none — do **not** pass `apiKey` | | Comfy Cloud | `new Comfy(baseUrl, { apiKey: "comfyui-..." })` | | Serverless | `new Comfy(baseUrl, { apiKey: "comfyui-..." })` |