实验性 API: 此 API 目前处于实验阶段,可能会发生变更。端点、请求/响应格式和行为可能会在不另行通知的情况下进行修改。
Comfy Cloud API
Comfy Cloud API 提供以编程方式访问 Comfy Cloud 的能力,可在云端基础设施上运行工作流。该 API 与本地 ComfyUI 的 API 兼容,便于迁移现有集成。
需要订阅: 通过 API 运行工作流需要有效的 Comfy Cloud 订阅。详情请参阅定价方案。
基础 URL
身份验证
所有 API 请求都需要通过 X-API-Key 请求头传递 API 密钥。
获取 API 密钥
访问 https://platform.comfy.org/login 并登录
在 API Keys 点击 `+ New` 创建 API Key
在 API Keys 点击 + New 创建 API Key
输入 API Key 名称

- (必填)输入 API Key 名称,
- 点击
Generate 创建
保存获取到的 API Key

由于 API Key 仅在第一次创建时可见,所以请在创建后立即保存,后续无法查看,请妥善保存,请注意不要公开分享你的 API Key,如果对应的 Key 已经泄露,请及时删除并创建新的 API Key。
请妥善保管您的 API 密钥。切勿将其提交到版本控制系统或公开分享。
使用 API 密钥
在每个请求中通过 X-API-Key 请求头传递您的 API 密钥:
curl -X GET "https://cloud.comfy.org/api/user" \
-H "X-API-Key: $COMFY_CLOUD_API_KEY"
核心概念
工作流
ComfyUI 工作流是描述节点图的 JSON 对象。API 接受”API 格式”的工作流(以节点 ID 为键,包含 class_type、inputs 等),该格式由 ComfyUI 前端的”Save (API Format)“选项导出。
当您提交工作流时,会创建一个任务。任务以异步方式执行:
- 通过
POST /api/prompt 提交工作流
- 收到
prompt_id(任务 ID)
- 通过 WebSocket 监控进度或轮询状态
- 完成后获取输出
生成的内容(图像、视频、音频)存储在云存储中。输出文件可通过 /api/view 端点下载,该端点会返回 302 重定向到临时签名 URL。
快速入门
以下是完整示例,展示如何提交工作流、监控进度并获取输出:
步骤 1:提交工作流
curl -X POST "https://cloud.comfy.org/api/prompt" \
-H "X-API-Key: $COMFY_CLOUD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": '"$(cat workflow_api.json)"'}'
步骤 2:监控任务进度
您可以使用轮询或 WebSocket 来监控任务完成情况,以便获取实时更新。
选项 A:轮询(简单)
任务状态值:
API 返回以下状态值之一:
| 状态 | 描述 |
|---|
pending | 任务已排队,等待开始 |
in_progress | 任务正在执行 |
completed | 任务成功完成 |
failed | 任务遇到错误 |
cancelled | 任务被用户取消 |
# 轮询任务完成状态
curl -X GET "$BASE_URL/api/job/{prompt_id}/status" \
-H "X-API-Key: $COMFY_CLOUD_API_KEY"
# 响应示例:
# {"status": "pending"} - 任务已排队
# {"status": "in_progress"} - 任务正在运行
# {"status": "completed"} - 任务成功完成
# {"status": "failed"} - 任务遇到错误
# {"status": "cancelled"} - 任务被取消
选项 B:WebSocket(实时进度)
用于实时进度更新并收集输出元数据:
async function listenForCompletion(
promptId: string,
timeout: number = 300000
): Promise<Record<string, any>> {
const wsUrl = `wss://cloud.comfy.org/ws?clientId=${crypto.randomUUID()}&token=${API_KEY}`;
const outputs: Record<string, any> = {};
return new Promise((resolve, reject) => {
const ws = new WebSocket(wsUrl);
const timer = setTimeout(() => {
ws.close();
reject(new Error(`任务在 ${timeout / 1000}s 内未完成`));
}, timeout);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
const msgType = data.type;
const msgData = data.data ?? {};
// 过滤我们的任务
if (msgData.prompt_id !== promptId) return;
if (msgType === "executing") {
const node = msgData.node;
if (node) {
console.log(`正在执行节点:${node}`);
} else {
console.log("执行完成");
}
} else if (msgType === "progress") {
console.log(`进度:${msgData.value}/${msgData.max}`);
} else if (msgType === "executed" && msgData.output) {
outputs[msgData.node] = msgData.output;
} else if (msgType === "execution_success") {
console.log("任务成功完成!");
clearTimeout(timer);
ws.close();
resolve(outputs);
} else if (msgType === "execution_error") {
const errorMsg = msgData.exception_message ?? "未知错误";
clearTimeout(timer);
ws.close();
reject(new Error(`执行错误:${errorMsg}`));
}
};
ws.onerror = (err) => {
clearTimeout(timer);
reject(err);
};
});
}
// 等待完成并收集输出
const outputs = await listenForCompletion(promptId);
步骤 3:下载输出
任务完成后,下载生成的文件。从 WebSocket 返回的 outputs 对象(或通过历史端点获取)包含按节点 ID 组织的输出数据。每个节点的输出可能包含 images、video 或 audio 数组,其中包含文件元数据。
输出结构示例:
{
"9": {
"images": [
{
"filename": "ComfyUI_00001_.png",
"subfolder": "",
"type": "output"
}
]
}
}
节点 ID(此例中的 "9")对应于工作流中的 SaveImage 或其他输出节点。您可以通过打开工作流 JSON 文件并查找 class_type 为 SaveImage、VHS_VideoCombine 等的节点来找到这些 ID。
# 下载单个输出文件(使用 -L 跟随 302 重定向)
curl -L "$BASE_URL/api/view?filename=output.png&subfolder=&type=output" \
-H "X-API-Key: $COMFY_CLOUD_API_KEY" \
-o output.png
/api/view 端点返回 302 重定向到临时签名 URL。您的 HTTP 客户端必须跟随重定向才能下载文件。
完整示例
以下是结合所有三个步骤的完整端到端示例:
import { readFile, writeFile } from "fs/promises";
const BASE_URL = "https://cloud.comfy.org";
const API_KEY = process.env.COMFY_CLOUD_API_KEY!;
async function main() {
// 1. 加载并修改工作流
const workflow = JSON.parse(await readFile("workflow_api.json", "utf-8"));
workflow["3"].inputs.seed = 42;
workflow["6"].inputs.text = "a beautiful sunset";
// 2. 提交工作流
const response = await fetch(`${BASE_URL}/api/prompt`, {
method: "POST",
headers: { "X-API-Key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ prompt: workflow }),
});
const { prompt_id } = await response.json();
console.log(`任务已提交:${prompt_id}`);
// 3. 轮询完成状态
while (true) {
const statusRes = await fetch(`${BASE_URL}/api/job/${prompt_id}/status`, {
headers: { "X-API-Key": API_KEY },
});
const { status } = await statusRes.json();
if (status === "completed") break;
if (["failed", "cancelled"].includes(status)) {
throw new Error(`任务 ${status}`);
}
await new Promise((resolve) => setTimeout(resolve, 2000));
}
// 4. 通过历史端点获取输出
const historyRes = await fetch(`${BASE_URL}/api/history_v2/${prompt_id}`, {
headers: { "X-API-Key": API_KEY },
});
const history = await historyRes.json();
const outputs = history.outputs;
// 5. 下载输出文件
for (const nodeOutputs of Object.values(outputs)) {
for (const fileInfo of (nodeOutputs as any).images ?? []) {
const params = new URLSearchParams({
filename: fileInfo.filename,
subfolder: fileInfo.subfolder ?? "",
type: "output",
});
const viewRes = await fetch(`${BASE_URL}/api/view?${params}`, {
headers: { "X-API-Key": API_KEY },
redirect: "manual",
});
const signedUrl = viewRes.headers.get("location")!;
const fileRes = await fetch(signedUrl);
await writeFile(`./${fileInfo.filename}`, Buffer.from(await fileRes.arrayBuffer()));
console.log(`已下载:${fileInfo.filename}`);
}
}
}
main();
可用端点
| 类别 | 描述 |
|---|
| 工作流 | 提交工作流、检查状态 |
| 任务 | 监控任务状态和队列 |
| 输入 | 上传图像、遮罩和其他输入 |
| 输出 | 下载生成的内容 |
| WebSocket | 实时进度更新 |
| 对象信息 | 可用节点及其定义 |
后续步骤
上面的快速入门涵盖了提交工作流和获取结果的基础知识。对于更高级的用例,请参阅 Cloud API 参考:
- 上传输入文件 - 为需要外部输入的工作流上传图像、遮罩或其他用户提供的内容
- 修改工作流输入 - 在提交前动态更改工作流参数,如提示词、随机种子或节点设置
- 使用合作伙伴节点 - 调用需要额外 API 密钥配置的外部 AI 服务(Flux Pro、Ideogram 等)
- 队列管理 - 监控队列状态、取消任务或中断正在运行的执行
- 错误处理 - 处理 HTTP 错误、执行失败,并了解异常类型
其他资源: