2026-01-17 18:30:08 +05:30

ComfyUI Workflow API

HTTP API for ComfyUI with webhook-based workflow execution. Submit workflows via HTTP, receive real-time progress updates and outputs at your callback URL.

Installation

cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/isala404/comfy-workflow-api.git
pip install -r comfy-workflow-api/requirements.txt

Use Cases

  • Backend Integration: Run ComfyUI as a headless service behind your application
  • Batch Processing: Submit multiple workflows and receive results asynchronously
  • Distributed Systems: Decouple workflow submission from result handling
  • Mobile/Web Apps: Trigger image generation from any HTTP client

How It Works

Client                          ComfyUI                         Your Server
  │                                │                                │
  ├─── POST /api/webhook ─────────►│                                │
  │    (workflow + callback_url)   │                                │
  │                                │                                │
  │◄── {request_id, prompt_id} ────┤                                │
  │                                │                                │
  │                                ├── workflow.progress ──────────►│
  │                                ├── workflow.progress ──────────►│
  │                                ├── ...                          │
  │                                │                                │
  │                                ├── multipart (files) ──────────►│
  │                                │                                │

Quick Start

1. Create a workflow using webhook nodes

Use WebhookReceiver → WebhookTransformer → WebhookSend to read inputs from HTTP and send outputs back:

                    ┌─► WebhookTransformer ──► CLIPTextEncode ──┐
WebhookReceiver ────┤   (extracts "prompt")                     ├──► KSampler ──► WebhookSend
                    └─► WebhookTransformer ──► VAEEncode ───────┘
                        (extracts "image")

2. Submit via HTTP

# Image-to-image example
curl -X POST http://localhost:8188/api/webhook \
  -F "workflow=@workflow.json" \
  -F "callback_url=http://your-server.com/webhook" \
  -F "prompt=turn it into a watercolor painting" \
  -F "image=@input.png"

3. Receive at your callback

Your server receives:

  • Progress events (JSON): {"event": "workflow.progress", "progress": {"value": 5, "max": 20}}
  • Output files (gzip multipart): Images, audio, video, etc.

Nodes

WebhookReceiver

Entry point for webhook workflows. Reads request configuration from the HTTP call.

Output Type Description
webhook_context WEBHOOK_CONTEXT Context for other webhook nodes

WebhookTransformer

Extracts a field from the HTTP request. Connects to any input type.

Input Description
webhook_context From WebhookReceiver
field Field name to extract (e.g., "prompt")
default_value Optional fallback if field missing
Output Type Description
value * (wildcard) Extracted value, auto-typed

Type inference: Strings are converted to INT, FLOAT, BOOLEAN when applicable. File uploads become IMAGE, AUDIO, VIDEO, MESH, or LATENT based on content type.

WebhookSend

Sends outputs to the callback URL. Supports 5 output fields.

Input Description
webhook_context From WebhookReceiver
field_1..5 Any ComfyUI type (IMAGE, AUDIO, STRING, etc.)
field_1..5_name Names for each output

Encoding: IMAGE→PNG, AUDIO→FLAC, VIDEO→MP4, MESH→GLB, LATENT→safetensors

API Reference

POST /api/webhook

Field Required Description
workflow Yes Workflow JSON
callback_url Yes URL to receive events/outputs
auth_header No Auth header name
auth_value No Auth header value
timeout No HTTP timeout (default: 60s)
max_retries No Retry attempts (default: 3)
custom fields No Any field accessible via WebhookTransformer

Response:

{"request_id": "...", "prompt_id": "...", "status": "queued"}

GET /api/webhook/status/{request_id}

Check request status.

DELETE /api/webhook/{request_id}

Cancel a queued/running workflow.

Webhook Events

Event Content-Type Description
workflow.started application/json Execution began
workflow.progress application/json Step progress (throttled 500ms)
workflow.completed multipart/form-data (gzip) Output files + metadata
workflow.error application/json Execution failed

Note: Completion payload is gzip compressed. Decompress before parsing.

Example

workflow.json (see example_workflow.json):

{
  "10": {
    "class_type": "WebhookReceiver",
    "inputs": {"debug": true}
  },
  "11": {
    "class_type": "WebhookTransformer",
    "inputs": {"field": "prompt", "webhook_context": ["10", 0]}
  },
  "6": {
    "class_type": "CLIPTextEncode",
    "inputs": {"text": ["11", 0], "clip": ["4", 1]}
  },
  "...": "... rest of workflow ...",
  "12": {
    "class_type": "WebhookSend",
    "inputs": {"webhook_context": ["10", 0], "field_1": ["8", 0]}
  }
}

Python client (see example_client.py):

import requests, json

# Load image for img2img
image_data = open("input.png", "rb").read()

response = requests.post(
    "http://localhost:8188/api/webhook",
    files={
        "workflow": (None, json.dumps(workflow), "application/json"),
        "callback_url": (None, "http://localhost:5001/webhook"),
        "prompt": (None, "make it look like a painting"),
        "image": ("input.png", image_data, "image/png"),
    }
)

Testing

# Terminal 1: Start ComfyUI
python main.py

# Terminal 2: Run example client (image-to-image)
cd custom_nodes/comfy-workflow-api
python example_client.py sample_input.png "turn it into a watercolor painting"

A sample image (sample_input.png) is included in the repo for testing.

License

MIT

S
Description
No description provided
Readme
508 KiB
Languages
Python 100%