From 730e73f5a48228d2e8644eb59e465296802d5a52 Mon Sep 17 00:00:00 2001 From: Bryan Wade Date: Tue, 15 Sep 2026 14:11:05 -0700 Subject: [PATCH 1/5] Help developers choose the right integration path faster The development landing page now presents its four primary paths together before the existing workflow quickstart, with one destination and a concise description per path. Constraint: Preserve the existing Quick Start guide and its current upstream copy. Rejected: Keep the supplemental More grid | the request calls for exactly four use-case panels. Confidence: high Scope-risk: narrow Reversibility: clean Tested: Mintlify strict build validation under Node 22.22.2; local desktop preview of the card grid and Quick Start transition Not-tested: Dedicated mobile viewport --- development/overview.mdx | 66 ++++++++++------------------------------ 1 file changed, 16 insertions(+), 50 deletions(-) diff --git a/development/overview.mdx b/development/overview.mdx index dc58feb41..5a22ffc14 100644 --- a/development/overview.mdx +++ b/development/overview.mdx @@ -5,9 +5,22 @@ description: "Using ComfyUI as a Developer" ComfyUI is a modular GenAI inference engine that can be run as a server, accessed via API, extended with custom nodes, and managed from the command line. Most API work follows two steps: get ComfyUI running somewhere, then run workflows against it from your application. - - Generate your first image with a Comfy API key in Python, TypeScript, or cURL. - +## Use cases + + + + Generate with hosted models through Comfy Router. + + + Deploy ComfyUI on the Developer Platform or your own infrastructure. + + + Run workflows from your application with an SDK or the HTTP API. + + + Connect AI agents to ComfyUI with MCP and Comfy CLI. + + ## Quick Start @@ -60,50 +73,3 @@ The fastest way to try the workflow API is to run a workflow against Comfy Cloud When you need your own models and custom nodes behind the endpoint, create a [Comfy API deployment](/development/serverless/overview), a serverless endpoint managed through the Developer Platform. The same SDK code works against it; only the base URL changes. - -## Deploy ComfyUI - -Learn how to deploy and scale ComfyUI, on the Developer Platform or your own infrastructure. - - - Compare Comfy API deployments, Comfy Cloud, and self-hosting, and pick the right target. - - -See also: [Comfy API deployments](/development/serverless/overview) · [Comfy Cloud](/development/deploy/cloud) · [Self-Hosting Options](/development/deploy/self-hosting) - -## Run Workflows - -Learn how to run workflows using our SDKs and the v2 HTTP API. They work against Comfy Cloud, Comfy API deployments, and your own ComfyUI instance. - - - See which client works with which deployment, starting with the Python and TypeScript SDKs. - - -See also: [Comfy SDKs](/development/api-development/sdks) · [API Proxy for Self-Hosted](/development/comfyui-server/api-proxy) · [Comfy API v2 Reference](/api-reference/v2/overview) - -## Agent Tools / MCP - -Connect AI agents to ComfyUI via the Model Context Protocol (MCP). Start with the hosted Cloud MCP, or use Local MCP and Comfy CLI for other setups. - - - Compare Cloud MCP, Local MCP, and Comfy CLI, and find the right setup for your AI agent integration. - - -See also: [Comfy MCP](/agent-tools/mcp) for cloud and local connections - -## More - - - - The raw REST and WebSocket API of the ComfyUI server: routes, messages, and startup flags. - - - Install, update, and manage ComfyUI from the terminal. - - - Extend ComfyUI with Python backends and JavaScript UI extensions. - - - Package and publish custom nodes through the Comfy Registry. - - From d0e8e503944dd3f92292541b3b394b117a440bcb Mon Sep 17 00:00:00 2001 From: Bryan Wade Date: Tue, 15 Sep 2026 14:27:10 -0700 Subject: [PATCH 2/5] Keep Router limitations aligned with queued delivery The new queued-delivery guide landed while the capabilities page still described Router as synchronous-only. Reconcile that page with the gated preview and point readers to the canonical queue guide instead of duplicating its examples. Constraint: Queued delivery is a caller-gated preview and returns 403 not_enabled when unavailable. Rejected: Keep the separate API-guide summary | upstream now has a dedicated queue guide and model examples, so another summary would duplicate them. Confidence: high Scope-risk: narrow Directive: Update queue semantics at the upstream contract before changing generated reference text. Tested: Mintlify strict validation; Mintlify broken-link check; unauthenticated live requests reached all four api.comfy.org queue routes and returned 401 with request IDs Not-tested: Authenticated queued generation because it can consume credits and is rollout-gated --- development/comfy-router/limitations.mdx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/development/comfy-router/limitations.mdx b/development/comfy-router/limitations.mdx index c377726ee..861e87331 100644 --- a/development/comfy-router/limitations.mdx +++ b/development/comfy-router/limitations.mdx @@ -4,26 +4,24 @@ sidebarTitle: "Capabilities and limits" description: "Choose Router or a partner proxy, plan for long-running calls, and understand recovery, rate limits, and asset storage." --- -Router runs a partner model through one synchronous HTTP call. Use it when your application can wait for a finished result and handle the model's own input and output fields. +Router's default route runs a partner model through one synchronous HTTP call. Queued delivery is available in a gated preview for applications that need to submit work and collect it later. ## What Router supports | Requirement | Router support | Alternative or next step | | --- | --- | --- | | Generate with one request | `POST /v2/models/{provider}/{model}` returns the finished result. | Start with the [Quickstart](/development/comfy-router/quickstart). | -| Submit a job and collect it later | No general job/status API or completion webhook. | Run Router from a worker, or use a partner proxy with submit-and-poll operations. | -| Show progress or stream output | No live progress, streaming, or preview frames during the call. | Show an indeterminate state, or use a supported proxy operation. | -| Recover after a lost connection | Same-key collection is available when Router retained a handle to an accepted generation. | Preserve the key and follow [retry guidance](/development/comfy-router/api#retry-outcomes). | +| Submit a request and collect it later | Available in gated preview through `POST /v2/models/{provider}/{model}/requests`. | See [Queued delivery](/development/comfy-router/queue). | +| Show progress or stream output | Queued delivery reports queue state and can include queue position, but no percentage progress, streaming output, or preview frames. | Poll the returned `status_url`, or use a supported proxy operation for provider-specific progress. | +| Recover after a lost connection | After receiving a queued request handle, use its returned URLs. If submission is interrupted before that, retry with the same idempotency key. Synchronous calls can sometimes be collected the same way. | Preserve the idempotency key and follow [retry guidance](/development/comfy-router/api#retry-outcomes). | | Reconcile Comfy charges | No universal Comfy cost or credit-balance field on the response. | Use [workspace billing](https://platform.comfy.org). | | Store results permanently | Asset URLs can expire, including rehosted and replayed URLs. | Download the assets; see [result assets](/development/comfy-router/reference#result-assets). | -## No queued submission +## Queued delivery is in preview -Router holds the connection while the model runs. For asynchronous providers, it submits the job and polls internally. Queued delivery (submit, get a `request_id`, poll, collect) is in a gated preview: see [Queued delivery](/development/comfy-router/queue). Outside the preview, Router does not expose a job ID, status endpoint, callback, or webhook. +Queued delivery returns a `request_id` and URLs for status, result collection, and cancellation. It is enabled per caller; callers without access receive `403` with `not_enabled`. Cancellation is best effort, and Router does not provide a completion webhook. See [Queued delivery](/development/comfy-router/queue) for examples and the full lifecycle. -If your request cannot stay open long enough, call Router from a worker and track the job in your application. Use a [partner proxy](#router-does-not-cover-every-partner-operation) when you need the provider's submit-and-poll controls. - -## Calls are cut off at a server deadline +## Synchronous calls are cut off at a server deadline Router's default deadline is **10 minutes**, configurable by the deployment. Set your client timeout above it so Router can return its error and request ID first. @@ -48,11 +46,11 @@ The request-rate limit applies to invocation and catalog/schema reads, including Cache catalog and schema reads. Revalidate schemas with `ETag` and `If-None-Match`. See [Headers](/development/comfy-router/headers) for retry and committed-spend fields. -## No progress while a call runs +## No live progress while a request runs -Router returns a final response, with no streamed tokens, server-sent events, percentage updates, or intermediate preview frames. A provider's internal polling state is not forwarded during the request. +Synchronous delivery returns only the final response. Queued delivery exposes queue state and can include queue position, but neither mode provides streamed tokens, server-sent events, percentage updates, or intermediate preview frames. A provider's internal progress is not forwarded. -Show an indeterminate progress indicator. If you need progress or streaming, use a partner-proxy operation that exposes it. +Show an indeterminate progress indicator after a queued request begins running. If you need provider-specific progress or streaming, use a partner-proxy operation that exposes it. From b5c079a2f36cd03287d5183189f2e9a07e57653f Mon Sep 17 00:00:00 2001 From: Bryan Wade Date: Tue, 15 Sep 2026 16:41:13 -0700 Subject: [PATCH 3/5] Use workspace terminology for queue preview gating The canonical queue guide scopes preview enablement and not_enabled responses to a workspace, so the capabilities page now uses the same term. Constraint: Leave the surrounding lifecycle description unchanged. Confidence: high Scope-risk: narrow Tested: Mintlify strict validation; git diff --check --- development/comfy-router/limitations.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/comfy-router/limitations.mdx b/development/comfy-router/limitations.mdx index 861e87331..bbac6036e 100644 --- a/development/comfy-router/limitations.mdx +++ b/development/comfy-router/limitations.mdx @@ -19,7 +19,7 @@ Router's default route runs a partner model through one synchronous HTTP call. Q ## Queued delivery is in preview -Queued delivery returns a `request_id` and URLs for status, result collection, and cancellation. It is enabled per caller; callers without access receive `403` with `not_enabled`. Cancellation is best effort, and Router does not provide a completion webhook. See [Queued delivery](/development/comfy-router/queue) for examples and the full lifecycle. +Queued delivery returns a `request_id` and URLs for status, result collection, and cancellation. It is enabled per workspace; workspaces without access receive `403` with `not_enabled`. Cancellation is best effort, and Router does not provide a completion webhook. See [Queued delivery](/development/comfy-router/queue) for examples and the full lifecycle. ## Synchronous calls are cut off at a server deadline From 56ac08695ed52265356257879bf3befb39730c52 Mon Sep 17 00:00:00 2001 From: Bryan Wade Date: Tue, 15 Sep 2026 16:50:10 -0700 Subject: [PATCH 4/5] Present queued delivery as a workspace rollout Queued delivery is a released API and SDK feature whose availability is still expanding by workspace. Describe the two delivery modes directly and reserve the access caveat for the availability section. Constraint: Workspaces without queue access still receive 403 not_enabled. Rejected: Remove the rollout caveat | universal enablement is not yet documented. Confidence: high Scope-risk: narrow Tested: Mintlify strict validation; git diff --check --- development/comfy-router/limitations.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/development/comfy-router/limitations.mdx b/development/comfy-router/limitations.mdx index bbac6036e..96b10b3ad 100644 --- a/development/comfy-router/limitations.mdx +++ b/development/comfy-router/limitations.mdx @@ -4,22 +4,22 @@ sidebarTitle: "Capabilities and limits" description: "Choose Router or a partner proxy, plan for long-running calls, and understand recovery, rate limits, and asset storage." --- -Router's default route runs a partner model through one synchronous HTTP call. Queued delivery is available in a gated preview for applications that need to submit work and collect it later. +Router supports synchronous and queued delivery. Synchronous delivery returns the finished result in one response. Queued delivery returns a request handle and is rolling out by workspace. ## What Router supports | Requirement | Router support | Alternative or next step | | --- | --- | --- | | Generate with one request | `POST /v2/models/{provider}/{model}` returns the finished result. | Start with the [Quickstart](/development/comfy-router/quickstart). | -| Submit a request and collect it later | Available in gated preview through `POST /v2/models/{provider}/{model}/requests`. | See [Queued delivery](/development/comfy-router/queue). | +| Submit a request and collect it later | Supported through `POST /v2/models/{provider}/{model}/requests` and rolling out by workspace. | See [Queued delivery](/development/comfy-router/queue). | | Show progress or stream output | Queued delivery reports queue state and can include queue position, but no percentage progress, streaming output, or preview frames. | Poll the returned `status_url`, or use a supported proxy operation for provider-specific progress. | | Recover after a lost connection | After receiving a queued request handle, use its returned URLs. If submission is interrupted before that, retry with the same idempotency key. Synchronous calls can sometimes be collected the same way. | Preserve the idempotency key and follow [retry guidance](/development/comfy-router/api#retry-outcomes). | | Reconcile Comfy charges | No universal Comfy cost or credit-balance field on the response. | Use [workspace billing](https://platform.comfy.org). | | Store results permanently | Asset URLs can expire, including rehosted and replayed URLs. | Download the assets; see [result assets](/development/comfy-router/reference#result-assets). | -## Queued delivery is in preview +## Queued delivery availability -Queued delivery returns a `request_id` and URLs for status, result collection, and cancellation. It is enabled per workspace; workspaces without access receive `403` with `not_enabled`. Cancellation is best effort, and Router does not provide a completion webhook. See [Queued delivery](/development/comfy-router/queue) for examples and the full lifecycle. +Queued delivery returns a `request_id` and URLs for status, result collection, and cancellation. It is rolling out by workspace; workspaces without access receive `403` with `not_enabled`. Cancellation is best effort, and Router does not provide a completion webhook. See [Queued delivery](/development/comfy-router/queue) for examples and the full lifecycle. ## Synchronous calls are cut off at a server deadline From 5f2066ca0e3afdbe5aff9930028432fe45e7680e Mon Sep 17 00:00:00 2001 From: Bryan Wade Date: Mon, 14 Sep 2026 16:33:43 -0700 Subject: [PATCH 5/5] Give API newcomers a runnable first workflow Publish a model-free API-format workflow with Python and TypeScript clients so developers can verify authentication, execution, and output download without finding a compatible community workflow first. Constraint: The first workflow must not depend on model availability or custom nodes. Rejected: Rewrite the developer landing page | PR #1686 owns that information architecture. Rejected: Add a second quickstart hub to the API-key page | the dedicated quickstarts already provide the next steps. Confidence: high Scope-risk: narrow Tested: Link and anchor validation; SDK workflow parsing and mocked downloads; strict TypeScript and Node syntax checks. Not-tested: Live Comfy Cloud execution. --- development/api-development/quickstart.mdx | 91 ++++++++++++++++++++++ docs.json | 1 + files/api-first-result/first_workflow.mts | 21 +++++ files/api-first-result/first_workflow.py | 20 +++++ files/api-first-result/workflow_api.json | 18 +++++ 5 files changed, 151 insertions(+) create mode 100644 development/api-development/quickstart.mdx create mode 100644 files/api-first-result/first_workflow.mts create mode 100644 files/api-first-result/first_workflow.py create mode 100644 files/api-first-result/workflow_api.json diff --git a/development/api-development/quickstart.mdx b/development/api-development/quickstart.mdx new file mode 100644 index 000000000..af7604038 --- /dev/null +++ b/development/api-development/quickstart.mdx @@ -0,0 +1,91 @@ +--- +title: "Run your first workflow" +description: "Run a sample workflow on Comfy Cloud and download its output with Python or TypeScript." +--- + +Run a complete workflow from code and save its output as `first-result.png`. This sample creates a **512 × 512 solid blue image** using two built-in nodes. It verifies authentication, workflow execution, and output download without requiring a model, an input image, or custom nodes. + +To generate an image by calling a hosted model directly, start with the [Comfy Router quickstart](/development/comfy-router/quickstart). + +## Before you start + +- A [Comfy API key](/development/api-development/getting-an-api-key). +- A [paid Comfy Cloud subscription](/development/deploy/cloud). Cloud workflow API access is not included in the free tier. +- Python 3.10 or newer, or Node.js 22.18 or newer for the TypeScript example. + +This guide uses Comfy Cloud, the SDKs' default target. If you previously set `COMFY_BASE_URL`, unset it to use Cloud. For an existing Comfy API deployment or a self-hosted instance, see [Choosing a base URL](/development/api-development/sdks#choosing-a-base-url). + +## 1. Download the sample + +Create a folder for the example. Download [workflow_api.json](/files/api-first-result/workflow_api.json) and the script for your language into that folder: + +- [Python: first_workflow.py](/files/api-first-result/first_workflow.py) +- [TypeScript: first_workflow.mts](/files/api-first-result/first_workflow.mts) + +The workflow is already in API format. Node `"1"` creates the blue image and node `"2"` saves it. The scripts read outputs from that exact SaveImage node, so you do not need to find or edit a node ID. + +## 2. Install the SDK and set your key + +Open a terminal in the folder where you saved the files. + + +```bash Python +python -m venv .venv +source .venv/bin/activate +python -m pip install comfy-sdk +``` + +```bash TypeScript +npm init -y +npm install @comfyorg/sdk +``` + + +On Windows, activate the Python environment with `.venv\Scripts\Activate.ps1` in PowerShell. + +Set your key in the same terminal: + + +```bash macOS / Linux +export COMFY_API_KEY="comfyui-your-key" +``` + +```powershell Windows PowerShell +$env:COMFY_API_KEY = "comfyui-your-key" +``` + + +Keep your API key in your server environment. Do not include it in browser code or commit it to source control. + +## 3. Run and view the result + + +```bash Python +python first_workflow.py +``` + +```bash TypeScript +node first_workflow.mts +``` + + +The script submits the workflow, waits for it to finish, and downloads the image. When it prints `Saved` followed by a path, open `first-result.png` from that location. You should see a solid blue square. Running the sample again replaces that local file. + + + This is a workflow connection check. It does not use a generative model. The same submit, wait, and download steps work with your own generation workflows. + + +### If the request fails + +- **Missing key or unauthorized:** check that `COMFY_API_KEY` is set in the terminal running the script and contains an active key. +- **Access or credit error:** check your Cloud subscription and available credits before retrying. +- **Workflow file not found:** keep `workflow_api.json` next to the downloaded script. +- **Unexpected endpoint:** check `COMFY_BASE_URL`. Unset it for this Cloud example. + +For error handling and job progress, see the [SDK guide](/development/api-development/sdks). + +## 4. Run your own generation workflow + +Build or choose a workflow in the ComfyUI editor, run it successfully there, and [export it in API format](/development/api-development/workflow-api-format). Replace `workflow_api.json` with your export and update `get_outputs("2")` in Python or `getOutputs("2")` in TypeScript to use your workflow's SaveImage node ID. Check that the target environment has the models and custom nodes your workflow uses. + +To host workflows with your own models and custom nodes, create a [Comfy API deployment](/development/serverless/overview). To change workflow inputs, upload files, or watch progress, continue to [Comfy SDKs](/development/api-development/sdks). diff --git a/docs.json b/docs.json index 856d618c6..f35e9d41c 100644 --- a/docs.json +++ b/docs.json @@ -3036,6 +3036,7 @@ "group": "Run Workflows", "pages": [ "development/run-workflows/overview", + "development/api-development/quickstart", "development/api-development/sdks", "development/comfyui-server/api-proxy", "development/api-development/workflow-api-format", diff --git a/files/api-first-result/first_workflow.mts b/files/api-first-result/first_workflow.mts new file mode 100644 index 000000000..068a5e4d5 --- /dev/null +++ b/files/api-first-result/first_workflow.mts @@ -0,0 +1,21 @@ +import { fileURLToPath } from "node:url"; +import { resolve } from "node:path"; +import { Comfy } from "@comfyorg/sdk"; + +const apiKey = process.env.COMFY_API_KEY; +if (!apiKey) { + throw new Error("Set COMFY_API_KEY to your Comfy API key before running this example."); +} + +// Keep the downloaded workflow alongside this script. +const workflowPath = fileURLToPath(new URL("./workflow_api.json", import.meta.url)); +const client = new Comfy({ apiKey }); +const workflow = await client.workflows.fromFile(workflowPath); +const job = await client.run(workflow); +// Node 2 is SaveImage in the bundled workflow. +const output = job.getOutputs("2")[0]; +if (!output) { + throw new Error("The workflow finished without an image from SaveImage (node 2)."); +} +await output.toFile("first-result.png"); +console.log(`Saved ${resolve("first-result.png")}`); diff --git a/files/api-first-result/first_workflow.py b/files/api-first-result/first_workflow.py new file mode 100644 index 000000000..68ef2aec3 --- /dev/null +++ b/files/api-first-result/first_workflow.py @@ -0,0 +1,20 @@ +import os +from pathlib import Path + +from comfy_sdk import Comfy + +api_key = os.environ.get("COMFY_API_KEY") +if not api_key: + raise SystemExit("Set COMFY_API_KEY to your Comfy API key before running this example.") + +# Keep the downloaded workflow alongside this script. +workflow_path = Path(__file__).with_name("workflow_api.json") +with Comfy(api_key=api_key) as client: + workflow = client.workflows.from_file(workflow_path) + job = client.run(workflow) + # Node 2 is SaveImage in the bundled workflow. + outputs = job.get_outputs("2") + if not outputs: + raise RuntimeError("The workflow finished without an image from SaveImage (node 2).") + output_path = outputs[0].to_file("first-result.png") + print(f"Saved {output_path.resolve()}") diff --git a/files/api-first-result/workflow_api.json b/files/api-first-result/workflow_api.json new file mode 100644 index 000000000..8d5fea656 --- /dev/null +++ b/files/api-first-result/workflow_api.json @@ -0,0 +1,18 @@ +{ + "1": { + "class_type": "EmptyImage", + "inputs": { + "width": 512, + "height": 512, + "batch_size": 1, + "color": 3368703 + } + }, + "2": { + "class_type": "SaveImage", + "inputs": { + "images": ["1", 0], + "filename_prefix": "comfy-first-result" + } + } +}