From b03d4e5269b3bf58d3def0171b09e28ee4c23b80 Mon Sep 17 00:00:00 2001 From: Bryan Wade Date: Mon, 14 Sep 2026 16:33:43 -0700 Subject: [PATCH] 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" + } + } +}