From 967845df04a20a5389a81983f8a74908a76e4b7e Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 01:56:24 +0800 Subject: [PATCH 01/22] feat: rename Cloud & Partner APIs group to ComfyUI APIs, add Server API overview and quick start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename side navigation group 'Cloud & Partner APIs' → 'ComfyUI APIs' - Remove redundant 'ComfyUI Server' group from Development tab (merged into APIs) - Add new development/apis/overview.mdx with API comparison table (EN/ZH/JA) - Add new development/comfyui-server/server-guide.mdx as entry point (EN/ZH/JA) - Add new development/comfyui-server/quick-start.mdx with 3 code patterns (EN/ZH/JA) - HTTP only (basic_api_example) - WebSocket + History (websockets_api_example) - SaveImageWebsocket real-time images (websockets_api_example_ws_images) - Update development/overview.mdx references and links - Update docs.json for all 3 languages --- development/api-development/overview.mdx | 48 +++ development/comfyui-server/quick-start.mdx | 301 ++++++++++++++++++ development/comfyui-server/server-guide.mdx | 65 ++++ development/overview.mdx | 8 +- docs.json | 87 ++--- ja/development/api-development/overview.mdx | 46 +++ ja/development/comfyui-server/quick-start.mdx | 248 +++++++++++++++ .../comfyui-server/server-guide.mdx | 65 ++++ zh/development/api-development/overview.mdx | 46 +++ zh/development/comfyui-server/quick-start.mdx | 272 ++++++++++++++++ .../comfyui-server/server-guide.mdx | 65 ++++ 11 files changed, 1208 insertions(+), 43 deletions(-) create mode 100644 development/api-development/overview.mdx create mode 100644 development/comfyui-server/quick-start.mdx create mode 100644 development/comfyui-server/server-guide.mdx create mode 100644 ja/development/api-development/overview.mdx create mode 100644 ja/development/comfyui-server/quick-start.mdx create mode 100644 ja/development/comfyui-server/server-guide.mdx create mode 100644 zh/development/api-development/overview.mdx create mode 100644 zh/development/comfyui-server/quick-start.mdx create mode 100644 zh/development/comfyui-server/server-guide.mdx diff --git a/development/api-development/overview.mdx b/development/api-development/overview.mdx new file mode 100644 index 000000000..4214f3d36 --- /dev/null +++ b/development/api-development/overview.mdx @@ -0,0 +1,48 @@ +--- +title: "APIs Overview" +description: "An overview of the different ways to interact with ComfyUI programmatically" +--- + +ComfyUI offers several API options depending on where you want to run your workflows and how much infrastructure you want to manage. This page helps you choose the right approach. + +--- + +## Which API Should I Use? + +| | Cloud API | ComfyUI Server API | +|---|---|---| +| **Where it runs** | Comfy Cloud (managed GPUs) | Your own machine | +| **GPU management** | Handled for you | You manage your own hardware | +| **Models** | Pre-installed and managed by Comfy | You download and manage locally | +| **Authentication** | `X-API-Key` header (Comfy Cloud account) | None (local) or API key for Partner Nodes | +| **Base URL** | `https://cloud.comfy.org` | `http://localhost:8188` | +| **Protocol** | REST + WebSocket | REST + WebSocket | +| **Pricing** | Subscription-based (Creator/Pro tiers) | Free (your own compute) | +| **Best for** | Quick integration, no infrastructure | Full control, custom hardware & models | + +Both APIs use the same workflow format ("API format"), so you can develop and test workflows locally and move them to the cloud without changes. + +--- + +## Getting Started + + + + Run workflows on Comfy's managed infrastructure. No GPU setup required. + + + Run ComfyUI as a server on your own machine and call it via API. + + + Use paid Partner Nodes in headless or API-driven workflows. + + + +--- + +## Prerequisites + +Before using any API, you'll need: + +- A Comfy Cloud account ([sign up](https://comfy.org/signup)) +- An API key (see [Getting an API Key](/development/api-development/getting-an-api-key)) diff --git a/development/comfyui-server/quick-start.mdx b/development/comfyui-server/quick-start.mdx new file mode 100644 index 000000000..b4aebde9e --- /dev/null +++ b/development/comfyui-server/quick-start.mdx @@ -0,0 +1,301 @@ +--- +title: "Quick Start" +description: "Three common patterns for calling the ComfyUI Server API" +--- + +This page demonstrates three ways to interact with the ComfyUI Server API, from a simple HTTP submission to a full WebSocket integration with real-time image output. + +All examples use the [default SD1.5 workflow](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples) for illustration. You can export any workflow in API format from the ComfyUI frontend (`File → Save (API Format)`). + + + These examples use Python with the standard library and the `websocket-client` package (`pip install websocket-client`). The underlying API protocol is the same regardless of language — see the [Cloud API Reference](/development/cloud/api-reference) for TypeScript and curl equivalents. + + +--- + +## Method 1: Submit and Forget (HTTP only) + +The simplest approach: submit a workflow and don't wait for results. Useful for fire-and-forget jobs where you check outputs later. + +```python +"""basic_api_example.py — Submit a workflow via HTTP only.""" + +import json +from urllib import request + +SERVER_ADDRESS = "127.0.0.1:8188" + + +def queue_prompt(prompt): + p = {"prompt": prompt} + data = json.dumps(p).encode("utf-8") + req = request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + request.urlopen(req) + + +if __name__ == "__main__": + # Load a workflow exported in API format + prompt_text = """{ + "3": { + "class_type": "KSampler", + "inputs": { + "cfg": 8, "denoise": 1, + "latent_image": ["5", 0], + "model": ["4", 0], + "negative": ["7", 0], + "positive": ["6", 0], + "sampler_name": "euler", + "scheduler": "normal", + "seed": 8566257, "steps": 20 + } + }, + "4": { + "class_type": "CheckpointLoaderSimple", + "inputs": {"ckpt_name": "v1-5-pruned-emaonly.safetensors"} + }, + "5": { + "class_type": "EmptyLatentImage", + "inputs": {"batch_size": 1, "height": 512, "width": 512} + }, + "6": { + "class_type": "CLIPTextEncode", + "inputs": {"clip": ["4", 1], "text": "masterpiece best quality man"} + }, + "7": { + "class_type": "CLIPTextEncode", + "inputs": {"clip": ["4", 1], "text": "bad hands"} + }, + "8": { + "class_type": "VAEDecode", + "inputs": {"samples": ["3", 0], "vae": ["4", 2]} + }, + "9": { + "class_type": "SaveImage", + "inputs": {"filename_prefix": "ComfyUI", "images": ["8", 0]} + } + }""" + + prompt = json.loads(prompt_text) + # Modify inputs before submitting + prompt["3"]["inputs"]["seed"] = 5 + prompt["6"]["inputs"]["text"] = "masterpiece best quality man" + + queue_prompt(prompt) + print("Prompt submitted successfully.") +``` + + + This method uses the `SaveImage` node, which saves images to disk on the server. To retrieve them, you'd need to follow up with a call to `GET /view?filename=...`. + + +--- + +## Method 2: WebSocket + History (Monitor Completion) + +Use WebSocket to wait for execution to finish, then retrieve outputs via the `/history` endpoint. This is the recommended pattern for most use cases. + +```python +"""websockets_api_example.py — Monitor execution via WebSocket, download via /history.""" + +import websocket # pip install websocket-client +import uuid +import json +import urllib.request +import urllib.parse + +SERVER_ADDRESS = "127.0.0.1:8188" +client_id = str(uuid.uuid4()) + + +def queue_prompt(prompt, prompt_id): + p = {"prompt": prompt, "client_id": client_id, "prompt_id": prompt_id} + data = json.dumps(p).encode("utf-8") + req = urllib.request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + urllib.request.urlopen(req) + + +def get_image(filename, subfolder, folder_type): + params = urllib.parse.urlencode({ + "filename": filename, + "subfolder": subfolder, + "type": folder_type, + }) + with urllib.request.urlopen( + f"http://{SERVER_ADDRESS}/view?{params}" + ) as response: + return response.read() + + +def get_history(prompt_id): + with urllib.request.urlopen( + f"http://{SERVER_ADDRESS}/history/{prompt_id}" + ) as response: + return json.loads(response.read()) + + +def get_images(ws, prompt): + prompt_id = str(uuid.uuid4()) + queue_prompt(prompt, prompt_id) + + while True: + out = ws.recv() + if isinstance(out, str): + message = json.loads(out) + if message["type"] == "executing": + data = message["data"] + if data["node"] is None and data["prompt_id"] == prompt_id: + break # Execution done + # Binary frames are preview images — skip them here + continue + + history = get_history(prompt_id)[prompt_id] + output_images = {} + for node_id in history["outputs"]: + node_output = history["outputs"][node_id] + images_output = [] + if "images" in node_output: + for image in node_output["images"]: + image_data = get_image( + image["filename"], image["subfolder"], image["type"] + ) + images_output.append(image_data) + output_images[node_id] = images_output + return output_images + + +if __name__ == "__main__": + prompt_text = """{ + "3": { ... }, "4": { ... }, "5": { ... }, + "6": { ... }, "7": { ... }, "8": { ... }, + "9": { "class_type": "SaveImage", "inputs": { ... } } + }""" + prompt = json.loads(prompt_text) + prompt["3"]["inputs"]["seed"] = 5 + prompt["6"]["inputs"]["text"] = "masterpiece best quality man" + + ws = websocket.WebSocket() + ws.connect(f"ws://{SERVER_ADDRESS}/ws?clientId={client_id}") + images = get_images(ws, prompt) + ws.close() + + print(f"Got {len(images)} output node(s) with images.") + + # Display the images (requires Pillow): + # for node_id in images: + # for image_data in images[node_id]: + # from PIL import Image + # import io + # img = Image.open(io.BytesIO(image_data)) + # img.show() +``` + + + The WebSocket binary frames contain in-progress preview images during generation. You can decode them for live previews (see the [Server Messages](/development/comfyui-server/comms_messages) page for the binary format). + + +--- + +## Method 3: WebSocket with SaveImageWebsocket (Real-time Images) + +For scenarios where you don't want images saved to disk, use the `SaveImageWebsocket` node. Images are delivered directly via WebSocket binary frames. + +```python +"""websockets_api_example_ws_images.py — Receive images directly via WebSocket.""" + +import websocket # pip install websocket-client +import uuid +import json +import urllib.request +import urllib.parse + +SERVER_ADDRESS = "127.0.0.1:8188" +client_id = str(uuid.uuid4()) + + +def queue_prompt(prompt): + p = {"prompt": prompt, "client_id": client_id} + data = json.dumps(p).encode("utf-8") + req = urllib.request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + return json.loads(urllib.request.urlopen(req).read()) + + +def get_images(ws, prompt): + prompt_id = queue_prompt(prompt)["prompt_id"] + output_images = {} + current_node = "" + + while True: + out = ws.recv() + if isinstance(out, str): + message = json.loads(out) + if message["type"] == "executing": + data = message["data"] + if data["prompt_id"] == prompt_id: + if data["node"] is None: + break # Execution done + current_node = data["node"] + else: + # Binary frame — image data from SaveImageWebsocket + if current_node == "save_image_websocket_node": + images_output = output_images.get(current_node, []) + # The first 8 bytes are type/meta, rest is image data + images_output.append(out[8:]) + output_images[current_node] = images_output + + return output_images + + +if __name__ == "__main__": + prompt_text = """{ + "3": { "class_type": "KSampler", "inputs": { ... } }, + ... + "save_image_websocket_node": { + "class_type": "SaveImageWebsocket", + "inputs": {"images": ["8", 0]} + } + }""" + prompt = json.loads(prompt_text) + prompt["3"]["inputs"]["seed"] = 5 + + ws = websocket.WebSocket() + ws.connect(f"ws://{SERVER_ADDRESS}/ws?clientId={client_id}") + images = get_images(ws, prompt) + ws.close() + + print(f"Received {len(images)} image(s) via WebSocket.") + + # Display (requires Pillow): + # for image_data in images.get("save_image_websocket_node", []): + # from PIL import Image + # import io + # img = Image.open(io.BytesIO(image_data)) + # img.show() +``` + + + The workflow must use a node with `class_type: "SaveImageWebsocket"` (a built-in node) instead of the regular `SaveImage` node. + + +--- + +## Which Method Should I Use? + + + + **Fire and forget.** Use when you don't need immediate output, or when retrieving results later is acceptable. + + + **Recommended.** Wait for completion, then download outputs. Best balance of simplicity and reliability. + + + **Real-time images.** Best for interactive apps where you want images delivered without disk writes. + + + +For the full API reference (endpoints, payload formats, error handling), see the [Server Routes](/development/comfyui-server/comms_routes) and [Server Messages](/development/comfyui-server/comms_messages) pages. diff --git a/development/comfyui-server/server-guide.mdx b/development/comfyui-server/server-guide.mdx new file mode 100644 index 000000000..1a9f84b0c --- /dev/null +++ b/development/comfyui-server/server-guide.mdx @@ -0,0 +1,65 @@ +--- +title: "ComfyUI Server API" +description: "Run ComfyUI as a server and interact with it programmatically via REST and WebSocket APIs" +--- + +ComfyUI runs as an HTTP server on your machine by default. You can call it programmatically to submit workflows, upload files, download outputs, and monitor progress — all without opening the browser. + +## Starting the Server + +When you launch ComfyUI, it automatically starts an HTTP server: + +```bash +# Default server address +http://127.0.0.1:8188 +``` + +To run ComfyUI as a headless server (no browser): + + +```bash +# Run without opening the browser +python main.py --headless +``` + +```bash +# Specify a custom port +python main.py --port 8288 +``` + +```bash +# Listen on all network interfaces (for remote access) +python main.py --listen 0.0.0.0 +``` + + + + For a full list of available startup flags, run `python main.py --help` or see the [install guide](/installation/manual_install#basic-usage). + + +## Quick Start + +The [Quick Start](/development/comfyui-server/quick-start) page shows three common patterns for calling the API, from a simple HTTP submission to a full WebSocket integration with real-time image output. + +## Server Internals + +For details on the server architecture, message types, and route handling: + + + + Understand the server's architecture (aiohttp, asyncio, message passing). + + + All message types the server sends to the client. + + + Available HTTP routes you can call on the server. + + + Advanced: invert execution for custom control flows. + + + +## Using Partner Nodes + +If your workflow contains paid Partner Nodes, you can include your API key in the payload. See the [Partner Node API Integration](/development/comfyui-server/api-key-integration) guide for details. diff --git a/development/overview.mdx b/development/overview.mdx index c82010b48..d54afd3d5 100644 --- a/development/overview.mdx +++ b/development/overview.mdx @@ -9,11 +9,11 @@ ComfyUI is a modular GenAI inference engine that can be run as a server, accesse Run ComfyUI in your own environment and expose it as an API endpoint. Learn about the WebSocket message protocol, available routes, and execution modes. - - Get started with the local server setup, message types, route handling, and execution model inversion. + + Run ComfyUI as a server on your own machine. Start, configure, and call it via REST and WebSocket APIs. -See also: [Messages & Routes](/development/comfyui-server/comms_messages) · [Execution Model Inversion](/development/comfyui-server/execution_model_inversion_guide) · [Partner Node API Integration](/development/comfyui-server/api-key-integration) +See also: [Server API Quick Start](/development/comfyui-server/quick-start) · [Partner Node API Integration](/development/comfyui-server/api-key-integration) ## Cloud API @@ -23,7 +23,7 @@ Run workflows programmatically on Comfy Cloud without managing your own hardware Learn how to authenticate, submit jobs, check status, and download results from Comfy Cloud. -See also: [API Reference](/development/cloud/api-reference) · [OpenAPI Specification](/development/cloud/openapi) · [Getting an API Key](/development/api-development/getting-an-api-key) +See also: [API Reference](/development/cloud/api-reference) · [OpenAPI Specification](/development/cloud/openapi) · [Getting an API Key](/development/api-development/getting-an-api-key) · [APIs Overview](/development/api-development/overview) ## Agent Tools / MCP diff --git a/docs.json b/docs.json index 5b46f867c..a080ce66f 100644 --- a/docs.json +++ b/docs.json @@ -2257,22 +2257,13 @@ "tab": "Development", "pages": [ "development/overview", + { - "group": "ComfyUI Server", - "icon": "code", - "pages": [ - "development/comfyui-server/comms_overview", - "development/comfyui-server/comms_messages", - "development/comfyui-server/comms_routes", - "development/comfyui-server/execution_model_inversion_guide" - ] - }, - { - "group": "Cloud & Partner APIs", + "group": "ComfyUI APIs", "icon": "cloud", "pages": [ + "development/api-development/overview", "development/api-development/getting-an-api-key", - "development/comfyui-server/api-key-integration", { "group": "Cloud API", "pages": [ @@ -2280,7 +2271,19 @@ "development/cloud/api-reference", "development/cloud/openapi" ] - } + }, + { + "group": "ComfyUI Server API", + "pages": [ + "development/comfyui-server/server-guide", + "development/comfyui-server/quick-start", + "development/comfyui-server/comms_overview", + "development/comfyui-server/comms_messages", + "development/comfyui-server/comms_routes", + "development/comfyui-server/execution_model_inversion_guide" + ] + }, + "development/comfyui-server/api-key-integration" ] }, { @@ -4696,22 +4699,13 @@ "tab": "开发", "pages": [ "zh/development/overview", + { - "group": "ComfyUI Server", - "icon": "code", - "pages": [ - "zh/development/comfyui-server/comms_overview", - "zh/development/comfyui-server/comms_messages", - "zh/development/comfyui-server/comms_routes", - "zh/development/comfyui-server/execution_model_inversion_guide" - ] - }, - { - "group": "Cloud & Partner APIs", + "group": "ComfyUI APIs", "icon": "cloud", "pages": [ + "zh/development/api-development/overview", "zh/development/api-development/getting-an-api-key", - "zh/development/comfyui-server/api-key-integration", { "group": "Cloud API", "pages": [ @@ -4719,7 +4713,19 @@ "zh/development/cloud/api-reference", "zh/development/cloud/openapi" ] - } + }, + { + "group": "ComfyUI Server API", + "pages": [ + "zh/development/comfyui-server/server-guide", + "zh/development/comfyui-server/quick-start", + "zh/development/comfyui-server/comms_overview", + "zh/development/comfyui-server/comms_messages", + "zh/development/comfyui-server/comms_routes", + "zh/development/comfyui-server/execution_model_inversion_guide" + ] + }, + "zh/development/comfyui-server/api-key-integration" ] }, { @@ -7135,22 +7141,13 @@ "tab": "開発", "pages": [ "ja/development/overview", + { - "group": "ComfyUI Server", - "icon": "code", - "pages": [ - "ja/development/comfyui-server/comms_overview", - "ja/development/comfyui-server/comms_messages", - "ja/development/comfyui-server/comms_routes", - "ja/development/comfyui-server/execution_model_inversion_guide" - ] - }, - { - "group": "Cloud & Partner APIs", + "group": "ComfyUI APIs", "icon": "cloud", "pages": [ + "ja/development/api-development/overview", "ja/development/api-development/getting-an-api-key", - "ja/development/comfyui-server/api-key-integration", { "group": "Cloud API", "pages": [ @@ -7158,7 +7155,19 @@ "ja/development/cloud/api-reference", "ja/development/cloud/openapi" ] - } + }, + { + "group": "ComfyUI Server API", + "pages": [ + "ja/development/comfyui-server/server-guide", + "ja/development/comfyui-server/quick-start", + "ja/development/comfyui-server/comms_overview", + "ja/development/comfyui-server/comms_messages", + "ja/development/comfyui-server/comms_routes", + "ja/development/comfyui-server/execution_model_inversion_guide" + ] + }, + "ja/development/comfyui-server/api-key-integration" ] }, { diff --git a/ja/development/api-development/overview.mdx b/ja/development/api-development/overview.mdx new file mode 100644 index 000000000..57eac569e --- /dev/null +++ b/ja/development/api-development/overview.mdx @@ -0,0 +1,46 @@ +--- +title: "API 概要" +description: "ComfyUI をプログラムから操作するための様々なAPIの概要" +--- + +ComfyUI には、ワークフローを実行する場所や管理したいインフラストラクチャに応じて、複数の API オプションがあります。このページは適切な方法を選ぶのに役立ちます。 + +--- + +## どの API を使うべきか? + +| | Cloud API | ComfyUI Server API | +|---|---|---| +| **実行環境** | Comfy Cloud(マネージド GPU) | 自分のマシン | +| **GPU 管理** | 不要 | 自分で管理 | +| **モデル** | クラウドにプリインストール | 自分でダウンロード・管理 | +| **認証** | `X-API-Key` ヘッダー | 不要(ローカル)または API Key(Partner Nodes) | +| **ベースURL** | `https://cloud.comfy.org` | `http://localhost:8188` | +| **プロトコル** | REST + WebSocket | REST + WebSocket | +| **料金** | サブスクリプション制 | 無料(自分の計算リソース)| +| **用途** | 迅速な統合、インフラ不要 | 完全制御、カスタムハードウェア・モデル | + +両 API は同じワークフロー形式("API 形式")を使用するため、ローカルで開発・テストしてからクラウドに移行しても変更は不要です。 + +--- + +## クイックスタート + + + + Comfy のマネージドインフラ上でワークフローを実行。GPU 設定は不要。 + + + 自分のマシンで ComfyUI をサーバーとして実行し、API 経由で呼び出し。 + + + ヘッドレスまたは API 駆動のワークフローで Partner Nodes を利用。 + + + +--- + +## 前提条件 + +- Comfy Cloud アカウント([登録](https://comfy.org/signup)) +- API Key([API Key の取得](/ja/development/api-development/getting-an-api-key)を参照) diff --git a/ja/development/comfyui-server/quick-start.mdx b/ja/development/comfyui-server/quick-start.mdx new file mode 100644 index 000000000..c586b7803 --- /dev/null +++ b/ja/development/comfyui-server/quick-start.mdx @@ -0,0 +1,248 @@ +--- +title: "クイックスタート" +description: "ComfyUI Server API を呼び出す3つのパターン" +--- + +このページでは、シンプルな HTTP 送信から WebSocket を使用したリアルタイム画像出力まで、ComfyUI Server API との3つの対話方法を紹介します。 + +すべての例は[デフォルトの SD1.5 ワークフロー](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)を使用しています。ComfyUI フロントエンドから任意のワークフローを API 形式でエクスポートできます(`File → Save (API Format)`)。 + + + これらの例は Python 標準ライブラリと `websocket-client` パッケージ(`pip install websocket-client`)を使用しています。API プロトコルは言語に依存しません — TypeScript と curl 版については [Cloud API リファレンス](/ja/development/cloud/api-reference)を参照してください。 + + +--- + +## 方法1:送信して忘れる(HTTP のみ) + +最もシンプルな方法:ワークフローを送信し、結果を待ちません。後で出力を確認するような「送りっぱなし」のジョブに適しています。 + +```python +"""basic_api_example.py — HTTP のみでワークフローを送信。""" + +import json +from urllib import request + +SERVER_ADDRESS = "127.0.0.1:8188" + + +def queue_prompt(prompt): + p = {"prompt": prompt} + data = json.dumps(p).encode("utf-8") + req = request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + request.urlopen(req) + + +if __name__ == "__main__": + # API 形式でエクスポートされたワークフローを読み込み + prompt_text = """{ + "3": { + "class_type": "KSampler", + "inputs": { + "cfg": 8, "denoise": 1, + "latent_image": ["5", 0], + "model": ["4", 0], + "negative": ["7", 0], + "positive": ["6", 0], + "sampler_name": "euler", + "scheduler": "normal", + "seed": 8566257, "steps": 20 + } + }, + "4": { + "class_type": "CheckpointLoaderSimple", + "inputs": {"ckpt_name": "v1-5-pruned-emaonly.safetensors"} + }, + "5": { + "class_type": "EmptyLatentImage", + "inputs": {"batch_size": 1, "height": 512, "width": 512} + }, + "6": { + "class_type": "CLIPTextEncode", + "inputs": {"clip": ["4", 1], "text": "masterpiece best quality man"} + }, + "7": { + "class_type": "CLIPTextEncode", + "inputs": {"clip": ["4", 1], "text": "bad hands"} + }, + "8": { + "class_type": "VAEDecode", + "inputs": {"samples": ["3", 0], "vae": ["4", 2]} + }, + "9": { + "class_type": "SaveImage", + "inputs": {"filename_prefix": "ComfyUI", "images": ["8", 0]} + } + }""" + + prompt = json.loads(prompt_text) + # 送信前に入力を変更 + prompt["3"]["inputs"]["seed"] = 5 + prompt["6"]["inputs"]["text"] = "masterpiece best quality man" + + queue_prompt(prompt) + print("Prompt submitted successfully.") +``` + + + この方法は `SaveImage` ノードを使用するため、画像はサーバーのディスクに保存されます。画像を取得するには `GET /view?filename=...` を呼び出す必要があります。 + + +--- + +## 方法2:WebSocket + History(完了を監視) + +WebSocket で実行完了を待ち、`/history` エンドポイントから結果を取得します。ほとんどのユースケースで推奨されるパターンです。 + +```python +"""websockets_api_example.py — WebSocket で実行を監視、/history からダウンロード。""" + +import websocket # pip install websocket-client +import uuid +import json +import urllib.request +import urllib.parse + +SERVER_ADDRESS = "127.0.0.1:8188" +client_id = str(uuid.uuid4()) + + +def queue_prompt(prompt, prompt_id): + p = {"prompt": prompt, "client_id": client_id, "prompt_id": prompt_id} + data = json.dumps(p).encode("utf-8") + req = urllib.request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + urllib.request.urlopen(req) + + +def get_image(filename, subfolder, folder_type): + params = urllib.parse.urlencode({ + "filename": filename, + "subfolder": subfolder, + "type": folder_type, + }) + with urllib.request.urlopen( + f"http://{SERVER_ADDRESS}/view?{params}" + ) as response: + return response.read() + + +def get_history(prompt_id): + with urllib.request.urlopen( + f"http://{SERVER_ADDRESS}/history/{prompt_id}" + ) as response: + return json.loads(response.read()) + + +def get_images(ws, prompt): + prompt_id = str(uuid.uuid4()) + queue_prompt(prompt, prompt_id) + + while True: + out = ws.recv() + if isinstance(out, str): + message = json.loads(out) + if message["type"] == "executing": + data = message["data"] + if data["node"] is None and data["prompt_id"] == prompt_id: + break # 実行完了 + # バイナリフレームはプレビュー画像 — ここではスキップ + continue + + history = get_history(prompt_id)[prompt_id] + output_images = {} + for node_id in history["outputs"]: + node_output = history["outputs"][node_id] + images_output = [] + if "images" in node_output: + for image in node_output["images"]: + image_data = get_image( + image["filename"], image["subfolder"], image["type"] + ) + images_output.append(image_data) + output_images[node_id] = images_output + return output_images +``` + + + WebSocket のバイナリフレームには生成途中のプレビュー画像が含まれています。ライブプレビュー用にデコードできます(バイナリ形式の詳細は[サーバーメッセージ](/ja/development/comfyui-server/comms_messages)ページを参照)。 + + +--- + +## 方法3:WebSocket + SaveImageWebsocket(リアルタイム画像) + +画像をディスクに保存せずに受け取りたい場合は、`SaveImageWebsocket` ノードを使用します。画像は WebSocket のバイナリフレームで直接配信されます。 + +```python +"""websockets_api_example_ws_images.py — WebSocket 経由で画像を直接受信。""" + +import websocket # pip install websocket-client +import uuid +import json +import urllib.request +import urllib.parse + +SERVER_ADDRESS = "127.0.0.1:8188" +client_id = str(uuid.uuid4()) + + +def queue_prompt(prompt): + p = {"prompt": prompt, "client_id": client_id} + data = json.dumps(p).encode("utf-8") + req = urllib.request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + return json.loads(urllib.request.urlopen(req).read()) + + +def get_images(ws, prompt): + prompt_id = queue_prompt(prompt)["prompt_id"] + output_images = {} + current_node = "" + + while True: + out = ws.recv() + if isinstance(out, str): + message = json.loads(out) + if message["type"] == "executing": + data = message["data"] + if data["prompt_id"] == prompt_id: + if data["node"] is None: + break # 実行完了 + current_node = data["node"] + else: + # バイナリフレーム — SaveImageWebsocket の画像データ + if current_node == "save_image_websocket_node": + images_output = output_images.get(current_node, []) + # 先頭8バイトはタイプ/メタデータ、残りが画像データ + images_output.append(out[8:]) + output_images[current_node] = images_output + + return output_images +``` + + + ワークフローは通常の `SaveImage` ノードの代わりに `class_type: "SaveImageWebsocket"`(組み込みノード)を使用する必要があります。 + + +--- + +## どの方法を選ぶべきか? + + + + **送って忘れる。** 即時の出力が必要ない場合に。 + + + **推奨。** 完了を待ち、結果をダウンロード。シンプルさと信頼性の最適なバランス。 + + + **リアルタイム画像。** ディスク書き込みなしで画像を受け取りたいインタラクティブなアプリに。 + + + +完全な API リファレンス(エンドポイント、ペイロード形式、エラー処理)については、[サーバールート](/ja/development/comfyui-server/comms_routes)および[サーバーメッセージ](/ja/development/comfyui-server/comms_messages)ページを参照してください。 diff --git a/ja/development/comfyui-server/server-guide.mdx b/ja/development/comfyui-server/server-guide.mdx new file mode 100644 index 000000000..193408a41 --- /dev/null +++ b/ja/development/comfyui-server/server-guide.mdx @@ -0,0 +1,65 @@ +--- +title: "ComfyUI Server API" +description: "ComfyUI をサーバーとして実行し、REST および WebSocket API でプログラムから操作" +--- + +ComfyUI はデフォルトで HTTP サーバーとしてローカルで実行されます。ブラウザを開かずに、プログラムからワークフローの送信、ファイルのアップロード、出力のダウンロード、進捗の監視が可能です。 + +## サーバーの起動 + +ComfyUI を起動すると、自動的に HTTP サーバーが起動します: + +```bash +# デフォルトのサーバーアドレス +http://127.0.0.1:8188 +``` + +ヘッドレスモード(ブラウザを開かずに)で実行: + + +```bash +# ブラウザを開かずに実行 +python main.py --headless +``` + +```bash +# カスタムポートを指定 +python main.py --port 8288 +``` + +```bash +# 全ネットワークインターフェースで待受(リモートアクセス用) +python main.py --listen 0.0.0.0 +``` + + + + 全起動オプションの一覧は `python main.py --help` を実行してください。詳細は[インストールガイド](/ja/installation/manual_install)も参照。 + + +## クイックスタート + +[クイックスタート](/ja/development/comfyui-server/quick-start)ページでは、シンプルな HTTP 送信から WebSocket を使用したリアルタイム画像出力まで、3つの一般的な API 呼び出しパターンを紹介しています。 + +## サーバー内部 + +サーバーアーキテクチャ、メッセージタイプ、ルーティングの詳細: + + + + サーバーアーキテクチャの理解(aiohttp、asyncio、メッセージパッシング)。 + + + サーバーからクライアントに送信される全メッセージタイプ。 + + + サーバーで利用可能な HTTP ルート。 + + + 上級:カスタム制御フローのための実行逆転。 + + + +## Partner Nodes の使用 + +ワークフローに有料 Partner Nodes が含まれている場合、ペイロードに API Key を含めることができます。詳細は [Partner Node API 統合](/ja/development/comfyui-server/api-key-integration) ガイドを参照してください。 diff --git a/zh/development/api-development/overview.mdx b/zh/development/api-development/overview.mdx new file mode 100644 index 000000000..54a1d4334 --- /dev/null +++ b/zh/development/api-development/overview.mdx @@ -0,0 +1,46 @@ +--- +title: "API 总览" +description: "通过不同方式编程调用 ComfyUI 的接口概览" +--- + +ComfyUI 提供多种 API 选项,取决于你希望在哪里运行工作流以及你想管理多少基础设施。本页帮助你选择合适的方式。 + +--- + +## 我应该用哪种 API? + +| | Cloud API | ComfyUI Server API | +|---|---|---| +| **在哪运行** | Comfy Cloud(托管 GPU) | 你自己的机器 | +| **GPU 管理** | 无需操心 | 自己管理硬件 | +| **模型** | 云端预装并由 Comfy 管理 | 自行下载和管理模型 | +| **认证** | `X-API-Key` 请求头 | 无(本地)或 API Key(Partner Nodes)| +| **基础地址** | `https://cloud.comfy.org` | `http://localhost:8188` | +| **协议** | REST + WebSocket | REST + WebSocket | +| **价格** | 订阅制(Creator/Pro 等级) | 免费(用你自己的算力)| +| **适合场景** | 快速集成,无需管理基础设施 | 完全控制、自定义硬件和模型 | + +两种 API 使用相同的 "API 格式" 工作流,你可以在本地开发和测试工作流,然后直接迁移到云端。 + +--- + +## 快速开始 + + + + 在 Comfy 托管的基础设施上运行工作流。无需 GPU 设置。 + + + 将 ComfyUI 作为服务器在本地运行,通过 API 调用。 + + + 在无界面或 API 驱动的工作流中使用付费 Partner Nodes。 + + + +--- + +## 前提条件 + +- 一个 Comfy Cloud 账户([注册](https://comfy.org/signup)) +- 一个 API Key(参见[获取 API Key](/zh/development/api-development/getting-an-api-key)) diff --git a/zh/development/comfyui-server/quick-start.mdx b/zh/development/comfyui-server/quick-start.mdx new file mode 100644 index 000000000..7af67db1a --- /dev/null +++ b/zh/development/comfyui-server/quick-start.mdx @@ -0,0 +1,272 @@ +--- +title: "快速入门" +description: "调用 ComfyUI Server API 的三种常见方式" +--- + +本页演示了与 ComfyUI Server API 交互的三种方式,从简单的 HTTP 提交到完整的 WebSocket 集成实时图像输出。 + +所有示例均使用[默认的 SD1.5 工作流](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)进行演示。你可以从 ComfyUI 前端导出任何工作流的 API 格式(`文件 → 另存为 (API 格式)`)。 + + + 这些示例使用 Python 标准库和 `websocket-client` 包(`pip install websocket-client`)。底层 API 协议与语言无关 — 请参阅 [Cloud API 参考](/zh/development/cloud/api-reference) 了解 TypeScript 和 curl 版本。 + + +--- + +## 方法一:提交即忘(仅 HTTP) + +最简单的方式:提交工作流,不等待结果。适用于不需要即时输出的场景。 + +```python +"""basic_api_example.py — 仅通过 HTTP 提交工作流。""" + +import json +from urllib import request + +SERVER_ADDRESS = "127.0.0.1:8188" + + +def queue_prompt(prompt): + p = {"prompt": prompt} + data = json.dumps(p).encode("utf-8") + req = request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + request.urlopen(req) + + +if __name__ == "__main__": + # 加载 API 格式导出的工作流 + prompt_text = """{ + "3": { + "class_type": "KSampler", + "inputs": { + "cfg": 8, "denoise": 1, + "latent_image": ["5", 0], + "model": ["4", 0], + "negative": ["7", 0], + "positive": ["6", 0], + "sampler_name": "euler", + "scheduler": "normal", + "seed": 8566257, "steps": 20 + } + }, + "4": { + "class_type": "CheckpointLoaderSimple", + "inputs": {"ckpt_name": "v1-5-pruned-emaonly.safetensors"} + }, + "5": { + "class_type": "EmptyLatentImage", + "inputs": {"batch_size": 1, "height": 512, "width": 512} + }, + "6": { + "class_type": "CLIPTextEncode", + "inputs": {"clip": ["4", 1], "text": "masterpiece best quality man"} + }, + "7": { + "class_type": "CLIPTextEncode", + "inputs": {"clip": ["4", 1], "text": "bad hands"} + }, + "8": { + "class_type": "VAEDecode", + "inputs": {"samples": ["3", 0], "vae": ["4", 2]} + }, + "9": { + "class_type": "SaveImage", + "inputs": {"filename_prefix": "ComfyUI", "images": ["8", 0]} + } + }""" + + prompt = json.loads(prompt_text) + # 提交前修改输入 + prompt["3"]["inputs"]["seed"] = 5 + prompt["6"]["inputs"]["text"] = "masterpiece best quality man" + + queue_prompt(prompt) + print("Prompt submitted successfully.") +``` + + + 此方法使用 `SaveImage` 节点,图片会保存到服务器磁盘。要获取图片,需要调用 `GET /view?filename=...`。 + + +--- + +## 方法二:WebSocket + History(监控执行完成) + +使用 WebSocket 等待执行完成,然后通过 `/history` 端点获取结果。这是大多数场景的推荐方式。 + +```python +"""websockets_api_example.py — 通过 WebSocket 监控执行,通过 /history 下载。""" + +import websocket # pip install websocket-client +import uuid +import json +import urllib.request +import urllib.parse + +SERVER_ADDRESS = "127.0.0.1:8188" +client_id = str(uuid.uuid4()) + + +def queue_prompt(prompt, prompt_id): + p = {"prompt": prompt, "client_id": client_id, "prompt_id": prompt_id} + data = json.dumps(p).encode("utf-8") + req = urllib.request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + urllib.request.urlopen(req) + + +def get_image(filename, subfolder, folder_type): + params = urllib.parse.urlencode({ + "filename": filename, + "subfolder": subfolder, + "type": folder_type, + }) + with urllib.request.urlopen( + f"http://{SERVER_ADDRESS}/view?{params}" + ) as response: + return response.read() + + +def get_history(prompt_id): + with urllib.request.urlopen( + f"http://{SERVER_ADDRESS}/history/{prompt_id}" + ) as response: + return json.loads(response.read()) + + +def get_images(ws, prompt): + prompt_id = str(uuid.uuid4()) + queue_prompt(prompt, prompt_id) + + while True: + out = ws.recv() + if isinstance(out, str): + message = json.loads(out) + if message["type"] == "executing": + data = message["data"] + if data["node"] is None and data["prompt_id"] == prompt_id: + break # 执行完成 + # 二进制帧是预览图片 — 此处跳过 + continue + + history = get_history(prompt_id)[prompt_id] + output_images = {} + for node_id in history["outputs"]: + node_output = history["outputs"][node_id] + images_output = [] + if "images" in node_output: + for image in node_output["images"]: + image_data = get_image( + image["filename"], image["subfolder"], image["type"] + ) + images_output.append(image_data) + output_images[node_id] = images_output + return output_images + + +if __name__ == "__main__": + # 此处省略完整工作流 JSON,请参考方法一的示例 + # prompt = json.loads(prompt_text) + # prompt["3"]["inputs"]["seed"] = 5 + # prompt["6"]["inputs"]["text"] = "masterpiece best quality man" + + # ws = websocket.WebSocket() + # ws.connect(f"ws://{SERVER_ADDRESS}/ws?clientId={client_id}") + # images = get_images(ws, prompt) + # ws.close() + pass +``` + + + WebSocket 二进制帧中的生成过程预览图片可以解码用于实时预览(二进制格式参见[服务器消息](/zh/development/comfyui-server/comms_messages)页面)。 + + +--- + +## 方法三:WebSocket 配合 SaveImageWebsocket(实时获取图片) + +如果不想将图片保存到磁盘,可以使用 `SaveImageWebsocket` 节点。图片会通过 WebSocket 二进制帧直接传送。 + +```python +"""websockets_api_example_ws_images.py — 通过 WebSocket 直接接收图片。""" + +import websocket # pip install websocket-client +import uuid +import json +import urllib.request +import urllib.parse + +SERVER_ADDRESS = "127.0.0.1:8188" +client_id = str(uuid.uuid4()) + + +def queue_prompt(prompt): + p = {"prompt": prompt, "client_id": client_id} + data = json.dumps(p).encode("utf-8") + req = urllib.request.Request( + f"http://{SERVER_ADDRESS}/prompt", data=data + ) + return json.loads(urllib.request.urlopen(req).read()) + + +def get_images(ws, prompt): + prompt_id = queue_prompt(prompt)["prompt_id"] + output_images = {} + current_node = "" + + while True: + out = ws.recv() + if isinstance(out, str): + message = json.loads(out) + if message["type"] == "executing": + data = message["data"] + if data["prompt_id"] == prompt_id: + if data["node"] is None: + break # 执行完成 + current_node = data["node"] + else: + # 二进制帧 — SaveImageWebsocket 的图片数据 + if current_node == "save_image_websocket_node": + images_output = output_images.get(current_node, []) + # 前 8 字节是类型/元数据,剩余是图片数据 + images_output.append(out[8:]) + output_images[current_node] = images_output + + return output_images + + +if __name__ == "__main__": + # prompt = json.loads(prompt_text) + # prompt["3"]["inputs"]["seed"] = 5 + + # ws = websocket.WebSocket() + # ws.connect(f"ws://{SERVER_ADDRESS}/ws?clientId={client_id}") + # images = get_images(ws, prompt) + # ws.close() + pass +``` + + + 工作流必须使用 `class_type: "SaveImageWebsocket"`(内置节点)代替普通的 `SaveImage` 节点。 + + +--- + +## 应该用哪种方法? + + + + **发送即忘。** 适用于不需要立即获取输出的场景。 + + + **推荐。** 等待完成,然后下载结果。简单性和可靠性之间最佳平衡。 + + + **实时图片。** 适用于需要图片不写磁盘直接送达的交互式应用。 + + + +完整的 API 参考(端点、负载格式、错误处理)请参阅[服务器路由](/zh/development/comfyui-server/comms_routes)和[服务器消息](/zh/development/comfyui-server/comms_messages)页面。 diff --git a/zh/development/comfyui-server/server-guide.mdx b/zh/development/comfyui-server/server-guide.mdx new file mode 100644 index 000000000..1cfa8aa07 --- /dev/null +++ b/zh/development/comfyui-server/server-guide.mdx @@ -0,0 +1,65 @@ +--- +title: "ComfyUI Server API" +description: "将 ComfyUI 作为服务器运行,通过 REST 和 WebSocket API 编程交互" +--- + +ComfyUI 默认作为 HTTP 服务器在本地运行。你可以通过编程方式调用它来提交工作流、上传文件、下载输出和监控进度 — 无需打开浏览器。 + +## 启动服务器 + +启动 ComfyUI 时,它会自动启动一个 HTTP 服务器: + +```bash +# 默认服务器地址 +http://127.0.0.1:8188 +``` + +以无界面模式运行 ComfyUI(不打开浏览器): + + +```bash +# 不打开浏览器运行 +python main.py --headless +``` + +```bash +# 指定自定义端口 +python main.py --port 8288 +``` + +```bash +# 监听所有网络接口(用于远程访问) +python main.py --listen 0.0.0.0 +``` + + + + 查看完整启动参数列表请运行 `python main.py --help`,或参阅[安装指南](/zh/installation/manual_install)。 + + +## 快速入门 + +[快速入门](/zh/development/comfyui-server/quick-start)页面展示了三种常见的 API 调用模式,从简单的 HTTP 提交到完整的 WebSocket 集成实时图像输出。 + +## 服务器内部 + +有关服务器架构、消息类型和路由处理的详细说明: + + + + 了解服务器架构(aiohttp、asyncio、消息传递)。 + + + 服务器发送给客户端的所有消息类型。 + + + 服务器上可用的 HTTP 路由。 + + + 高级:反转执行以实现自定义控制流。 + + + +## 使用 Partner Nodes + +如果你的工作流包含付费 Partner Nodes,可以在请求体中包含 API Key。详见 [Partner Node API 集成](/zh/development/comfyui-server/api-key-integration) 指南。 From ecaba20768c8737edda9f9310da57e139403ff1e Mon Sep 17 00:00:00 2001 From: ComfyUI Wiki Date: Wed, 3 Jun 2026 02:15:59 +0800 Subject: [PATCH 02/22] Add image --- .../development/export_workflow_api_format.png | Bin 0 -> 88064 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/development/export_workflow_api_format.png diff --git a/images/development/export_workflow_api_format.png b/images/development/export_workflow_api_format.png new file mode 100644 index 0000000000000000000000000000000000000000..1d7fff09de07971661a692473251864c42de6677 GIT binary patch literal 88064 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 literal 0 HcmV?d00001 From 2ee989d0db15dee21c82d2a3a115e65f6f4eab6e Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:20:18 +0800 Subject: [PATCH 03/22] Add export workflow API format image to quick-start pages --- development/comfyui-server/quick-start.mdx | 4 ++++ ja/development/comfyui-server/quick-start.mdx | 4 ++++ zh/development/comfyui-server/quick-start.mdx | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/development/comfyui-server/quick-start.mdx b/development/comfyui-server/quick-start.mdx index b4aebde9e..e0ae5a15c 100644 --- a/development/comfyui-server/quick-start.mdx +++ b/development/comfyui-server/quick-start.mdx @@ -7,6 +7,10 @@ This page demonstrates three ways to interact with the ComfyUI Server API, from All examples use the [default SD1.5 workflow](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples) for illustration. You can export any workflow in API format from the ComfyUI frontend (`File → Save (API Format)`). + + Saving a workflow in API format + + These examples use Python with the standard library and the `websocket-client` package (`pip install websocket-client`). The underlying API protocol is the same regardless of language — see the [Cloud API Reference](/development/cloud/api-reference) for TypeScript and curl equivalents. diff --git a/ja/development/comfyui-server/quick-start.mdx b/ja/development/comfyui-server/quick-start.mdx index c586b7803..36255f4ab 100644 --- a/ja/development/comfyui-server/quick-start.mdx +++ b/ja/development/comfyui-server/quick-start.mdx @@ -7,6 +7,10 @@ description: "ComfyUI Server API を呼び出す3つのパターン" すべての例は[デフォルトの SD1.5 ワークフロー](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)を使用しています。ComfyUI フロントエンドから任意のワークフローを API 形式でエクスポートできます(`File → Save (API Format)`)。 + + API 形式でワークフローを保存 + + これらの例は Python 標準ライブラリと `websocket-client` パッケージ(`pip install websocket-client`)を使用しています。API プロトコルは言語に依存しません — TypeScript と curl 版については [Cloud API リファレンス](/ja/development/cloud/api-reference)を参照してください。 diff --git a/zh/development/comfyui-server/quick-start.mdx b/zh/development/comfyui-server/quick-start.mdx index 7af67db1a..229d19075 100644 --- a/zh/development/comfyui-server/quick-start.mdx +++ b/zh/development/comfyui-server/quick-start.mdx @@ -7,6 +7,10 @@ description: "调用 ComfyUI Server API 的三种常见方式" 所有示例均使用[默认的 SD1.5 工作流](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)进行演示。你可以从 ComfyUI 前端导出任何工作流的 API 格式(`文件 → 另存为 (API 格式)`)。 + + 以 API 格式保存工作流 + + 这些示例使用 Python 标准库和 `websocket-client` 包(`pip install websocket-client`)。底层 API 协议与语言无关 — 请参阅 [Cloud API 参考](/zh/development/cloud/api-reference) 了解 TypeScript 和 curl 版本。 From b1afa719050a8f36ab79424b232c072e9e512446 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:21:54 +0800 Subject: [PATCH 04/22] Rename quick-start to api-examples for clarity --- .../comfyui-server/{quick-start.mdx => api-examples.mdx} | 0 docs.json | 6 +++--- .../comfyui-server/{quick-start.mdx => api-examples.mdx} | 0 .../comfyui-server/{quick-start.mdx => api-examples.mdx} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename development/comfyui-server/{quick-start.mdx => api-examples.mdx} (100%) rename ja/development/comfyui-server/{quick-start.mdx => api-examples.mdx} (100%) rename zh/development/comfyui-server/{quick-start.mdx => api-examples.mdx} (100%) diff --git a/development/comfyui-server/quick-start.mdx b/development/comfyui-server/api-examples.mdx similarity index 100% rename from development/comfyui-server/quick-start.mdx rename to development/comfyui-server/api-examples.mdx diff --git a/docs.json b/docs.json index a080ce66f..1baf40bb4 100644 --- a/docs.json +++ b/docs.json @@ -2276,7 +2276,7 @@ "group": "ComfyUI Server API", "pages": [ "development/comfyui-server/server-guide", - "development/comfyui-server/quick-start", + "development/comfyui-server/api-examples", "development/comfyui-server/comms_overview", "development/comfyui-server/comms_messages", "development/comfyui-server/comms_routes", @@ -4718,7 +4718,7 @@ "group": "ComfyUI Server API", "pages": [ "zh/development/comfyui-server/server-guide", - "zh/development/comfyui-server/quick-start", + "zh/development/comfyui-server/api-examples", "zh/development/comfyui-server/comms_overview", "zh/development/comfyui-server/comms_messages", "zh/development/comfyui-server/comms_routes", @@ -7160,7 +7160,7 @@ "group": "ComfyUI Server API", "pages": [ "ja/development/comfyui-server/server-guide", - "ja/development/comfyui-server/quick-start", + "ja/development/comfyui-server/api-examples", "ja/development/comfyui-server/comms_overview", "ja/development/comfyui-server/comms_messages", "ja/development/comfyui-server/comms_routes", diff --git a/ja/development/comfyui-server/quick-start.mdx b/ja/development/comfyui-server/api-examples.mdx similarity index 100% rename from ja/development/comfyui-server/quick-start.mdx rename to ja/development/comfyui-server/api-examples.mdx diff --git a/zh/development/comfyui-server/quick-start.mdx b/zh/development/comfyui-server/api-examples.mdx similarity index 100% rename from zh/development/comfyui-server/quick-start.mdx rename to zh/development/comfyui-server/api-examples.mdx From bf19136bf7256ddec7bdf21e29134bdec2966c26 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:26:03 +0800 Subject: [PATCH 05/22] Add Workflow API Format page, link from Cloud overview and API examples --- .../api-development/workflow-api-format.mdx | 99 +++++++++++++++++++ development/cloud/overview.mdx | 2 +- development/comfyui-server/api-examples.mdx | 6 +- docs.json | 3 + .../api-development/workflow-api-format.mdx | 99 +++++++++++++++++++ ja/development/cloud/overview.mdx | 2 +- .../comfyui-server/api-examples.mdx | 6 +- .../api-development/workflow-api-format.mdx | 99 +++++++++++++++++++ zh/development/cloud/overview.mdx | 2 +- .../comfyui-server/api-examples.mdx | 6 +- 10 files changed, 306 insertions(+), 18 deletions(-) create mode 100644 development/api-development/workflow-api-format.mdx create mode 100644 ja/development/api-development/workflow-api-format.mdx create mode 100644 zh/development/api-development/workflow-api-format.mdx diff --git a/development/api-development/workflow-api-format.mdx b/development/api-development/workflow-api-format.mdx new file mode 100644 index 000000000..07c86fea9 --- /dev/null +++ b/development/api-development/workflow-api-format.mdx @@ -0,0 +1,99 @@ +--- +title: "Workflow API Format" +description: "Understanding the API format for ComfyUI workflows and how to export them" +--- + +ComfyUI workflows are JSON objects that describe a graph of nodes. When calling ComfyUI programmatically — whether through the Cloud API or running your own server — the workflow must be submitted in **API format**, a specialized JSON structure that differs from the regular save format used in the browser. + +This page explains the differences and how to export your workflows correctly. + +--- + +## Save Format vs API Format + +The ComfyUI frontend can save workflows in two formats: + +| | Save Format | API Format | +|---|---|---| +| **File menu** | `File → Save` or `Ctrl+S` | `File → Export Workflow (API)` | +| **File extension** | `.json` | `.json` | +| **Node keys** | Node titles or labels | Numeric node IDs | +| **Widget values** | Included | Included | +| **Position/layout data** | Included (x, y, width) | **Excluded** | +| **Colors/groups** | Included | **Excluded** | +| **Usage** | Re-opening in the frontend | API submission | +| **Can be loaded in UI** | Yes | Yes, but without layout | + +The key difference: **API format omits UI metadata** (positions, colors, groups, node sizes) that is only needed for visual editing in the frontend. This keeps the JSON smaller and cleaner for programmatic use. + +--- + +## How to Export + +Open your workflow in the ComfyUI frontend, then navigate to `File → Export Workflow (API)`: + + + Saving a workflow in API format + + +This will download a `.json` file containing only the API-relevant data: + +```json +{ + "3": { + "inputs": { + "seed": 8566257, + "steps": 20, + "cfg": 8, + "sampler_name": "euler", + "scheduler": "normal", + "denoise": 1, + "model": ["4", 0], + "positive": ["6", 0], + "negative": ["7", 0], + "latent_image": ["5", 0] + }, + "class_type": "KSampler" + }, + "4": { + "inputs": { + "ckpt_name": "v1-5-pruned-emaonly.safetensors" + }, + "class_type": "CheckpointLoaderSimple" + }, + "8": { + "inputs": { + "samples": ["3", 0], + "vae": ["4", 2] + }, + "class_type": "VAEDecode" + } +} +``` + +Notice the structure: +- **Top-level keys** are numeric node IDs (`"3"`, `"4"`, `"8"`) +- Each node has `inputs` (with links as `[node_id, output_index]`) and `class_type` +- No `x`, `y`, `width` fields — UI-only data is stripped + +You can also load an API-format workflow back into the frontend (`File → Load` or drag-and-drop), but node positions will be auto-arranged. + +--- + +## Converting Between Formats + +If you have a save-format workflow and need it in API format, the simplest method is: + +1. Open the `.json` file using `File → Load` in the frontend +2. Export it via `File → Export Workflow (API)` + +For automated conversion, you can write a script that strips the `x`, `y`, `width` fields from each node and removes the `groups` and `extra` sections from the root JSON. + +--- + +## Related Pages + +- [APIs Overview](/development/api-development/overview) — Compare Cloud and Server API options +- [Cloud API Overview](/development/cloud/overview) — Submit API-format workflows to Comfy Cloud +- [API Examples](/development/comfyui-server/api-examples) — See API-format workflows in action +- [Getting an API Key](/development/api-development/getting-an-api-key) — Required for Cloud API and Partner Nodes diff --git a/development/cloud/overview.mdx b/development/cloud/overview.mdx index e3e5bb511..bcf70a242 100644 --- a/development/cloud/overview.mdx +++ b/development/cloud/overview.mdx @@ -80,7 +80,7 @@ response = requests.get( ### Workflows -ComfyUI workflows are JSON objects describing a graph of nodes. The API accepts workflows in the "API format" (node IDs as keys with class_type, inputs, etc.) as produced by the ComfyUI frontend's "Save (API Format)" option. +ComfyUI workflows are JSON objects describing a graph of nodes. The API accepts workflows in the [API format](/development/api-development/workflow-api-format) (node IDs as keys with class_type, inputs, etc.) as produced by the ComfyUI frontend's "Export Workflow (API)" option. ### Jobs diff --git a/development/comfyui-server/api-examples.mdx b/development/comfyui-server/api-examples.mdx index e0ae5a15c..9fd240bc2 100644 --- a/development/comfyui-server/api-examples.mdx +++ b/development/comfyui-server/api-examples.mdx @@ -5,11 +5,7 @@ description: "Three common patterns for calling the ComfyUI Server API" This page demonstrates three ways to interact with the ComfyUI Server API, from a simple HTTP submission to a full WebSocket integration with real-time image output. -All examples use the [default SD1.5 workflow](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples) for illustration. You can export any workflow in API format from the ComfyUI frontend (`File → Save (API Format)`). - - - Saving a workflow in API format - +All examples use the [default SD1.5 workflow](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples) for illustration. Before using the API, you need to export your workflow in [API format](/development/api-development/workflow-api-format). These examples use Python with the standard library and the `websocket-client` package (`pip install websocket-client`). The underlying API protocol is the same regardless of language — see the [Cloud API Reference](/development/cloud/api-reference) for TypeScript and curl equivalents. diff --git a/docs.json b/docs.json index 1baf40bb4..87f65b3b9 100644 --- a/docs.json +++ b/docs.json @@ -2263,6 +2263,7 @@ "icon": "cloud", "pages": [ "development/api-development/overview", + "development/api-development/workflow-api-format", "development/api-development/getting-an-api-key", { "group": "Cloud API", @@ -4705,6 +4706,7 @@ "icon": "cloud", "pages": [ "zh/development/api-development/overview", + "zh/development/api-development/workflow-api-format", "zh/development/api-development/getting-an-api-key", { "group": "Cloud API", @@ -7147,6 +7149,7 @@ "icon": "cloud", "pages": [ "ja/development/api-development/overview", + "ja/development/api-development/workflow-api-format", "ja/development/api-development/getting-an-api-key", { "group": "Cloud API", diff --git a/ja/development/api-development/workflow-api-format.mdx b/ja/development/api-development/workflow-api-format.mdx new file mode 100644 index 000000000..7259afc40 --- /dev/null +++ b/ja/development/api-development/workflow-api-format.mdx @@ -0,0 +1,99 @@ +--- +title: "ワークフロー API 形式" +description: "ComfyUI ワークフローの API 形式とそのエクスポート方法" +--- + +ComfyUI ワークフローは、ノードのグラフを記述する JSON オブジェクトです。Cloud API や自身のサーバーを通じてプログラムから ComfyUI を呼び出す場合、ワークフローは**API 形式**で送信する必要があります。これはブラウザで使用される通常の保存形式とは異なる専用の JSON 構造です。 + +このページでは、両者の違いとワークフローを正しくエクスポートする方法を説明します。 + +--- + +## 保存形式 vs API 形式 + +ComfyUI フロントエンドは 2 つの形式でワークフローを保存できます: + +| | 保存形式 | API 形式 | +|---|---|---| +| **メニュー** | `File → Save` または `Ctrl+S` | `File → Export Workflow (API)` | +| **ファイル拡張子** | `.json` | `.json` | +| **ノードキー** | ノードタイトルまたはラベル | 数値ノード ID | +| **ウィジェット値** | 含む | 含む | +| **位置/レイアウトデータ** | 含む (x, y, width) | **含まない** | +| **色/グループ** | 含む | **含まない** | +| **用途** | フロントエンドで再読み込み | API 送信用 | +| **UI に読み込み可能か** | 可 | 可(ただしレイアウトなし)| + +重要な違い:**API 形式は UI メタデータを省略**します(位置、色、グループ、ノードサイズ)。これらはフロントエンドでの視覚的編集にのみ必要なためです。これにより JSON がより小さく、プログラムでの使用に適した形になります。 + +--- + +## エクスポート方法 + +ComfyUI フロントエンドでワークフローを開き、`File → Export Workflow (API)` を選択します: + + + API 形式でワークフローを保存 + + +これにより、API 関連データのみを含む `.json` ファイルがダウンロードされます: + +```json +{ + "3": { + "inputs": { + "seed": 8566257, + "steps": 20, + "cfg": 8, + "sampler_name": "euler", + "scheduler": "normal", + "denoise": 1, + "model": ["4", 0], + "positive": ["6", 0], + "negative": ["7", 0], + "latent_image": ["5", 0] + }, + "class_type": "KSampler" + }, + "4": { + "inputs": { + "ckpt_name": "v1-5-pruned-emaonly.safetensors" + }, + "class_type": "CheckpointLoaderSimple" + }, + "8": { + "inputs": { + "samples": ["3", 0], + "vae": ["4", 2] + }, + "class_type": "VAEDecode" + } +} +``` + +構造に注目: +- **トップレベルのキー**は数値ノード ID(`"3"`、`"4"`、`"8"`) +- 各ノードは `inputs`(リンクは `[node_id, output_index]` 形式)と `class_type` を含む +- `x`、`y`、`width` フィールドなし — UI のみのデータは削除済み + +API 形式のワークフローをフロントエンドに読み込むこともできます(`File → Load` またはドラッグ&ドロップ)が、ノード位置は自動配置されます。 + +--- + +## 形式の変換 + +保存形式のワークフローを API 形式に変換する最も簡単な方法: + +1. フロントエンドで `File → Load` から `.json` ファイルを開く +2. `File → Export Workflow (API)` で再エクスポート + +自動化が必要な場合は、各ノードの `x`、`y`、`width` フィールドを削除し、ルート JSON から `groups` と `extra` セクションを取り除くスクリプトを作成できます。 + +--- + +## 関連ページ + +- [API 概要](/ja/development/api-development/overview) — Cloud と Server API の比較 +- [Cloud API 概要](/ja/development/cloud/overview) — Comfy Cloud に API 形式のワークフローを送信 +- [API 例](/ja/development/comfyui-server/api-examples) — API 形式ワークフローの実例 +- [API Key の取得](/ja/development/api-development/getting-an-api-key) — Cloud API と Partner Nodes に必要 diff --git a/ja/development/cloud/overview.mdx b/ja/development/cloud/overview.mdx index 34f418bd0..43c8e8474 100644 --- a/ja/development/cloud/overview.mdx +++ b/ja/development/cloud/overview.mdx @@ -82,7 +82,7 @@ response = requests.get( ### ワークフロー -ComfyUI ワークフローは、ノードのグラフを記述する JSON オブジェクトです。API は「API 形式」のワークフローを受け付けます(ノード ID をキーとし、class_type、inputs などを含む)。この形式は、ComfyUI フロントエンドの「Save (API Format)」オプションによって生成されます。 +ComfyUI ワークフローは、ノードのグラフを記述する JSON オブジェクトです。API は [API 形式](/ja/development/api-development/workflow-api-format) のワークフローを受け付けます(ノード ID をキーとし、class_type、inputs などを含む)。この形式は、ComfyUI フロントエンドの「Export Workflow (API)」オプションによって生成されます。 ### ジョブ diff --git a/ja/development/comfyui-server/api-examples.mdx b/ja/development/comfyui-server/api-examples.mdx index 36255f4ab..e8f15c757 100644 --- a/ja/development/comfyui-server/api-examples.mdx +++ b/ja/development/comfyui-server/api-examples.mdx @@ -5,11 +5,7 @@ description: "ComfyUI Server API を呼び出す3つのパターン" このページでは、シンプルな HTTP 送信から WebSocket を使用したリアルタイム画像出力まで、ComfyUI Server API との3つの対話方法を紹介します。 -すべての例は[デフォルトの SD1.5 ワークフロー](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)を使用しています。ComfyUI フロントエンドから任意のワークフローを API 形式でエクスポートできます(`File → Save (API Format)`)。 - - - API 形式でワークフローを保存 - +すべての例は[デフォルトの SD1.5 ワークフロー](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)を使用しています。API を使用する前に、ワークフローを [API 形式](/ja/development/api-development/workflow-api-format) でエクスポートする必要があります。 これらの例は Python 標準ライブラリと `websocket-client` パッケージ(`pip install websocket-client`)を使用しています。API プロトコルは言語に依存しません — TypeScript と curl 版については [Cloud API リファレンス](/ja/development/cloud/api-reference)を参照してください。 diff --git a/zh/development/api-development/workflow-api-format.mdx b/zh/development/api-development/workflow-api-format.mdx new file mode 100644 index 000000000..7462d17b0 --- /dev/null +++ b/zh/development/api-development/workflow-api-format.mdx @@ -0,0 +1,99 @@ +--- +title: "工作流 API 格式" +description: "理解 ComfyUI 工作流的 API 格式以及如何导出" +--- + +ComfyUI 工作流是描述节点图的 JSON 对象。当你通过 Cloud API 或自建服务器以编程方式调用 ComfyUI 时,工作流必须以 **API 格式**提交——这是一种与浏览器中使用的常规保存格式不同的专用 JSON 结构。 + +本页解释两者的区别以及如何正确导出你的工作流。 + +--- + +## 保存格式 vs API 格式 + +ComfyUI 前端可以以两种格式保存工作流: + +| | 保存格式 | API 格式 | +|---|---|---| +| **菜单路径** | `文件 → 保存` 或 `Ctrl+S` | `文件 → 导出工作流 (API)` | +| **文件后缀** | `.json` | `.json` | +| **节点键** | 节点标题或标签 | 数字节点 ID | +| **组件值** | 包含 | 包含 | +| **位置/布局数据** | 包含 (x, y, width) | **不包含** | +| **颜色/分组** | 包含 | **不包含** | +| **用途** | 在前端重新打开 | API 提交 | +| **可否加载到 UI** | 可以 | 可以,但没有布局 | + +关键区别:**API 格式省略了 UI 元数据**(位置、颜色、分组、节点尺寸),这些仅在前端可视化编辑时需要。这使 JSON 更小、更简洁,适合程序化使用。 + +--- + +## 如何导出 + +在 ComfyUI 前端打开工作流,然后导航到 `文件 → 导出工作流 (API)`: + + + 以 API 格式保存工作流 + + +这将下载一个只包含 API 相关数据的 `.json` 文件: + +```json +{ + "3": { + "inputs": { + "seed": 8566257, + "steps": 20, + "cfg": 8, + "sampler_name": "euler", + "scheduler": "normal", + "denoise": 1, + "model": ["4", 0], + "positive": ["6", 0], + "negative": ["7", 0], + "latent_image": ["5", 0] + }, + "class_type": "KSampler" + }, + "4": { + "inputs": { + "ckpt_name": "v1-5-pruned-emaonly.safetensors" + }, + "class_type": "CheckpointLoaderSimple" + }, + "8": { + "inputs": { + "samples": ["3", 0], + "vae": ["4", 2] + }, + "class_type": "VAEDecode" + } +} +``` + +注意结构: +- **顶层键**是数字节点 ID(如 `"3"`、`"4"`、`"8"`) +- 每个节点包含 `inputs`(链接格式为 `[node_id, output_index]`)和 `class_type` +- 没有 `x`、`y`、`width` 字段——仅 UI 相关的数据已被移除 + +你也可以将 API 格式的工作流加载回前端(`文件 → 加载` 或拖拽),但节点位置会被自动排列。 + +--- + +## 格式转换 + +如果你有一个保存格式的工作流需要转为 API 格式,最简单的方法是: + +1. 在前端通过 `文件 → 加载` 打开 `.json` 文件 +2. 通过 `文件 → 导出工作流 (API)` 重新导出 + +如果需要自动化转换,可以编写脚本去除每个节点的 `x`、`y`、`width` 字段,并移除根 JSON 中的 `groups` 和 `extra` 部分。 + +--- + +## 相关页面 + +- [API 总览](/zh/development/api-development/overview) — 比较 Cloud 和 Server API 选项 +- [Cloud API 概述](/zh/development/cloud/overview) — 向 Comfy Cloud 提交 API 格式的工作流 +- [API 示例](/zh/development/comfyui-server/api-examples) — 查看 API 格式工作流的使用示例 +- [获取 API Key](/zh/development/api-development/getting-an-api-key) — Cloud API 和 Partner Nodes 所需 diff --git a/zh/development/cloud/overview.mdx b/zh/development/cloud/overview.mdx index cd8a6db8e..6f8725373 100644 --- a/zh/development/cloud/overview.mdx +++ b/zh/development/cloud/overview.mdx @@ -80,7 +80,7 @@ response = requests.get( ### 工作流 -ComfyUI 工作流是描述节点图的 JSON 对象。API 接受"API 格式"的工作流(以节点 ID 为键,包含 class_type、inputs 等),该格式由 ComfyUI 前端的"Save (API Format)"选项导出。 +ComfyUI 工作流是描述节点图的 JSON 对象。API 接受 [API 格式](/zh/development/api-development/workflow-api-format) 的工作流(以节点 ID 为键,包含 class_type、inputs 等),该格式由 ComfyUI 前端的"导出工作流 (API)"选项导出。 ### 任务 diff --git a/zh/development/comfyui-server/api-examples.mdx b/zh/development/comfyui-server/api-examples.mdx index 229d19075..7f04e05d7 100644 --- a/zh/development/comfyui-server/api-examples.mdx +++ b/zh/development/comfyui-server/api-examples.mdx @@ -5,11 +5,7 @@ description: "调用 ComfyUI Server API 的三种常见方式" 本页演示了与 ComfyUI Server API 交互的三种方式,从简单的 HTTP 提交到完整的 WebSocket 集成实时图像输出。 -所有示例均使用[默认的 SD1.5 工作流](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)进行演示。你可以从 ComfyUI 前端导出任何工作流的 API 格式(`文件 → 另存为 (API 格式)`)。 - - - 以 API 格式保存工作流 - +所有示例均使用[默认的 SD1.5 工作流](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples)进行演示。使用 API 之前,你需要先导出工作流的 [API 格式](/zh/development/api-development/workflow-api-format)。 这些示例使用 Python 标准库和 `websocket-client` 包(`pip install websocket-client`)。底层 API 协议与语言无关 — 请参阅 [Cloud API 参考](/zh/development/cloud/api-reference) 了解 TypeScript 和 curl 版本。 From 738bbd25630bb7c66cdcac06193f0ae552ca1b3b Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:27:54 +0800 Subject: [PATCH 06/22] Reorder sidebar: move utility pages after API groups --- docs.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs.json b/docs.json index 87f65b3b9..3484c4c35 100644 --- a/docs.json +++ b/docs.json @@ -2263,8 +2263,6 @@ "icon": "cloud", "pages": [ "development/api-development/overview", - "development/api-development/workflow-api-format", - "development/api-development/getting-an-api-key", { "group": "Cloud API", "pages": [ @@ -2284,7 +2282,9 @@ "development/comfyui-server/execution_model_inversion_guide" ] }, - "development/comfyui-server/api-key-integration" + "development/comfyui-server/api-key-integration", + "development/api-development/workflow-api-format", + "development/api-development/getting-an-api-key" ] }, { @@ -4706,8 +4706,6 @@ "icon": "cloud", "pages": [ "zh/development/api-development/overview", - "zh/development/api-development/workflow-api-format", - "zh/development/api-development/getting-an-api-key", { "group": "Cloud API", "pages": [ @@ -4727,7 +4725,9 @@ "zh/development/comfyui-server/execution_model_inversion_guide" ] }, - "zh/development/comfyui-server/api-key-integration" + "zh/development/comfyui-server/api-key-integration", + "zh/development/api-development/workflow-api-format", + "zh/development/api-development/getting-an-api-key" ] }, { @@ -7149,8 +7149,6 @@ "icon": "cloud", "pages": [ "ja/development/api-development/overview", - "ja/development/api-development/workflow-api-format", - "ja/development/api-development/getting-an-api-key", { "group": "Cloud API", "pages": [ @@ -7170,7 +7168,9 @@ "ja/development/comfyui-server/execution_model_inversion_guide" ] }, - "ja/development/comfyui-server/api-key-integration" + "ja/development/comfyui-server/api-key-integration", + "ja/development/api-development/workflow-api-format", + "ja/development/api-development/getting-an-api-key" ] }, { From 150ab5e8b5b0467f54edfac6594880f6157b4b06 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:30:28 +0800 Subject: [PATCH 07/22] Fix Server API base URL: use generic description instead of hardcoded localhost --- development/api-development/overview.mdx | 2 +- ja/development/api-development/overview.mdx | 2 +- zh/development/api-development/overview.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/development/api-development/overview.mdx b/development/api-development/overview.mdx index 4214f3d36..a3c844343 100644 --- a/development/api-development/overview.mdx +++ b/development/api-development/overview.mdx @@ -15,7 +15,7 @@ ComfyUI offers several API options depending on where you want to run your workf | **GPU management** | Handled for you | You manage your own hardware | | **Models** | Pre-installed and managed by Comfy | You download and manage locally | | **Authentication** | `X-API-Key` header (Comfy Cloud account) | None (local) or API key for Partner Nodes | -| **Base URL** | `https://cloud.comfy.org` | `http://localhost:8188` | +| **Base URL** | `https://cloud.comfy.org` | Your server URL (e.g. `http://localhost:8188`) | | **Protocol** | REST + WebSocket | REST + WebSocket | | **Pricing** | Subscription-based (Creator/Pro tiers) | Free (your own compute) | | **Best for** | Quick integration, no infrastructure | Full control, custom hardware & models | diff --git a/ja/development/api-development/overview.mdx b/ja/development/api-development/overview.mdx index 57eac569e..cad6af5be 100644 --- a/ja/development/api-development/overview.mdx +++ b/ja/development/api-development/overview.mdx @@ -15,7 +15,7 @@ ComfyUI には、ワークフローを実行する場所や管理したいイン | **GPU 管理** | 不要 | 自分で管理 | | **モデル** | クラウドにプリインストール | 自分でダウンロード・管理 | | **認証** | `X-API-Key` ヘッダー | 不要(ローカル)または API Key(Partner Nodes) | -| **ベースURL** | `https://cloud.comfy.org` | `http://localhost:8188` | +| **ベースURL** | `https://cloud.comfy.org` | サーバーURL(例:`http://localhost:8188`)| | **プロトコル** | REST + WebSocket | REST + WebSocket | | **料金** | サブスクリプション制 | 無料(自分の計算リソース)| | **用途** | 迅速な統合、インフラ不要 | 完全制御、カスタムハードウェア・モデル | diff --git a/zh/development/api-development/overview.mdx b/zh/development/api-development/overview.mdx index 54a1d4334..22272aabb 100644 --- a/zh/development/api-development/overview.mdx +++ b/zh/development/api-development/overview.mdx @@ -15,7 +15,7 @@ ComfyUI 提供多种 API 选项,取决于你希望在哪里运行工作流以 | **GPU 管理** | 无需操心 | 自己管理硬件 | | **模型** | 云端预装并由 Comfy 管理 | 自行下载和管理模型 | | **认证** | `X-API-Key` 请求头 | 无(本地)或 API Key(Partner Nodes)| -| **基础地址** | `https://cloud.comfy.org` | `http://localhost:8188` | +| **基础地址** | `https://cloud.comfy.org` | 你自己的服务器地址(例如 `http://localhost:8188`)| | **协议** | REST + WebSocket | REST + WebSocket | | **价格** | 订阅制(Creator/Pro 等级) | 免费(用你自己的算力)| | **适合场景** | 快速集成,无需管理基础设施 | 完全控制、自定义硬件和模型 | From a28897b03c726c81aee13c15580433d310f64d3e Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:31:58 +0800 Subject: [PATCH 08/22] Link API format to workflow-api-format page in overview --- development/api-development/overview.mdx | 2 +- ja/development/api-development/overview.mdx | 2 +- zh/development/api-development/overview.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/development/api-development/overview.mdx b/development/api-development/overview.mdx index a3c844343..c382a9ccd 100644 --- a/development/api-development/overview.mdx +++ b/development/api-development/overview.mdx @@ -20,7 +20,7 @@ ComfyUI offers several API options depending on where you want to run your workf | **Pricing** | Subscription-based (Creator/Pro tiers) | Free (your own compute) | | **Best for** | Quick integration, no infrastructure | Full control, custom hardware & models | -Both APIs use the same workflow format ("API format"), so you can develop and test workflows locally and move them to the cloud without changes. +Both APIs use the same workflow format ([API format](/development/api-development/workflow-api-format)), so you can develop and test workflows locally and move them to the cloud without changes. --- diff --git a/ja/development/api-development/overview.mdx b/ja/development/api-development/overview.mdx index cad6af5be..964705513 100644 --- a/ja/development/api-development/overview.mdx +++ b/ja/development/api-development/overview.mdx @@ -20,7 +20,7 @@ ComfyUI には、ワークフローを実行する場所や管理したいイン | **料金** | サブスクリプション制 | 無料(自分の計算リソース)| | **用途** | 迅速な統合、インフラ不要 | 完全制御、カスタムハードウェア・モデル | -両 API は同じワークフロー形式("API 形式")を使用するため、ローカルで開発・テストしてからクラウドに移行しても変更は不要です。 +両 API は同じワークフロー形式([API 形式](/ja/development/api-development/workflow-api-format))を使用するため、ローカルで開発・テストしてからクラウドに移行しても変更は不要です。 --- diff --git a/zh/development/api-development/overview.mdx b/zh/development/api-development/overview.mdx index 22272aabb..a2c494123 100644 --- a/zh/development/api-development/overview.mdx +++ b/zh/development/api-development/overview.mdx @@ -20,7 +20,7 @@ ComfyUI 提供多种 API 选项,取决于你希望在哪里运行工作流以 | **价格** | 订阅制(Creator/Pro 等级) | 免费(用你自己的算力)| | **适合场景** | 快速集成,无需管理基础设施 | 完全控制、自定义硬件和模型 | -两种 API 使用相同的 "API 格式" 工作流,你可以在本地开发和测试工作流,然后直接迁移到云端。 +两种 API 使用相同的 [API 格式](/zh/development/api-development/workflow-api-format) 工作流,你可以在本地开发和测试工作流,然后直接迁移到云端。 --- From 770091abbab8f60fc8d3d971616a113575fd19fc Mon Sep 17 00:00:00 2001 From: ComfyUI Wiki Date: Wed, 3 Jun 2026 02:35:08 +0800 Subject: [PATCH 09/22] Update API format workflow example --- .../api-development/workflow-api-format.mdx | 99 ++++++++++++++++--- .../api-development/workflow-api-format.mdx | 99 ++++++++++++++++--- .../api-development/workflow-api-format.mdx | 99 ++++++++++++++++--- 3 files changed, 264 insertions(+), 33 deletions(-) diff --git a/development/api-development/workflow-api-format.mdx b/development/api-development/workflow-api-format.mdx index 07c86fea9..c99c0ef61 100644 --- a/development/api-development/workflow-api-format.mdx +++ b/development/api-development/workflow-api-format.mdx @@ -42,31 +42,108 @@ This will download a `.json` file containing only the API-relevant data: { "3": { "inputs": { - "seed": 8566257, + "seed": 156680208700286, "steps": 20, "cfg": 8, "sampler_name": "euler", "scheduler": "normal", "denoise": 1, - "model": ["4", 0], - "positive": ["6", 0], - "negative": ["7", 0], - "latent_image": ["5", 0] + "model": [ + "4", + 0 + ], + "positive": [ + "6", + 0 + ], + "negative": [ + "7", + 0 + ], + "latent_image": [ + "5", + 0 + ] }, - "class_type": "KSampler" + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } }, "4": { "inputs": { - "ckpt_name": "v1-5-pruned-emaonly.safetensors" + "ckpt_name": "v1-5-pruned-emaonly-fp16.safetensors" }, - "class_type": "CheckpointLoaderSimple" + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "5": { + "inputs": { + "width": 512, + "height": 512, + "batch_size": 1 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "6": { + "inputs": { + "text": "beautiful scenery nature glass bottle landscape, , purple galaxy bottle,", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "7": { + "inputs": { + "text": "text, watermark", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } }, "8": { "inputs": { - "samples": ["3", 0], - "vae": ["4", 2] + "samples": [ + "3", + 0 + ], + "vae": [ + "4", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "ComfyUI", + "images": [ + "8", + 0 + ] }, - "class_type": "VAEDecode" + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } } } ``` diff --git a/ja/development/api-development/workflow-api-format.mdx b/ja/development/api-development/workflow-api-format.mdx index 7259afc40..71ee1d7e8 100644 --- a/ja/development/api-development/workflow-api-format.mdx +++ b/ja/development/api-development/workflow-api-format.mdx @@ -42,31 +42,108 @@ ComfyUI フロントエンドでワークフローを開き、`File → Export W { "3": { "inputs": { - "seed": 8566257, + "seed": 156680208700286, "steps": 20, "cfg": 8, "sampler_name": "euler", "scheduler": "normal", "denoise": 1, - "model": ["4", 0], - "positive": ["6", 0], - "negative": ["7", 0], - "latent_image": ["5", 0] + "model": [ + "4", + 0 + ], + "positive": [ + "6", + 0 + ], + "negative": [ + "7", + 0 + ], + "latent_image": [ + "5", + 0 + ] }, - "class_type": "KSampler" + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } }, "4": { "inputs": { - "ckpt_name": "v1-5-pruned-emaonly.safetensors" + "ckpt_name": "v1-5-pruned-emaonly-fp16.safetensors" }, - "class_type": "CheckpointLoaderSimple" + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "5": { + "inputs": { + "width": 512, + "height": 512, + "batch_size": 1 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "6": { + "inputs": { + "text": "beautiful scenery nature glass bottle landscape, , purple galaxy bottle,", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "7": { + "inputs": { + "text": "text, watermark", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } }, "8": { "inputs": { - "samples": ["3", 0], - "vae": ["4", 2] + "samples": [ + "3", + 0 + ], + "vae": [ + "4", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "ComfyUI", + "images": [ + "8", + 0 + ] }, - "class_type": "VAEDecode" + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } } } ``` diff --git a/zh/development/api-development/workflow-api-format.mdx b/zh/development/api-development/workflow-api-format.mdx index 7462d17b0..e3fed5358 100644 --- a/zh/development/api-development/workflow-api-format.mdx +++ b/zh/development/api-development/workflow-api-format.mdx @@ -42,31 +42,108 @@ ComfyUI 前端可以以两种格式保存工作流: { "3": { "inputs": { - "seed": 8566257, + "seed": 156680208700286, "steps": 20, "cfg": 8, "sampler_name": "euler", "scheduler": "normal", "denoise": 1, - "model": ["4", 0], - "positive": ["6", 0], - "negative": ["7", 0], - "latent_image": ["5", 0] + "model": [ + "4", + 0 + ], + "positive": [ + "6", + 0 + ], + "negative": [ + "7", + 0 + ], + "latent_image": [ + "5", + 0 + ] }, - "class_type": "KSampler" + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } }, "4": { "inputs": { - "ckpt_name": "v1-5-pruned-emaonly.safetensors" + "ckpt_name": "v1-5-pruned-emaonly-fp16.safetensors" }, - "class_type": "CheckpointLoaderSimple" + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "5": { + "inputs": { + "width": 512, + "height": 512, + "batch_size": 1 + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "6": { + "inputs": { + "text": "beautiful scenery nature glass bottle landscape, , purple galaxy bottle,", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "7": { + "inputs": { + "text": "text, watermark", + "clip": [ + "4", + 1 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } }, "8": { "inputs": { - "samples": ["3", 0], - "vae": ["4", 2] + "samples": [ + "3", + 0 + ], + "vae": [ + "4", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "ComfyUI", + "images": [ + "8", + 0 + ] }, - "class_type": "VAEDecode" + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } } } ``` From a3934a39f6935b7059382cc785b31564d72b4ef5 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:36:36 +0800 Subject: [PATCH 10/22] Remove verbose structure explanation from workflow-api-format pages --- development/api-development/workflow-api-format.mdx | 7 ------- ja/development/api-development/workflow-api-format.mdx | 7 ------- zh/development/api-development/workflow-api-format.mdx | 7 ------- 3 files changed, 21 deletions(-) diff --git a/development/api-development/workflow-api-format.mdx b/development/api-development/workflow-api-format.mdx index c99c0ef61..cca4e86d9 100644 --- a/development/api-development/workflow-api-format.mdx +++ b/development/api-development/workflow-api-format.mdx @@ -148,13 +148,6 @@ This will download a `.json` file containing only the API-relevant data: } ``` -Notice the structure: -- **Top-level keys** are numeric node IDs (`"3"`, `"4"`, `"8"`) -- Each node has `inputs` (with links as `[node_id, output_index]`) and `class_type` -- No `x`, `y`, `width` fields — UI-only data is stripped - -You can also load an API-format workflow back into the frontend (`File → Load` or drag-and-drop), but node positions will be auto-arranged. - --- ## Converting Between Formats diff --git a/ja/development/api-development/workflow-api-format.mdx b/ja/development/api-development/workflow-api-format.mdx index 71ee1d7e8..9f1883cd5 100644 --- a/ja/development/api-development/workflow-api-format.mdx +++ b/ja/development/api-development/workflow-api-format.mdx @@ -148,13 +148,6 @@ ComfyUI フロントエンドでワークフローを開き、`File → Export W } ``` -構造に注目: -- **トップレベルのキー**は数値ノード ID(`"3"`、`"4"`、`"8"`) -- 各ノードは `inputs`(リンクは `[node_id, output_index]` 形式)と `class_type` を含む -- `x`、`y`、`width` フィールドなし — UI のみのデータは削除済み - -API 形式のワークフローをフロントエンドに読み込むこともできます(`File → Load` またはドラッグ&ドロップ)が、ノード位置は自動配置されます。 - --- ## 形式の変換 diff --git a/zh/development/api-development/workflow-api-format.mdx b/zh/development/api-development/workflow-api-format.mdx index e3fed5358..65eafb04a 100644 --- a/zh/development/api-development/workflow-api-format.mdx +++ b/zh/development/api-development/workflow-api-format.mdx @@ -148,13 +148,6 @@ ComfyUI 前端可以以两种格式保存工作流: } ``` -注意结构: -- **顶层键**是数字节点 ID(如 `"3"`、`"4"`、`"8"`) -- 每个节点包含 `inputs`(链接格式为 `[node_id, output_index]`)和 `class_type` -- 没有 `x`、`y`、`width` 字段——仅 UI 相关的数据已被移除 - -你也可以将 API 格式的工作流加载回前端(`文件 → 加载` 或拖拽),但节点位置会被自动排列。 - --- ## 格式转换 From 3e8eaf59735d24f9a82d1230a67d40e0675ce27a Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:37:44 +0800 Subject: [PATCH 11/22] =?UTF-8?q?Fix=20titles:=20quick-start=20=E2=86=92?= =?UTF-8?q?=20API=20Examples=20(EN/ZH/JA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- development/comfyui-server/api-examples.mdx | 2 +- ja/development/comfyui-server/api-examples.mdx | 2 +- zh/development/comfyui-server/api-examples.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/development/comfyui-server/api-examples.mdx b/development/comfyui-server/api-examples.mdx index 9fd240bc2..b5b041077 100644 --- a/development/comfyui-server/api-examples.mdx +++ b/development/comfyui-server/api-examples.mdx @@ -1,5 +1,5 @@ --- -title: "Quick Start" +title: "API Examples" description: "Three common patterns for calling the ComfyUI Server API" --- diff --git a/ja/development/comfyui-server/api-examples.mdx b/ja/development/comfyui-server/api-examples.mdx index e8f15c757..edd4f7258 100644 --- a/ja/development/comfyui-server/api-examples.mdx +++ b/ja/development/comfyui-server/api-examples.mdx @@ -1,5 +1,5 @@ --- -title: "クイックスタート" +title: "API 例" description: "ComfyUI Server API を呼び出す3つのパターン" --- diff --git a/zh/development/comfyui-server/api-examples.mdx b/zh/development/comfyui-server/api-examples.mdx index 7f04e05d7..700c734bb 100644 --- a/zh/development/comfyui-server/api-examples.mdx +++ b/zh/development/comfyui-server/api-examples.mdx @@ -1,5 +1,5 @@ --- -title: "快速入门" +title: "API 示例" description: "调用 ComfyUI Server API 的三种常见方式" --- From 74d6095ab4ad3cd54f7f50dafa5880efb8ce69ef Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:44:39 +0800 Subject: [PATCH 12/22] Merge server-guide into comms_overview, remove redundant page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Merge server startup guide and navigation cards into comms_overview - Rename comms_overview title to 'Server Overview' with full entry content - Delete server-guide.mdx (EN/ZH/JA) - Reorder sidebar: Overview → Routes → API Examples → Messages → Inversion - Update links in api-development/overview --- development/api-development/overview.mdx | 2 +- development/comfyui-server/comms_overview.mdx | 70 ++++++++++++++++--- development/comfyui-server/server-guide.mdx | 65 ----------------- docs.json | 15 ++-- ja/development/api-development/overview.mdx | 2 +- .../comfyui-server/comms_overview.mdx | 65 +++++++++++++++-- .../comfyui-server/server-guide.mdx | 65 ----------------- zh/development/api-development/overview.mdx | 2 +- .../comfyui-server/comms_overview.mdx | 70 ++++++++++++++++--- .../comfyui-server/server-guide.mdx | 65 ----------------- 10 files changed, 191 insertions(+), 230 deletions(-) delete mode 100644 development/comfyui-server/server-guide.mdx delete mode 100644 ja/development/comfyui-server/server-guide.mdx delete mode 100644 zh/development/comfyui-server/server-guide.mdx diff --git a/development/api-development/overview.mdx b/development/api-development/overview.mdx index c382a9ccd..80fd87dae 100644 --- a/development/api-development/overview.mdx +++ b/development/api-development/overview.mdx @@ -30,7 +30,7 @@ Both APIs use the same workflow format ([API format](/development/api-developmen Run workflows on Comfy's managed infrastructure. No GPU setup required. - + Run ComfyUI as a server on your own machine and call it via API. diff --git a/development/comfyui-server/comms_overview.mdx b/development/comfyui-server/comms_overview.mdx index a847a4272..3229accd7 100644 --- a/development/comfyui-server/comms_overview.mdx +++ b/development/comfyui-server/comms_overview.mdx @@ -1,18 +1,70 @@ --- title: "Server Overview" +description: "Run ComfyUI as a server and interact with it programmatically via REST and WebSocket APIs" --- -## Overview +ComfyUI runs as an HTTP server on your machine by default. You can call it programmatically to submit workflows, upload files, download outputs, and monitor progress — all without opening the browser. + +## Starting the Server + +When you launch ComfyUI, it automatically starts an HTTP server at `http://127.0.0.1:8188`. + +To run ComfyUI as a headless server (no browser): + + +```bash +# Run without opening the browser +python main.py --headless +``` + +```bash +# Specify a custom port +python main.py --port 8288 +``` + +```bash +# Listen on all network interfaces (for remote access) +python main.py --listen 0.0.0.0 +``` + + + + For a full list of startup flags, run `python main.py --help` or see the [install guide](/installation/manual_install#basic-usage). + + +## Key Pages in This Section + + + + Available HTTP endpoints for submitting workflows, uploading files, and querying status. + + + Code examples for calling the API: HTTP-only, WebSocket + History, and SaveImageWebsocket. + + + WebSocket message types the server sends to the client during execution. + + + Advanced: invert execution for custom control flows. + + + +## Using Partner Nodes + +If your workflow contains paid Partner Nodes, you can include your API key in the payload. See the [Partner Node API Integration](/development/comfyui-server/api-key-integration) guide for details. + +--- + +## How the Server Works The Comfy server runs on top of the [aiohttp framework](https://docs.aiohttp.org/), which in turn uses [asyncio](https://pypi.org/project/asyncio/). -Messages from the server to the client are sent by socket messages through the `send_sync` method of the server, -which is an instance of `PromptServer` (defined in `server.py`). They are processed -by a socket event listener registered in `api.js`. See [messages](/development/comfyui-server/comms_messages). +Messages from the server to the client are sent by socket messages through the `send_sync` method of the server, which is an instance of `PromptServer` (defined in `server.py`). They are processed by a socket event listener registered in `api.js`. See [messages](/development/comfyui-server/comms_messages). -Messages from the client to the server are sent by the `api.fetchApi()` method defined in `api.js`, -and are handled by http routes defined by the server. See [routes](/development/comfyui-server/comms_routes). +Messages from the client to the server are sent by the `api.fetchApi()` method defined in `api.js`, and are handled by HTTP routes defined by the server. See [routes](/development/comfyui-server/comms_routes). -The client submits the whole workflow (widget values and all) when you queue a request. -The server does not receive any changes you make after you send a request to the queue. -If you want to modify server behavior during execution, you'll need routes. + + The client submits the whole workflow (widget values and all) when you queue a request. + The server does not receive any changes you make after you send a request to the queue. + If you want to modify server behavior during execution, you'll need routes. + diff --git a/development/comfyui-server/server-guide.mdx b/development/comfyui-server/server-guide.mdx deleted file mode 100644 index 1a9f84b0c..000000000 --- a/development/comfyui-server/server-guide.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "ComfyUI Server API" -description: "Run ComfyUI as a server and interact with it programmatically via REST and WebSocket APIs" ---- - -ComfyUI runs as an HTTP server on your machine by default. You can call it programmatically to submit workflows, upload files, download outputs, and monitor progress — all without opening the browser. - -## Starting the Server - -When you launch ComfyUI, it automatically starts an HTTP server: - -```bash -# Default server address -http://127.0.0.1:8188 -``` - -To run ComfyUI as a headless server (no browser): - - -```bash -# Run without opening the browser -python main.py --headless -``` - -```bash -# Specify a custom port -python main.py --port 8288 -``` - -```bash -# Listen on all network interfaces (for remote access) -python main.py --listen 0.0.0.0 -``` - - - - For a full list of available startup flags, run `python main.py --help` or see the [install guide](/installation/manual_install#basic-usage). - - -## Quick Start - -The [Quick Start](/development/comfyui-server/quick-start) page shows three common patterns for calling the API, from a simple HTTP submission to a full WebSocket integration with real-time image output. - -## Server Internals - -For details on the server architecture, message types, and route handling: - - - - Understand the server's architecture (aiohttp, asyncio, message passing). - - - All message types the server sends to the client. - - - Available HTTP routes you can call on the server. - - - Advanced: invert execution for custom control flows. - - - -## Using Partner Nodes - -If your workflow contains paid Partner Nodes, you can include your API key in the payload. See the [Partner Node API Integration](/development/comfyui-server/api-key-integration) guide for details. diff --git a/docs.json b/docs.json index 3484c4c35..6311e931a 100644 --- a/docs.json +++ b/docs.json @@ -2274,11 +2274,10 @@ { "group": "ComfyUI Server API", "pages": [ - "development/comfyui-server/server-guide", - "development/comfyui-server/api-examples", "development/comfyui-server/comms_overview", - "development/comfyui-server/comms_messages", "development/comfyui-server/comms_routes", + "development/comfyui-server/api-examples", + "development/comfyui-server/comms_messages", "development/comfyui-server/execution_model_inversion_guide" ] }, @@ -4717,11 +4716,10 @@ { "group": "ComfyUI Server API", "pages": [ - "zh/development/comfyui-server/server-guide", - "zh/development/comfyui-server/api-examples", "zh/development/comfyui-server/comms_overview", - "zh/development/comfyui-server/comms_messages", "zh/development/comfyui-server/comms_routes", + "zh/development/comfyui-server/api-examples", + "zh/development/comfyui-server/comms_messages", "zh/development/comfyui-server/execution_model_inversion_guide" ] }, @@ -7160,11 +7158,10 @@ { "group": "ComfyUI Server API", "pages": [ - "ja/development/comfyui-server/server-guide", - "ja/development/comfyui-server/api-examples", "ja/development/comfyui-server/comms_overview", - "ja/development/comfyui-server/comms_messages", "ja/development/comfyui-server/comms_routes", + "ja/development/comfyui-server/api-examples", + "ja/development/comfyui-server/comms_messages", "ja/development/comfyui-server/execution_model_inversion_guide" ] }, diff --git a/ja/development/api-development/overview.mdx b/ja/development/api-development/overview.mdx index 964705513..736b8abeb 100644 --- a/ja/development/api-development/overview.mdx +++ b/ja/development/api-development/overview.mdx @@ -30,7 +30,7 @@ ComfyUI には、ワークフローを実行する場所や管理したいイン Comfy のマネージドインフラ上でワークフローを実行。GPU 設定は不要。 - + 自分のマシンで ComfyUI をサーバーとして実行し、API 経由で呼び出し。 diff --git a/ja/development/comfyui-server/comms_overview.mdx b/ja/development/comfyui-server/comms_overview.mdx index 62e5625c0..3707b9ad7 100644 --- a/ja/development/comfyui-server/comms_overview.mdx +++ b/ja/development/comfyui-server/comms_overview.mdx @@ -1,15 +1,68 @@ --- title: "サーバー概要" -translationSourceHash: eb8a8f9c -translationFrom: development/comfyui-server/comms_overview.mdx, zh/development/comfyui-server/comms_overview.mdx +description: "ComfyUI をサーバーとして実行し、REST および WebSocket API でプログラムから操作" --- -## 概要 +ComfyUI はデフォルトで HTTP サーバーとしてローカルで実行されます。ブラウザを開かずに、プログラムからワークフローの送信、ファイルのアップロード、出力のダウンロード、進捗の監視が可能です。 + +## サーバーの起動 + +ComfyUI を起動すると、自動的に HTTP サーバーが `http://127.0.0.1:8188` で起動します。 + +ヘッドレスモード(ブラウザを開かずに)で実行: + + +```bash +# ブラウザを開かずに実行 +python main.py --headless +``` + +```bash +# カスタムポートを指定 +python main.py --port 8288 +``` + +```bash +# 全ネットワークインターフェースで待受(リモートアクセス用) +python main.py --listen 0.0.0.0 +``` + + + + 全起動オプションの一覧は `python main.py --help` を実行してください。[インストールガイド](/ja/installation/manual_install#basic-usage)も参照。 + + +## このセクションの主要ページ + + + + ワークフロー送信、ファイルアップロード、ステータス確認用の HTTP エンドポイント。 + + + API 呼び出しのコード例:HTTP のみ、WebSocket + History、SaveImageWebsocket。 + + + 実行中にサーバーからクライアントに送信される WebSocket メッセージタイプ。 + + + 上級:カスタム制御フローのための実行逆転。 + + + +## Partner Nodes の使用 + +ワークフローに有料 Partner Nodes が含まれている場合、ペイロードに API Key を含めることができます。詳細は [Partner Node API 統合](/ja/development/comfyui-server/api-key-integration) ガイドを参照してください。 + +--- + +## サーバーの仕組み Comfy サーバーは [aiohttp フレームワーク](https://docs.aiohttp.org/) 上で動作しており、このフレームワークはさらに [asyncio](https://pypi.org/project/asyncio/) を使用しています。 -サーバーからクライアントへのメッセージは、サーバーの `send_sync` メソッドを通じてソケットメッセージとして送信されます。このサーバーは `server.py` で定義された `PromptServer` のインスタンスです。これらのメッセージは `api.js` に登録されたソケットイベントリスナーによって処理されます。詳細は [メッセージ](/development/comfyui-server/comms_messages) を参照してください。 +サーバーからクライアントへのメッセージは、`send_sync` メソッド(`server.py` で定義された `PromptServer` のインスタンス)を通じてソケットメッセージとして送信されます。これらのメッセージは `api.js` に登録されたソケットイベントリスナーによって処理されます。詳細は[メッセージ](/ja/development/comfyui-server/comms_messages)を参照。 -クライアントからサーバーへのメッセージは、`api.js` で定義された `api.fetchApi()` メソッドによって送信され、サーバーによって定義された HTTP ルートによって処理されます。詳細は [ルート](/development/comfyui-server/comms_routes) を参照してください。 +クライアントからサーバーへのメッセージは、`api.js` で定義された `api.fetchApi()` メソッドによって送信され、サーバーによって定義された HTTP ルートによって処理されます。詳細は[ルート](/ja/development/comfyui-server/comms_routes)を参照。 -リクエストをキューに追加すると、クライアントはワークフロー全体(ウィジェット値などすべて)を送信します。キューにリクエストを送信した後に変更を加えても、サーバーはその変更を受け取りません。実行中にサーバーの動作を変更したい場合は、ルートを使用する必要があります。 \ No newline at end of file + + リクエストをキューに追加すると、クライアントはワークフロー全体(ウィジェット値などすべて)を送信します。キューに送信した後に加えた変更はサーバーに反映されません。実行中にサーバーの動作を変更したい場合は、ルートを使用してください。 + diff --git a/ja/development/comfyui-server/server-guide.mdx b/ja/development/comfyui-server/server-guide.mdx deleted file mode 100644 index 193408a41..000000000 --- a/ja/development/comfyui-server/server-guide.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "ComfyUI Server API" -description: "ComfyUI をサーバーとして実行し、REST および WebSocket API でプログラムから操作" ---- - -ComfyUI はデフォルトで HTTP サーバーとしてローカルで実行されます。ブラウザを開かずに、プログラムからワークフローの送信、ファイルのアップロード、出力のダウンロード、進捗の監視が可能です。 - -## サーバーの起動 - -ComfyUI を起動すると、自動的に HTTP サーバーが起動します: - -```bash -# デフォルトのサーバーアドレス -http://127.0.0.1:8188 -``` - -ヘッドレスモード(ブラウザを開かずに)で実行: - - -```bash -# ブラウザを開かずに実行 -python main.py --headless -``` - -```bash -# カスタムポートを指定 -python main.py --port 8288 -``` - -```bash -# 全ネットワークインターフェースで待受(リモートアクセス用) -python main.py --listen 0.0.0.0 -``` - - - - 全起動オプションの一覧は `python main.py --help` を実行してください。詳細は[インストールガイド](/ja/installation/manual_install)も参照。 - - -## クイックスタート - -[クイックスタート](/ja/development/comfyui-server/quick-start)ページでは、シンプルな HTTP 送信から WebSocket を使用したリアルタイム画像出力まで、3つの一般的な API 呼び出しパターンを紹介しています。 - -## サーバー内部 - -サーバーアーキテクチャ、メッセージタイプ、ルーティングの詳細: - - - - サーバーアーキテクチャの理解(aiohttp、asyncio、メッセージパッシング)。 - - - サーバーからクライアントに送信される全メッセージタイプ。 - - - サーバーで利用可能な HTTP ルート。 - - - 上級:カスタム制御フローのための実行逆転。 - - - -## Partner Nodes の使用 - -ワークフローに有料 Partner Nodes が含まれている場合、ペイロードに API Key を含めることができます。詳細は [Partner Node API 統合](/ja/development/comfyui-server/api-key-integration) ガイドを参照してください。 diff --git a/zh/development/api-development/overview.mdx b/zh/development/api-development/overview.mdx index a2c494123..9f823af80 100644 --- a/zh/development/api-development/overview.mdx +++ b/zh/development/api-development/overview.mdx @@ -30,7 +30,7 @@ ComfyUI 提供多种 API 选项,取决于你希望在哪里运行工作流以 在 Comfy 托管的基础设施上运行工作流。无需 GPU 设置。 - + 将 ComfyUI 作为服务器在本地运行,通过 API 调用。 diff --git a/zh/development/comfyui-server/comms_overview.mdx b/zh/development/comfyui-server/comms_overview.mdx index 8366cb9d8..8c206faff 100644 --- a/zh/development/comfyui-server/comms_overview.mdx +++ b/zh/development/comfyui-server/comms_overview.mdx @@ -1,16 +1,70 @@ --- -title: "服务器概览" +title: "服务器概述" +description: "将 ComfyUI 作为服务器运行,通过 REST 和 WebSocket API 编程交互" --- -## 概览 +ComfyUI 默认作为 HTTP 服务器在本地运行。你可以通过编程方式调用它来提交工作流、上传文件、下载输出和监控进度 — 无需打开浏览器。 + +## 启动服务器 + +启动 ComfyUI 时会自动启动 HTTP 服务器,地址为 `http://127.0.0.1:8188`。 + +以无界面模式运行(不打开浏览器): + + +```bash +# 不打开浏览器运行 +python main.py --headless +``` + +```bash +# 指定自定义端口 +python main.py --port 8288 +``` + +```bash +# 监听所有网络接口(用于远程访问) +python main.py --listen 0.0.0.0 +``` + + + + 查看完整启动参数请运行 `python main.py --help`,或参阅[安装指南](/zh/installation/manual_install#basic-usage)。 + + +## 本部分的关键页面 + + + + 可用的 HTTP 端点:提交工作流、上传文件、查询状态。 + + + 调用 API 的代码示例:仅 HTTP、WebSocket + History、SaveImageWebsocket。 + + + 执行过程中服务器发送给客户端的 WebSocket 消息类型。 + + + 高级:反转执行以实现自定义控制流。 + + + +## 使用 Partner Nodes + +如果工作流包含付费 Partner Nodes,可在请求体中包含 API Key。详见 [Partner Node API 集成](/zh/development/comfyui-server/api-key-integration) 指南。 + +--- + +## 服务器工作原理 Comfy 服务器构建于 [aiohttp 框架](https://docs.aiohttp.org/) 基础之上,该框架则依赖于 [asyncio](https://pypi.org/project/asyncio/) 库。 -服务器向客户端发送消息时,会通过其 `send_sync` 方法(该服务器是 `server.py` 文件中定义的 `PromptServer` 类的一个实例)以 `socket` 消息的形式进行。这些消息由注册在 `api.js` 文件中的 `socket` 事件监听器负责处理。更多详情请参阅[消息传递](/zh/development/comfyui-server/comms_messages)。 +服务器向客户端发送消息时,会通过 `send_sync` 方法(`server.py` 中定义的 `PromptServer` 类实例)以 socket 消息形式发送。这些消息由 `api.js` 中注册的 socket 事件监听器处理。参见[消息传递](/zh/development/comfyui-server/comms_messages)。 -客户端向服务器发送消息时,则通过 `api.js` 文件中定义的 `api.fetchApi()` 方法进行,这些请求由服务器端设定的 HTTP 路由负责处理。更多详情请参阅[路由机制](/zh/development/comfyui-server/comms_routes)部分。 +客户端向服务器发送消息时,通过 `api.js` 中定义的 `api.fetchApi()` 方法,由服务器端设定的 HTTP 路由处理。参见[路由机制](/zh/development/comfyui-server/comms_routes)。 -当您将一个请求加入处理队列时,客户端会提交完整的工作流信息(包括所有小部件的当前值)。 -一旦请求进入队列,服务器将不会接收您在此之后对工作流所做的任何修改。 -若希望在程序执行过程中动态调整服务器行为,则需要借助路由机制来实现。 -python3 .github/scripts/validate-links.py \ No newline at end of file + + 当请求加入队列时,客户端会提交完整的工作流(包括所有组件的当前值)。 + 一旦请求进入队列,服务器不会接收之后对工作流的任何修改。 + 若需在执行过程中动态调整服务器行为,需要使用路由机制。 + diff --git a/zh/development/comfyui-server/server-guide.mdx b/zh/development/comfyui-server/server-guide.mdx deleted file mode 100644 index 1cfa8aa07..000000000 --- a/zh/development/comfyui-server/server-guide.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "ComfyUI Server API" -description: "将 ComfyUI 作为服务器运行,通过 REST 和 WebSocket API 编程交互" ---- - -ComfyUI 默认作为 HTTP 服务器在本地运行。你可以通过编程方式调用它来提交工作流、上传文件、下载输出和监控进度 — 无需打开浏览器。 - -## 启动服务器 - -启动 ComfyUI 时,它会自动启动一个 HTTP 服务器: - -```bash -# 默认服务器地址 -http://127.0.0.1:8188 -``` - -以无界面模式运行 ComfyUI(不打开浏览器): - - -```bash -# 不打开浏览器运行 -python main.py --headless -``` - -```bash -# 指定自定义端口 -python main.py --port 8288 -``` - -```bash -# 监听所有网络接口(用于远程访问) -python main.py --listen 0.0.0.0 -``` - - - - 查看完整启动参数列表请运行 `python main.py --help`,或参阅[安装指南](/zh/installation/manual_install)。 - - -## 快速入门 - -[快速入门](/zh/development/comfyui-server/quick-start)页面展示了三种常见的 API 调用模式,从简单的 HTTP 提交到完整的 WebSocket 集成实时图像输出。 - -## 服务器内部 - -有关服务器架构、消息类型和路由处理的详细说明: - - - - 了解服务器架构(aiohttp、asyncio、消息传递)。 - - - 服务器发送给客户端的所有消息类型。 - - - 服务器上可用的 HTTP 路由。 - - - 高级:反转执行以实现自定义控制流。 - - - -## 使用 Partner Nodes - -如果你的工作流包含付费 Partner Nodes,可以在请求体中包含 API Key。详见 [Partner Node API 集成](/zh/development/comfyui-server/api-key-integration) 指南。 From 615c7f2b4a9a54bb826f5736d4ed783f0a0c9bb3 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:48:09 +0800 Subject: [PATCH 13/22] Fix remaining server-guide link in development/overview --- development/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/overview.mdx b/development/overview.mdx index d54afd3d5..37e28e732 100644 --- a/development/overview.mdx +++ b/development/overview.mdx @@ -9,7 +9,7 @@ ComfyUI is a modular GenAI inference engine that can be run as a server, accesse Run ComfyUI in your own environment and expose it as an API endpoint. Learn about the WebSocket message protocol, available routes, and execution modes. - + Run ComfyUI as a server on your own machine. Start, configure, and call it via REST and WebSocket APIs. From 5f7baa094e666a72e535f6fb928f0a79d68440f9 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:53:48 +0800 Subject: [PATCH 14/22] Add source links to GitHub for each API example (EN/ZH/JA) --- development/comfyui-server/api-examples.mdx | 6 ++++++ ja/development/comfyui-server/api-examples.mdx | 6 ++++++ zh/development/comfyui-server/api-examples.mdx | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/development/comfyui-server/api-examples.mdx b/development/comfyui-server/api-examples.mdx index b5b041077..8bfd94961 100644 --- a/development/comfyui-server/api-examples.mdx +++ b/development/comfyui-server/api-examples.mdx @@ -15,6 +15,8 @@ All examples use the [default SD1.5 workflow](https://github.com/Comfy-Org/Comfy ## Method 1: Submit and Forget (HTTP only) +Source: [`basic_api_example.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/basic_api_example.py) + The simplest approach: submit a workflow and don't wait for results. Useful for fire-and-forget jobs where you check outputs later. ```python @@ -94,6 +96,8 @@ if __name__ == "__main__": ## Method 2: WebSocket + History (Monitor Completion) +Source: [`websockets_api_example.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/websockets_api_example.py) + Use WebSocket to wait for execution to finish, then retrieve outputs via the `/history` endpoint. This is the recommended pattern for most use cases. ```python @@ -201,6 +205,8 @@ if __name__ == "__main__": ## Method 3: WebSocket with SaveImageWebsocket (Real-time Images) +Source: [`websockets_api_example_ws_images.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/websockets_api_example_ws_images.py) + For scenarios where you don't want images saved to disk, use the `SaveImageWebsocket` node. Images are delivered directly via WebSocket binary frames. ```python diff --git a/ja/development/comfyui-server/api-examples.mdx b/ja/development/comfyui-server/api-examples.mdx index edd4f7258..f354eb413 100644 --- a/ja/development/comfyui-server/api-examples.mdx +++ b/ja/development/comfyui-server/api-examples.mdx @@ -15,6 +15,8 @@ description: "ComfyUI Server API を呼び出す3つのパターン" ## 方法1:送信して忘れる(HTTP のみ) +ソース:[`basic_api_example.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/basic_api_example.py) + 最もシンプルな方法:ワークフローを送信し、結果を待ちません。後で出力を確認するような「送りっぱなし」のジョブに適しています。 ```python @@ -94,6 +96,8 @@ if __name__ == "__main__": ## 方法2:WebSocket + History(完了を監視) +ソース:[`websockets_api_example.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/websockets_api_example.py) + WebSocket で実行完了を待ち、`/history` エンドポイントから結果を取得します。ほとんどのユースケースで推奨されるパターンです。 ```python @@ -175,6 +179,8 @@ def get_images(ws, prompt): ## 方法3:WebSocket + SaveImageWebsocket(リアルタイム画像) +ソース:[`websockets_api_example_ws_images.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/websockets_api_example_ws_images.py) + 画像をディスクに保存せずに受け取りたい場合は、`SaveImageWebsocket` ノードを使用します。画像は WebSocket のバイナリフレームで直接配信されます。 ```python diff --git a/zh/development/comfyui-server/api-examples.mdx b/zh/development/comfyui-server/api-examples.mdx index 700c734bb..e5d1d896b 100644 --- a/zh/development/comfyui-server/api-examples.mdx +++ b/zh/development/comfyui-server/api-examples.mdx @@ -15,6 +15,8 @@ description: "调用 ComfyUI Server API 的三种常见方式" ## 方法一:提交即忘(仅 HTTP) +源码:[`basic_api_example.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/basic_api_example.py) + 最简单的方式:提交工作流,不等待结果。适用于不需要即时输出的场景。 ```python @@ -94,6 +96,8 @@ if __name__ == "__main__": ## 方法二:WebSocket + History(监控执行完成) +源码:[`websockets_api_example.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/websockets_api_example.py) + 使用 WebSocket 等待执行完成,然后通过 `/history` 端点获取结果。这是大多数场景的推荐方式。 ```python @@ -188,6 +192,8 @@ if __name__ == "__main__": ## 方法三:WebSocket 配合 SaveImageWebsocket(实时获取图片) +源码:[`websockets_api_example_ws_images.py`](https://github.com/Comfy-Org/ComfyUI/blob/master/script_examples/websockets_api_example_ws_images.py) + 如果不想将图片保存到磁盘,可以使用 `SaveImageWebsocket` 节点。图片会通过 WebSocket 二进制帧直接传送。 ```python From 0460b9e90c000ce1cc385fa0b7c5b14be3fcd1d7 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 02:56:15 +0800 Subject: [PATCH 15/22] Remove irrelevant 'Login with API Key' card from api-key-integration --- development/comfyui-server/api-key-integration.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/development/comfyui-server/api-key-integration.mdx b/development/comfyui-server/api-key-integration.mdx index d7f3efa44..7a1f5f35f 100644 --- a/development/comfyui-server/api-key-integration.mdx +++ b/development/comfyui-server/api-key-integration.mdx @@ -27,9 +27,7 @@ Using your ComfyUI Account API Key to call paid Partner Nodes requires: To use your ComfyUI Account API Key to call paid Partner Nodes, you need to first register an account on [ComfyUI Platform](https://platform.comfy.org/login) and [create an API key](/development/api-development/getting-an-api-key) - -Please refer to the User Interface section to learn how to login with API Key - + You need to ensure your ComfyUI account has sufficient credits to test the corresponding features. From 2e6f20d7818aa3d293fdf729ed025849b29a2ba8 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 03:00:24 +0800 Subject: [PATCH 16/22] =?UTF-8?q?Update=20icons:=20ComfyUI=20APIs=20?= =?UTF-8?q?=E2=86=92=20computer,=20ComfyUI=20Server=20API=20=E2=86=92=20se?= =?UTF-8?q?rver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs.json b/docs.json index 6311e931a..10b25d3e5 100644 --- a/docs.json +++ b/docs.json @@ -2260,7 +2260,7 @@ { "group": "ComfyUI APIs", - "icon": "cloud", + "icon": "computer", "pages": [ "development/api-development/overview", { @@ -2273,6 +2273,7 @@ }, { "group": "ComfyUI Server API", + "icon": "server", "pages": [ "development/comfyui-server/comms_overview", "development/comfyui-server/comms_routes", @@ -4702,7 +4703,7 @@ { "group": "ComfyUI APIs", - "icon": "cloud", + "icon": "computer", "pages": [ "zh/development/api-development/overview", { @@ -4715,6 +4716,7 @@ }, { "group": "ComfyUI Server API", + "icon": "server", "pages": [ "zh/development/comfyui-server/comms_overview", "zh/development/comfyui-server/comms_routes", @@ -7144,7 +7146,7 @@ { "group": "ComfyUI APIs", - "icon": "cloud", + "icon": "computer", "pages": [ "ja/development/api-development/overview", { @@ -7157,6 +7159,7 @@ }, { "group": "ComfyUI Server API", + "icon": "server", "pages": [ "ja/development/comfyui-server/comms_overview", "ja/development/comfyui-server/comms_routes", From 7f0ea4b9ac1e453b148cc0e11417c9d0c10ede99 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 03:01:55 +0800 Subject: [PATCH 17/22] Simplify Cloud API overview: replace GetApiKey snippet with link to centralized getting-an-api-key page --- development/cloud/overview.mdx | 6 +----- ja/development/cloud/overview.mdx | 6 +----- zh/development/cloud/overview.mdx | 6 +----- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/development/cloud/overview.mdx b/development/cloud/overview.mdx index bcf70a242..092b47f6a 100644 --- a/development/cloud/overview.mdx +++ b/development/cloud/overview.mdx @@ -37,11 +37,7 @@ All API requests require an API key passed via the `X-API-Key` header. ### Getting an API Key - - - - Keep your API key secure. Never commit it to version control or share it publicly. - +See [Getting an API Key](/development/api-development/getting-an-api-key) for instructions on creating and managing your Cloud API key. ### Using the API Key diff --git a/ja/development/cloud/overview.mdx b/ja/development/cloud/overview.mdx index 43c8e8474..1ded1afb0 100644 --- a/ja/development/cloud/overview.mdx +++ b/ja/development/cloud/overview.mdx @@ -39,11 +39,7 @@ https://cloud.comfy.org ### API キーの取得 - - - - API キーは安全に保管してください。バージョン管理システムにコミットしたり、公開で共有したりしないでください。 - +API キーの作成と管理方法については、[API キーの取得](/ja/development/api-development/getting-an-api-key)を参照してください。 ### API キーの使用 diff --git a/zh/development/cloud/overview.mdx b/zh/development/cloud/overview.mdx index 6f8725373..02825b558 100644 --- a/zh/development/cloud/overview.mdx +++ b/zh/development/cloud/overview.mdx @@ -37,11 +37,7 @@ https://cloud.comfy.org ### 获取 API 密钥 - - - - 请妥善保管您的 API 密钥。切勿将其提交到版本控制系统或公开分享。 - +请参阅[获取 API 密钥](/zh/development/api-development/getting-an-api-key)了解如何创建和管理 Cloud API 密钥。 ### 使用 API 密钥 From 37db1b9bd9cad20351f6e890a915977cfcdded65 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 03:06:24 +0800 Subject: [PATCH 18/22] Add cloud icon to Cloud API group (EN/ZH/JA) --- docs.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs.json b/docs.json index 10b25d3e5..a30c5bcb5 100644 --- a/docs.json +++ b/docs.json @@ -2265,6 +2265,7 @@ "development/api-development/overview", { "group": "Cloud API", + "icon": "cloud", "pages": [ "development/cloud/overview", "development/cloud/api-reference", @@ -4708,6 +4709,7 @@ "zh/development/api-development/overview", { "group": "Cloud API", + "icon": "cloud", "pages": [ "zh/development/cloud/overview", "zh/development/cloud/api-reference", @@ -7151,6 +7153,7 @@ "ja/development/api-development/overview", { "group": "Cloud API", + "icon": "cloud", "pages": [ "ja/development/cloud/overview", "ja/development/cloud/api-reference", From 68da0d90727d8d8c2eba9185cd8ed21097781bbf Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 03:08:29 +0800 Subject: [PATCH 19/22] Add icons to all ComfyUI APIs pages in frontmatter (EN/ZH/JA) --- development/api-development/getting-an-api-key.mdx | 1 + development/api-development/overview.mdx | 1 + development/api-development/workflow-api-format.mdx | 1 + development/cloud/api-reference.mdx | 1 + development/cloud/openapi.mdx | 1 + development/comfyui-server/api-key-integration.mdx | 1 + development/comfyui-server/comms_messages.mdx | 1 + development/comfyui-server/comms_routes.mdx | 1 + development/comfyui-server/execution_model_inversion_guide.mdx | 1 + ja/development/api-development/getting-an-api-key.mdx | 1 + ja/development/api-development/overview.mdx | 1 + ja/development/api-development/workflow-api-format.mdx | 1 + ja/development/cloud/api-reference.mdx | 1 + ja/development/cloud/openapi.mdx | 1 + ja/development/comfyui-server/api-key-integration.mdx | 1 + ja/development/comfyui-server/comms_messages.mdx | 1 + ja/development/comfyui-server/comms_routes.mdx | 1 + .../comfyui-server/execution_model_inversion_guide.mdx | 1 + zh/development/api-development/getting-an-api-key.mdx | 1 + zh/development/api-development/overview.mdx | 1 + zh/development/api-development/workflow-api-format.mdx | 1 + zh/development/cloud/api-reference.mdx | 1 + zh/development/cloud/openapi.mdx | 1 + zh/development/comfyui-server/api-key-integration.mdx | 1 + zh/development/comfyui-server/comms_messages.mdx | 1 + zh/development/comfyui-server/comms_routes.mdx | 1 + .../comfyui-server/execution_model_inversion_guide.mdx | 1 + 27 files changed, 27 insertions(+) diff --git a/development/api-development/getting-an-api-key.mdx b/development/api-development/getting-an-api-key.mdx index 670599049..72323c668 100644 --- a/development/api-development/getting-an-api-key.mdx +++ b/development/api-development/getting-an-api-key.mdx @@ -1,6 +1,7 @@ --- title: 'Getting an API Key' description: 'Learn how to create and manage your Comfy Platform API Key for accessing Cloud APIs, Partner Nodes, and more.' +icon: 'key' --- import GetApiKey from '/snippets/get-api-key.mdx' diff --git a/development/api-development/overview.mdx b/development/api-development/overview.mdx index 80fd87dae..3dda341b0 100644 --- a/development/api-development/overview.mdx +++ b/development/api-development/overview.mdx @@ -1,6 +1,7 @@ --- title: "APIs Overview" description: "An overview of the different ways to interact with ComfyUI programmatically" +icon: "list-tree" --- ComfyUI offers several API options depending on where you want to run your workflows and how much infrastructure you want to manage. This page helps you choose the right approach. diff --git a/development/api-development/workflow-api-format.mdx b/development/api-development/workflow-api-format.mdx index cca4e86d9..fbca73eb0 100644 --- a/development/api-development/workflow-api-format.mdx +++ b/development/api-development/workflow-api-format.mdx @@ -1,6 +1,7 @@ --- title: "Workflow API Format" description: "Understanding the API format for ComfyUI workflows and how to export them" +icon: "file-json" --- ComfyUI workflows are JSON objects that describe a graph of nodes. When calling ComfyUI programmatically — whether through the Cloud API or running your own server — the workflow must be submitted in **API format**, a specialized JSON structure that differs from the regular save format used in the browser. diff --git a/development/cloud/api-reference.mdx b/development/cloud/api-reference.mdx index ad51ab161..13cbf6659 100644 --- a/development/cloud/api-reference.mdx +++ b/development/cloud/api-reference.mdx @@ -1,6 +1,7 @@ --- title: "Cloud API Reference" description: "Complete API reference with code examples for Comfy Cloud" +icon: "book-open" --- import PollJobCompletion from '/snippets/cloud/poll-job-completion.mdx' diff --git a/development/cloud/openapi.mdx b/development/cloud/openapi.mdx index 64047969c..fe431f9a1 100644 --- a/development/cloud/openapi.mdx +++ b/development/cloud/openapi.mdx @@ -1,6 +1,7 @@ --- title: "OpenAPI Specification" description: "Machine-readable OpenAPI specification for Comfy Cloud API" +icon: "file-text" openapi: "/openapi-cloud.yaml" --- diff --git a/development/comfyui-server/api-key-integration.mdx b/development/comfyui-server/api-key-integration.mdx index 7a1f5f35f..6f3e1fc93 100644 --- a/development/comfyui-server/api-key-integration.mdx +++ b/development/comfyui-server/api-key-integration.mdx @@ -2,6 +2,7 @@ title: 'ComfyUI Account API Key Integration' description: 'This article explains how to use ComfyUI Account API Key to call paid Partner Nodes in headless mode' sidebarTitle: 'Partner Node API Integration' +icon: 'plug' --- Starting from [PR #8041](https://github.com/Comfy-Org/ComfyUI/pull/8041), ComfyUI supports directly using built-in paid Partner Nodes through your ComfyUI Account API Key, without requiring a specific frontend interface (you can even run without a frontend). diff --git a/development/comfyui-server/comms_messages.mdx b/development/comfyui-server/comms_messages.mdx index fd04a86c5..cbb02d2d7 100644 --- a/development/comfyui-server/comms_messages.mdx +++ b/development/comfyui-server/comms_messages.mdx @@ -1,5 +1,6 @@ --- title: "Messages" +icon: "message-square" --- ## Messages diff --git a/development/comfyui-server/comms_routes.mdx b/development/comfyui-server/comms_routes.mdx index 92b8a1e41..ba2122665 100644 --- a/development/comfyui-server/comms_routes.mdx +++ b/development/comfyui-server/comms_routes.mdx @@ -1,5 +1,6 @@ --- title: "Routes" +icon: "route" --- ## Routes diff --git a/development/comfyui-server/execution_model_inversion_guide.mdx b/development/comfyui-server/execution_model_inversion_guide.mdx index 6378df658..bfad82b9c 100644 --- a/development/comfyui-server/execution_model_inversion_guide.mdx +++ b/development/comfyui-server/execution_model_inversion_guide.mdx @@ -1,5 +1,6 @@ --- title: "Execution Model Inversion Guide" +icon: "git-branch" --- [PR #2666](https://github.com/Comfy-Org/ComfyUI/pull/2666) inverts the execution model from a back-to-front recursive model to a front-to-back topological sort. While most custom nodes should continue to "just work", this page is intended to serve as a guide for custom node creators to the things that *could* break. diff --git a/ja/development/api-development/getting-an-api-key.mdx b/ja/development/api-development/getting-an-api-key.mdx index 3287b6402..8194e8dd2 100644 --- a/ja/development/api-development/getting-an-api-key.mdx +++ b/ja/development/api-development/getting-an-api-key.mdx @@ -1,6 +1,7 @@ --- title: 'API キーの取得' description: 'Cloud API、Partner Node などにアクセスするための Comfy Platform API キーの作成と管理方法を学びます。' +icon: 'key' --- import GetApiKey from '/snippets/ja/get-api-key.mdx' diff --git a/ja/development/api-development/overview.mdx b/ja/development/api-development/overview.mdx index 736b8abeb..57ef002a0 100644 --- a/ja/development/api-development/overview.mdx +++ b/ja/development/api-development/overview.mdx @@ -1,6 +1,7 @@ --- title: "API 概要" description: "ComfyUI をプログラムから操作するための様々なAPIの概要" +icon: "list-tree" --- ComfyUI には、ワークフローを実行する場所や管理したいインフラストラクチャに応じて、複数の API オプションがあります。このページは適切な方法を選ぶのに役立ちます。 diff --git a/ja/development/api-development/workflow-api-format.mdx b/ja/development/api-development/workflow-api-format.mdx index 9f1883cd5..4d87afb88 100644 --- a/ja/development/api-development/workflow-api-format.mdx +++ b/ja/development/api-development/workflow-api-format.mdx @@ -1,6 +1,7 @@ --- title: "ワークフロー API 形式" description: "ComfyUI ワークフローの API 形式とそのエクスポート方法" +icon: "file-json" --- ComfyUI ワークフローは、ノードのグラフを記述する JSON オブジェクトです。Cloud API や自身のサーバーを通じてプログラムから ComfyUI を呼び出す場合、ワークフローは**API 形式**で送信する必要があります。これはブラウザで使用される通常の保存形式とは異なる専用の JSON 構造です。 diff --git a/ja/development/cloud/api-reference.mdx b/ja/development/cloud/api-reference.mdx index 6180c4401..7ea11a63a 100644 --- a/ja/development/cloud/api-reference.mdx +++ b/ja/development/cloud/api-reference.mdx @@ -1,6 +1,7 @@ --- title: "Cloud API リファレンス" description: "Comfy Cloud の完全な API リファレンスとコード例" +icon: "book-open" translationSourceHash: ef54c171 translationFrom: development/cloud/api-reference.mdx, zh/development/cloud/api-reference.mdx translationMismatches: diff --git a/ja/development/cloud/openapi.mdx b/ja/development/cloud/openapi.mdx index db8e331f0..cabd9bbc1 100644 --- a/ja/development/cloud/openapi.mdx +++ b/ja/development/cloud/openapi.mdx @@ -1,6 +1,7 @@ --- title: "OpenAPI 仕様" description: "Comfy Cloud API の機械可読な OpenAPI 仕様" +icon: "file-text" openapi: "/openapi-cloud.yaml" translationSourceHash: 04c13223 translationFrom: development/cloud/openapi.mdx, zh/development/cloud/openapi.mdx diff --git a/ja/development/comfyui-server/api-key-integration.mdx b/ja/development/comfyui-server/api-key-integration.mdx index 1fae778a3..adf1df939 100644 --- a/ja/development/comfyui-server/api-key-integration.mdx +++ b/ja/development/comfyui-server/api-key-integration.mdx @@ -2,6 +2,7 @@ title: 'ComfyUI アカウント API キー統合' description: 'この記事では、ヘッドレスモードで有料 API ノードを呼び出すために ComfyUI アカウント API キーを使用する方法について説明します' sidebarTitle: 'Partner Node API 統合' +icon: 'plug' translationSourceHash: 6d4591f9 translationFrom: development/comfyui-server/api-key-integration.mdx, zh/development/comfyui-server/api-key-integration.mdx --- diff --git a/ja/development/comfyui-server/comms_messages.mdx b/ja/development/comfyui-server/comms_messages.mdx index 435ef0dad..bd31b7990 100644 --- a/ja/development/comfyui-server/comms_messages.mdx +++ b/ja/development/comfyui-server/comms_messages.mdx @@ -1,5 +1,6 @@ --- title: "メッセージ" +icon: "message-square" translationSourceHash: 7229c28c translationFrom: development/comfyui-server/comms_messages.mdx, zh/development/comfyui-server/comms_messages.mdx --- diff --git a/ja/development/comfyui-server/comms_routes.mdx b/ja/development/comfyui-server/comms_routes.mdx index b24308155..c34c21cb4 100644 --- a/ja/development/comfyui-server/comms_routes.mdx +++ b/ja/development/comfyui-server/comms_routes.mdx @@ -1,5 +1,6 @@ --- title: "ルート" +icon: "route" translationSourceHash: 5064650f translationFrom: development/comfyui-server/comms_routes.mdx, zh/development/comfyui-server/comms_routes.mdx --- diff --git a/ja/development/comfyui-server/execution_model_inversion_guide.mdx b/ja/development/comfyui-server/execution_model_inversion_guide.mdx index b4ff08208..8d133c982 100644 --- a/ja/development/comfyui-server/execution_model_inversion_guide.mdx +++ b/ja/development/comfyui-server/execution_model_inversion_guide.mdx @@ -1,5 +1,6 @@ --- title: "実行モデル反転ガイド" +icon: "git-branch" translationSourceHash: dfad1b9a translationFrom: development/comfyui-server/execution_model_inversion_guide.mdx, zh/development/comfyui-server/execution_model_inversion_guide.mdx --- diff --git a/zh/development/api-development/getting-an-api-key.mdx b/zh/development/api-development/getting-an-api-key.mdx index 74ed5aa84..fdbb5b88c 100644 --- a/zh/development/api-development/getting-an-api-key.mdx +++ b/zh/development/api-development/getting-an-api-key.mdx @@ -1,6 +1,7 @@ --- title: '获取 API Key' description: '了解如何创建和管理你的 Comfy Platform API Key,用于访问 Cloud API、Partner Nodes 等。' +icon: 'key' --- import GetApiKey from '/snippets/zh/get-api-key.mdx' diff --git a/zh/development/api-development/overview.mdx b/zh/development/api-development/overview.mdx index 9f823af80..ebd10768b 100644 --- a/zh/development/api-development/overview.mdx +++ b/zh/development/api-development/overview.mdx @@ -1,6 +1,7 @@ --- title: "API 总览" description: "通过不同方式编程调用 ComfyUI 的接口概览" +icon: "list-tree" --- ComfyUI 提供多种 API 选项,取决于你希望在哪里运行工作流以及你想管理多少基础设施。本页帮助你选择合适的方式。 diff --git a/zh/development/api-development/workflow-api-format.mdx b/zh/development/api-development/workflow-api-format.mdx index 65eafb04a..7e3a18323 100644 --- a/zh/development/api-development/workflow-api-format.mdx +++ b/zh/development/api-development/workflow-api-format.mdx @@ -1,6 +1,7 @@ --- title: "工作流 API 格式" description: "理解 ComfyUI 工作流的 API 格式以及如何导出" +icon: "file-json" --- ComfyUI 工作流是描述节点图的 JSON 对象。当你通过 Cloud API 或自建服务器以编程方式调用 ComfyUI 时,工作流必须以 **API 格式**提交——这是一种与浏览器中使用的常规保存格式不同的专用 JSON 结构。 diff --git a/zh/development/cloud/api-reference.mdx b/zh/development/cloud/api-reference.mdx index ad70a33e1..0dc2bcd9d 100644 --- a/zh/development/cloud/api-reference.mdx +++ b/zh/development/cloud/api-reference.mdx @@ -1,6 +1,7 @@ --- title: "Cloud API 参考" description: "Comfy Cloud 的完整 API 参考及代码示例" +icon: "book-open" --- import PollJobCompletion from '/snippets/zh/cloud/poll-job-completion.mdx' diff --git a/zh/development/cloud/openapi.mdx b/zh/development/cloud/openapi.mdx index 2241a3029..dd63b68ae 100644 --- a/zh/development/cloud/openapi.mdx +++ b/zh/development/cloud/openapi.mdx @@ -1,6 +1,7 @@ --- title: "OpenAPI 规范" description: "Comfy Cloud API 的机器可读的 OpenAPI 规范" +icon: "file-text" openapi: "/openapi-cloud.yaml" --- diff --git a/zh/development/comfyui-server/api-key-integration.mdx b/zh/development/comfyui-server/api-key-integration.mdx index bdae8ad49..7fa183a94 100644 --- a/zh/development/comfyui-server/api-key-integration.mdx +++ b/zh/development/comfyui-server/api-key-integration.mdx @@ -2,6 +2,7 @@ title: '通过 API Key 集成来使用 ComfyUI API 节点' description: '本文介绍了如何通过 API Key 集成来使用 ComfyUI API 节点' sidebarTitle: 'Partner Node API 集成' +icon: 'plug' --- 从[PR #8041](https://github.com/Comfy-Org/ComfyUI/pull/8041)开始,ComfyUI 支持通过创建 API Key 来直接使用 ComfyUI 内置的 API 节点,无需特定的前端界面(甚至可以完全不使用前端)。 diff --git a/zh/development/comfyui-server/comms_messages.mdx b/zh/development/comfyui-server/comms_messages.mdx index c92fe5f31..45e63d9f1 100644 --- a/zh/development/comfyui-server/comms_messages.mdx +++ b/zh/development/comfyui-server/comms_messages.mdx @@ -1,5 +1,6 @@ --- title: "消息传递" +icon: "message-square" --- ## 消息传递机制 diff --git a/zh/development/comfyui-server/comms_routes.mdx b/zh/development/comfyui-server/comms_routes.mdx index eb84763bd..4db7b8276 100644 --- a/zh/development/comfyui-server/comms_routes.mdx +++ b/zh/development/comfyui-server/comms_routes.mdx @@ -1,5 +1,6 @@ --- title: "路由" +icon: "route" --- ## 路由 diff --git a/zh/development/comfyui-server/execution_model_inversion_guide.mdx b/zh/development/comfyui-server/execution_model_inversion_guide.mdx index f2afe83a9..fa765981b 100644 --- a/zh/development/comfyui-server/execution_model_inversion_guide.mdx +++ b/zh/development/comfyui-server/execution_model_inversion_guide.mdx @@ -1,5 +1,6 @@ --- title: "执行模型反转指南" +icon: "git-branch" --- [PR #2666](https://github.com/Comfy-Org/ComfyUI/pull/2666) 将执行模型从原先的“后端到前端”递归方式,转变为“前端到后端”的拓扑排序方式。尽管多数自定义节点预计仍能照常工作,本指南旨在帮助自定义节点开发者识别那些*可能*因此变更而出现问题的情况。 From 5a34b1014c2da4b3898e7d132dca6c4c61334743 Mon Sep 17 00:00:00 2001 From: lin-bot23 Date: Wed, 3 Jun 2026 03:14:18 +0800 Subject: [PATCH 20/22] Replace non-standard icons with FontAwesome verified ones --- development/api-development/overview.mdx | 2 +- development/api-development/workflow-api-format.mdx | 2 +- development/cloud/openapi.mdx | 2 +- development/comfyui-server/api-key-integration.mdx | 2 +- development/comfyui-server/comms_messages.mdx | 2 +- development/comfyui-server/execution_model_inversion_guide.mdx | 2 +- ja/development/api-development/overview.mdx | 2 +- ja/development/api-development/workflow-api-format.mdx | 2 +- ja/development/cloud/openapi.mdx | 2 +- ja/development/comfyui-server/api-key-integration.mdx | 2 +- ja/development/comfyui-server/comms_messages.mdx | 2 +- .../comfyui-server/execution_model_inversion_guide.mdx | 2 +- zh/development/api-development/overview.mdx | 2 +- zh/development/api-development/workflow-api-format.mdx | 2 +- zh/development/cloud/openapi.mdx | 2 +- zh/development/comfyui-server/api-key-integration.mdx | 2 +- zh/development/comfyui-server/comms_messages.mdx | 2 +- .../comfyui-server/execution_model_inversion_guide.mdx | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/development/api-development/overview.mdx b/development/api-development/overview.mdx index 3dda341b0..a398cb5bf 100644 --- a/development/api-development/overview.mdx +++ b/development/api-development/overview.mdx @@ -1,7 +1,7 @@ --- title: "APIs Overview" description: "An overview of the different ways to interact with ComfyUI programmatically" -icon: "list-tree" +icon: "list" --- ComfyUI offers several API options depending on where you want to run your workflows and how much infrastructure you want to manage. This page helps you choose the right approach. diff --git a/development/api-development/workflow-api-format.mdx b/development/api-development/workflow-api-format.mdx index fbca73eb0..b3da0a30c 100644 --- a/development/api-development/workflow-api-format.mdx +++ b/development/api-development/workflow-api-format.mdx @@ -1,7 +1,7 @@ --- title: "Workflow API Format" description: "Understanding the API format for ComfyUI workflows and how to export them" -icon: "file-json" +icon: "file-code" --- ComfyUI workflows are JSON objects that describe a graph of nodes. When calling ComfyUI programmatically — whether through the Cloud API or running your own server — the workflow must be submitted in **API format**, a specialized JSON structure that differs from the regular save format used in the browser. diff --git a/development/cloud/openapi.mdx b/development/cloud/openapi.mdx index fe431f9a1..89ed98627 100644 --- a/development/cloud/openapi.mdx +++ b/development/cloud/openapi.mdx @@ -1,7 +1,7 @@ --- title: "OpenAPI Specification" description: "Machine-readable OpenAPI specification for Comfy Cloud API" -icon: "file-text" +icon: "file-lines" openapi: "/openapi-cloud.yaml" --- diff --git a/development/comfyui-server/api-key-integration.mdx b/development/comfyui-server/api-key-integration.mdx index 6f3e1fc93..6a6e970f5 100644 --- a/development/comfyui-server/api-key-integration.mdx +++ b/development/comfyui-server/api-key-integration.mdx @@ -2,7 +2,7 @@ title: 'ComfyUI Account API Key Integration' description: 'This article explains how to use ComfyUI Account API Key to call paid Partner Nodes in headless mode' sidebarTitle: 'Partner Node API Integration' -icon: 'plug' +icon: 'puzzle-piece' --- Starting from [PR #8041](https://github.com/Comfy-Org/ComfyUI/pull/8041), ComfyUI supports directly using built-in paid Partner Nodes through your ComfyUI Account API Key, without requiring a specific frontend interface (you can even run without a frontend). diff --git a/development/comfyui-server/comms_messages.mdx b/development/comfyui-server/comms_messages.mdx index cbb02d2d7..b1d214f5a 100644 --- a/development/comfyui-server/comms_messages.mdx +++ b/development/comfyui-server/comms_messages.mdx @@ -1,6 +1,6 @@ --- title: "Messages" -icon: "message-square" +icon: "comment" --- ## Messages diff --git a/development/comfyui-server/execution_model_inversion_guide.mdx b/development/comfyui-server/execution_model_inversion_guide.mdx index bfad82b9c..3289c2bcf 100644 --- a/development/comfyui-server/execution_model_inversion_guide.mdx +++ b/development/comfyui-server/execution_model_inversion_guide.mdx @@ -1,6 +1,6 @@ --- title: "Execution Model Inversion Guide" -icon: "git-branch" +icon: "code-branch" --- [PR #2666](https://github.com/Comfy-Org/ComfyUI/pull/2666) inverts the execution model from a back-to-front recursive model to a front-to-back topological sort. While most custom nodes should continue to "just work", this page is intended to serve as a guide for custom node creators to the things that *could* break. diff --git a/ja/development/api-development/overview.mdx b/ja/development/api-development/overview.mdx index 57ef002a0..75cf767d7 100644 --- a/ja/development/api-development/overview.mdx +++ b/ja/development/api-development/overview.mdx @@ -1,7 +1,7 @@ --- title: "API 概要" description: "ComfyUI をプログラムから操作するための様々なAPIの概要" -icon: "list-tree" +icon: "list" --- ComfyUI には、ワークフローを実行する場所や管理したいインフラストラクチャに応じて、複数の API オプションがあります。このページは適切な方法を選ぶのに役立ちます。 diff --git a/ja/development/api-development/workflow-api-format.mdx b/ja/development/api-development/workflow-api-format.mdx index 4d87afb88..b9dfd2a4c 100644 --- a/ja/development/api-development/workflow-api-format.mdx +++ b/ja/development/api-development/workflow-api-format.mdx @@ -1,7 +1,7 @@ --- title: "ワークフロー API 形式" description: "ComfyUI ワークフローの API 形式とそのエクスポート方法" -icon: "file-json" +icon: "file-code" --- ComfyUI ワークフローは、ノードのグラフを記述する JSON オブジェクトです。Cloud API や自身のサーバーを通じてプログラムから ComfyUI を呼び出す場合、ワークフローは**API 形式**で送信する必要があります。これはブラウザで使用される通常の保存形式とは異なる専用の JSON 構造です。 diff --git a/ja/development/cloud/openapi.mdx b/ja/development/cloud/openapi.mdx index cabd9bbc1..eae92b9d0 100644 --- a/ja/development/cloud/openapi.mdx +++ b/ja/development/cloud/openapi.mdx @@ -1,7 +1,7 @@ --- title: "OpenAPI 仕様" description: "Comfy Cloud API の機械可読な OpenAPI 仕様" -icon: "file-text" +icon: "file-lines" openapi: "/openapi-cloud.yaml" translationSourceHash: 04c13223 translationFrom: development/cloud/openapi.mdx, zh/development/cloud/openapi.mdx diff --git a/ja/development/comfyui-server/api-key-integration.mdx b/ja/development/comfyui-server/api-key-integration.mdx index adf1df939..be434c88c 100644 --- a/ja/development/comfyui-server/api-key-integration.mdx +++ b/ja/development/comfyui-server/api-key-integration.mdx @@ -2,7 +2,7 @@ title: 'ComfyUI アカウント API キー統合' description: 'この記事では、ヘッドレスモードで有料 API ノードを呼び出すために ComfyUI アカウント API キーを使用する方法について説明します' sidebarTitle: 'Partner Node API 統合' -icon: 'plug' +icon: 'puzzle-piece' translationSourceHash: 6d4591f9 translationFrom: development/comfyui-server/api-key-integration.mdx, zh/development/comfyui-server/api-key-integration.mdx --- diff --git a/ja/development/comfyui-server/comms_messages.mdx b/ja/development/comfyui-server/comms_messages.mdx index bd31b7990..eb4092b5f 100644 --- a/ja/development/comfyui-server/comms_messages.mdx +++ b/ja/development/comfyui-server/comms_messages.mdx @@ -1,6 +1,6 @@ --- title: "メッセージ" -icon: "message-square" +icon: "comment" translationSourceHash: 7229c28c translationFrom: development/comfyui-server/comms_messages.mdx, zh/development/comfyui-server/comms_messages.mdx --- diff --git a/ja/development/comfyui-server/execution_model_inversion_guide.mdx b/ja/development/comfyui-server/execution_model_inversion_guide.mdx index 8d133c982..3e89d8c1a 100644 --- a/ja/development/comfyui-server/execution_model_inversion_guide.mdx +++ b/ja/development/comfyui-server/execution_model_inversion_guide.mdx @@ -1,6 +1,6 @@ --- title: "実行モデル反転ガイド" -icon: "git-branch" +icon: "code-branch" translationSourceHash: dfad1b9a translationFrom: development/comfyui-server/execution_model_inversion_guide.mdx, zh/development/comfyui-server/execution_model_inversion_guide.mdx --- diff --git a/zh/development/api-development/overview.mdx b/zh/development/api-development/overview.mdx index ebd10768b..12ba8e4fb 100644 --- a/zh/development/api-development/overview.mdx +++ b/zh/development/api-development/overview.mdx @@ -1,7 +1,7 @@ --- title: "API 总览" description: "通过不同方式编程调用 ComfyUI 的接口概览" -icon: "list-tree" +icon: "list" --- ComfyUI 提供多种 API 选项,取决于你希望在哪里运行工作流以及你想管理多少基础设施。本页帮助你选择合适的方式。 diff --git a/zh/development/api-development/workflow-api-format.mdx b/zh/development/api-development/workflow-api-format.mdx index 7e3a18323..d55e1f2c2 100644 --- a/zh/development/api-development/workflow-api-format.mdx +++ b/zh/development/api-development/workflow-api-format.mdx @@ -1,7 +1,7 @@ --- title: "工作流 API 格式" description: "理解 ComfyUI 工作流的 API 格式以及如何导出" -icon: "file-json" +icon: "file-code" --- ComfyUI 工作流是描述节点图的 JSON 对象。当你通过 Cloud API 或自建服务器以编程方式调用 ComfyUI 时,工作流必须以 **API 格式**提交——这是一种与浏览器中使用的常规保存格式不同的专用 JSON 结构。 diff --git a/zh/development/cloud/openapi.mdx b/zh/development/cloud/openapi.mdx index dd63b68ae..3ad83c542 100644 --- a/zh/development/cloud/openapi.mdx +++ b/zh/development/cloud/openapi.mdx @@ -1,7 +1,7 @@ --- title: "OpenAPI 规范" description: "Comfy Cloud API 的机器可读的 OpenAPI 规范" -icon: "file-text" +icon: "file-lines" openapi: "/openapi-cloud.yaml" --- diff --git a/zh/development/comfyui-server/api-key-integration.mdx b/zh/development/comfyui-server/api-key-integration.mdx index 7fa183a94..b3313ad00 100644 --- a/zh/development/comfyui-server/api-key-integration.mdx +++ b/zh/development/comfyui-server/api-key-integration.mdx @@ -2,7 +2,7 @@ title: '通过 API Key 集成来使用 ComfyUI API 节点' description: '本文介绍了如何通过 API Key 集成来使用 ComfyUI API 节点' sidebarTitle: 'Partner Node API 集成' -icon: 'plug' +icon: 'puzzle-piece' --- 从[PR #8041](https://github.com/Comfy-Org/ComfyUI/pull/8041)开始,ComfyUI 支持通过创建 API Key 来直接使用 ComfyUI 内置的 API 节点,无需特定的前端界面(甚至可以完全不使用前端)。 diff --git a/zh/development/comfyui-server/comms_messages.mdx b/zh/development/comfyui-server/comms_messages.mdx index 45e63d9f1..6bcc74fa9 100644 --- a/zh/development/comfyui-server/comms_messages.mdx +++ b/zh/development/comfyui-server/comms_messages.mdx @@ -1,6 +1,6 @@ --- title: "消息传递" -icon: "message-square" +icon: "comment" --- ## 消息传递机制 diff --git a/zh/development/comfyui-server/execution_model_inversion_guide.mdx b/zh/development/comfyui-server/execution_model_inversion_guide.mdx index fa765981b..82db16c02 100644 --- a/zh/development/comfyui-server/execution_model_inversion_guide.mdx +++ b/zh/development/comfyui-server/execution_model_inversion_guide.mdx @@ -1,6 +1,6 @@ --- title: "执行模型反转指南" -icon: "git-branch" +icon: "code-branch" --- [PR #2666](https://github.com/Comfy-Org/ComfyUI/pull/2666) 将执行模型从原先的“后端到前端”递归方式,转变为“前端到后端”的拓扑排序方式。尽管多数自定义节点预计仍能照常工作,本指南旨在帮助自定义节点开发者识别那些*可能*因此变更而出现问题的情况。 From 75cefd40fc97ed5051597a8e0bf38bd63cfb6bc2 Mon Sep 17 00:00:00 2001 From: ComfyUI Wiki Date: Wed, 3 Jun 2026 10:34:38 +0800 Subject: [PATCH 21/22] fix: update development overview link to api-examples page The quick-start page was renamed to api-examples; mint broken-links CI was failing on the stale path. --- development/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/overview.mdx b/development/overview.mdx index 37e28e732..7a2a83ade 100644 --- a/development/overview.mdx +++ b/development/overview.mdx @@ -13,7 +13,7 @@ Run ComfyUI in your own environment and expose it as an API endpoint. Learn abou Run ComfyUI as a server on your own machine. Start, configure, and call it via REST and WebSocket APIs. -See also: [Server API Quick Start](/development/comfyui-server/quick-start) · [Partner Node API Integration](/development/comfyui-server/api-key-integration) +See also: [API Examples](/development/comfyui-server/api-examples) · [Partner Node API Integration](/development/comfyui-server/api-key-integration) ## Cloud API From 99dce4f6ae69af4430ed6d6c8915be0d8df6df43 Mon Sep 17 00:00:00 2001 From: ComfyUI Wiki Date: Thu, 4 Jun 2026 10:05:41 +0800 Subject: [PATCH 22/22] Remove Comfy Cloud account requirement from API prerequisites in English, Japanese, and Chinese overview files --- development/api-development/overview.mdx | 1 - ja/development/api-development/overview.mdx | 1 - zh/development/api-development/overview.mdx | 1 - 3 files changed, 3 deletions(-) diff --git a/development/api-development/overview.mdx b/development/api-development/overview.mdx index a398cb5bf..f365ec469 100644 --- a/development/api-development/overview.mdx +++ b/development/api-development/overview.mdx @@ -45,5 +45,4 @@ Both APIs use the same workflow format ([API format](/development/api-developmen Before using any API, you'll need: -- A Comfy Cloud account ([sign up](https://comfy.org/signup)) - An API key (see [Getting an API Key](/development/api-development/getting-an-api-key)) diff --git a/ja/development/api-development/overview.mdx b/ja/development/api-development/overview.mdx index 75cf767d7..66763de1c 100644 --- a/ja/development/api-development/overview.mdx +++ b/ja/development/api-development/overview.mdx @@ -43,5 +43,4 @@ ComfyUI には、ワークフローを実行する場所や管理したいイン ## 前提条件 -- Comfy Cloud アカウント([登録](https://comfy.org/signup)) - API Key([API Key の取得](/ja/development/api-development/getting-an-api-key)を参照) diff --git a/zh/development/api-development/overview.mdx b/zh/development/api-development/overview.mdx index 12ba8e4fb..f5646c17b 100644 --- a/zh/development/api-development/overview.mdx +++ b/zh/development/api-development/overview.mdx @@ -43,5 +43,4 @@ ComfyUI 提供多种 API 选项,取决于你希望在哪里运行工作流以 ## 前提条件 -- 一个 Comfy Cloud 账户([注册](https://comfy.org/signup)) - 一个 API Key(参见[获取 API Key](/zh/development/api-development/getting-an-api-key))