Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions development/api-development/quickstart.mdx
Original file line number Diff line number Diff line change
@@ -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).

Check warning on line 16 in development/api-development/quickstart.mdx

View check run for this annotation

Mintlify / Mintlify Validation (dripart) - vale-spellcheck

development/api-development/quickstart.mdx#L16

Did you really mean 'SDKs'?

## 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.

<CodeGroup>
```bash Python
python -m venv .venv

Check warning on line 33 in development/api-development/quickstart.mdx

View check run for this annotation

Mintlify / Mintlify Validation (dripart) - vale-spellcheck

development/api-development/quickstart.mdx#L33

'venv' is repeated!

Check warning on line 33 in development/api-development/quickstart.mdx

View check run for this annotation

Mintlify / Mintlify Validation (dripart) - vale-spellcheck

development/api-development/quickstart.mdx#L33

Did you really mean 'venv'?
source .venv/bin/activate
python -m pip install comfy-sdk
```

```bash TypeScript
npm init -y
npm install @comfyorg/sdk
```
</CodeGroup>

On Windows, activate the Python environment with `.venv\Scripts\Activate.ps1` in PowerShell.

Set your key in the same terminal:

<CodeGroup>
```bash macOS / Linux
export COMFY_API_KEY="comfyui-your-key"
```

```powershell Windows PowerShell
$env:COMFY_API_KEY = "comfyui-your-key"
```
</CodeGroup>

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

<CodeGroup>
```bash Python
python first_workflow.py
```

```bash TypeScript
node first_workflow.mts
```
</CodeGroup>

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.

<Note>
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.
</Note>

### 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).
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
21 changes: 21 additions & 0 deletions files/api-first-result/first_workflow.mts
Original file line number Diff line number Diff line change
@@ -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")}`);
20 changes: 20 additions & 0 deletions files/api-first-result/first_workflow.py
Original file line number Diff line number Diff line change
@@ -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()}")
18 changes: 18 additions & 0 deletions files/api-first-result/workflow_api.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
Loading