How to package ComfyUI workflow into API: tutorials, troubleshooting and FAQ

Introduces how to package ComfyUI workflow into a callable API, covering workflow export, parameter replacement, prompt submission, result polling, image download, service deployment and common error troubleshooting.

ComfyUI is great for building AI drawing, face swapping, zooming in, partial redrawing and video generation workflows. But if you just stay in the web interface and drag nodes, it is more like a creative tool; if you want to connect to websites, Bots, background tasks or enterprise processes, you need to package the workflow into an API.

This article is organized according to “Tutorial + Troubleshooting + FAQ”. The goal is to turn a workflow that can be run manually in ComfyUI into an interface where the backend can submit tasks, wait for results, and download images. The focus is not on writing a complex platform, but on getting through the smallest closed loop first.

First understand the API idea of ​​ComfyUI

The essence of ComfyUI’s API call is not to “turn nodes into functions”, but to submit the entire workflow JSON as a prompt to the ComfyUI backend. The backend executes according to the node graph. After generating the results, you can get the output through the history or file interface.

The minimum link is:

  1. Set up the workflow in the ComfyUI web interface.
  2. Export workflow JSON in API format.
  3. Replace prompt, picture, size, seed and other inputs in the back-end code.
  4. Call /prompt to submit the task.
  5. Query /history based on prompt_id.
  6. Read the output image or video file.

As long as this link is open, you can continue to encapsulate it into your own REST API, queue tasks or SaaS functions.

Prepare a stable workflow

Don’t API-ify a complex workflow with dozens of custom nodes right from the start. First choose a basic workflow that can produce stable images, for example:

  • Vincentian picture.
  • Pictures give rise to pictures.
  • Picture enlargement.
  • Partial redraw.
  • Fixed style poster.

First confirm a few things in the Web UI:

  • The model file has been downloaded.
  • Custom nodes are not missing.
  • The input image path can be read normally.
  • A single run can generate results.
  • Output nodes can save images.

If you can’t run it manually, API calls will only hide the problem deeper.

Export API format workflow

In the ComfyUI interface, the normally saved workflow and the prompt JSON required for API calls are not exactly the same. Usually you need to enable developer-related options and then export the API format.

The JSON you want to get looks like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
  "3": {
    "class_type": "KSampler",
    "inputs": {
      "seed": 123456,
      "steps": 20,
      "cfg": 7,
      "sampler_name": "euler",
      "scheduler": "normal"
    }
  },
  "6": {
    "class_type": "CLIPTextEncode",
    "inputs": {
      "text": "a cat sitting on a desk"
    }
  }
}

Each numeric key is a node ID. When making API changes, what you need to modify is usually the inputs of these nodes.

Find the node that needs to be replaced

Don’t rush to write code after exporting. Open the JSON and mark which fields are to be controlled by user input.

Common fields that need to be replaced:

use Common nodes Common fields
positive cue words CLIPTextEncode text
reverse prompt word CLIPTextEncode text
random seed KSampler seed
number of steps KSampler steps
size EmptyLatentImage width, height
Enter picture LoadImage image
output file SaveImage filename_prefix

It is recommended to maintain a mapping table in the project, for example:

1
2
3
4
5
6
7
{
  "positive_prompt_node": "6",
  "negative_prompt_node": "7",
  "sampler_node": "3",
  "latent_node": "5",
  "save_node": "9"
}

In this way, when adjusting the workflow nodes later, you only need to change the mapping, without having to look for the node ID everywhere in the business code.

Submit prompt in Python

Here’s a minimal example: read the workflow JSON, replace the prompt words, and submit to local ComfyUI.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import json
import urllib.request
import uuid

COMFYUI_URL = "http://127.0.0.1:8188"


def queue_prompt(prompt):
    payload = {
        "prompt": prompt,
        "client_id": str(uuid.uuid4())
    }
    data = json.dumps(payload).encode("utf-8")
    req = urllib.request.Request(
        f"{COMFYUI_URL}/prompt",
        data=data,
        headers={"Content-Type": "application/json"}
    )
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read().decode("utf-8"))


with open("workflow_api.json", "r", encoding="utf-8") as f:
    workflow = json.load(f)

workflow["6"]["inputs"]["text"] = "a clean product photo of a white sneaker"
workflow["7"]["inputs"]["text"] = "blurry, low quality, text watermark"
workflow["3"]["inputs"]["seed"] = 123456789

result = queue_prompt(workflow)
print(result)

Normally prompt_id will be returned on success. You will then rely on it to query the results.

Query task results

After submitting the task, ComfyUI will not return the image directly to you immediately. Need to query history:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import json
import time
import urllib.request


def get_history(prompt_id):
    with urllib.request.urlopen(f"{COMFYUI_URL}/history/{prompt_id}") as resp:
        return json.loads(resp.read().decode("utf-8"))


prompt_id = result["prompt_id"]

for _ in range(60):
    history = get_history(prompt_id)
    if prompt_id in history:
        print(json.dumps(history[prompt_id], indent=2, ensure_ascii=False))
        break
    time.sleep(1)
else:
    raise TimeoutError("ComfyUI task timed out")

The history will contain output node and file information. You need to find filename, subfolder, type and other fields, and then call /view to download.

Download output image

A common download method is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from urllib.parse import urlencode


def download_image(filename, subfolder="", folder_type="output"):
    params = urlencode({
        "filename": filename,
        "subfolder": subfolder,
        "type": folder_type
    })
    url = f"{COMFYUI_URL}/view?{params}"
    with urllib.request.urlopen(url) as resp:
        return resp.read()

After getting the bytes, you can write it to a local file, upload it to object storage, or return it to your business API.

Encapsulated into its own REST API

In actual projects, it is not recommended to let the front end call ComfyUI directly. A more stable structure is:

1
2
3
4
5
6
7
8
9
User frontend
Your business API
Task queue
ComfyUI API
Object storage / local output directory

Business API is responsible for:

  • Verify user parameters.
  • Control size, steps, model and style.
  • Limit concurrency and frequency.
  • Manage task status.
  • Returns the final image URL.

ComfyUI is only responsible for execution generation and is not directly exposed to the public network.

Common error: Unable to connect to ComfyUI

Typical performance:

1
2
connection refused
failed to connect to 127.0.0.1:8188

Check order:

  1. Whether ComfyUI is running.
  2. Whether the port is 8188.
  3. Whether the backend code and ComfyUI are on the same machine.
  4. Is localhost in Docker, WSL or remote server pointing correctly?
  5. Whether the firewall blocks the port.

If the backend runs in a container, 127.0.0.1 refers to the container itself, not the host. You need to change it to the host address or use the Docker network service name.

Common error: prompt format is incorrect

Typical performance:

1
2
invalid prompt
prompt outputs failed validation

Common reasons:

  • Used plain workflow JSON instead of API format JSON.
  • The node ID is written incorrectly.
  • A required input has been removed.
  • Input type mismatch, for example, numbers are written as strings.
  • The custom node is missing, causing the class_type to be unrecognized.

Troubleshooting method:

  • Submit with the original exported JSON first without any replacement.
  • The original JSON can be run, and then the fields are replaced one by one.
  • Compare node IDs and fields in the web UI.
  • See the ComfyUI console for detailed error reports.

Don’t replace a dozen fields at once. Changing only one variable at a time is the easiest to locate.

Common errors: model or custom node not found

Typical performance:

1
2
3
CheckpointLoaderSimple: ckpt_name not found
Cannot import custom node
class_type not found

The reason is usually that the API server environment is inconsistent with the environment where you exported the workflow.

Check these directories:

  • models/checkpoints
  • models/loras
  • models/vae
  • models/controlnet
  • custom_nodes

If it can run on the development machine but cannot run on the deployment machine, check the model file name, custom node version and dependent packages first.

Common error: Failed to read input image

Image path problems are often encountered when creating images, changing faces, and partially redrawing images.

Note a few points:

  • LoadImage usually reads files in the ComfyUI input directory.
  • Directly transferring to any path on the local machine may not be available.
  • You may need to upload images to ComfyUI before calling the API.
  • Windows and Linux path formats are different.

A more stable approach is to upload the user image to the input directory of ComfyUI or use the upload interface, and then write the returned file name to the LoadImage node.

Common error: tasks are always queued

If /prompt returns prompt_id, but history has no results, it may be:

  • The GPU is performing other tasks.
  • A node is stuck.
  • Model loading is very slow.
  • Insufficient video memory causes repeated switching.
  • The ComfyUI backend has reported an error but the business end has not read it.

It is recommended to do:

  • View the ComfyUI console log.
  • Add timeout to business side polling.
  • Limit the number of concurrent tasks.
  • Set longer but clear timeouts for large images, videos, and HD restorations.
  • Return a readable error on failure instead of keeping the user waiting.

Common error: Insufficient video memory

Typical performance:

1
2
CUDA out of memory
Allocation failed

Processing method:

  • Reduce resolution.
  • Reduce batch size.
  • Reduce steps.
  • Change to a smaller model.
  • Turn off unnecessary ControlNet, LoRA or HD fixes.
  • Set up different queues for different workflows.

After becoming API, it is even more important to control user input. Don’t let users upload 4096 x 4096, 100 steps, or multiple LoRA stacks at will, otherwise the service will easily be filled up.

FAQ: Results file not found

If there is a file name in history but a 404 error occurs when downloading, the common reasons are:

  • filename, subfolder, type parameters are transmitted incorrectly.
  • The output node is not SaveImage.
  • The file is saved to a temporary directory.
  • The task failed and there is no real output in the history.
  • During multi-instance deployment, another ComfyUI was requested.

When troubleshooting, print the history outputs first, and do not spell the URL from memory.

Protection before going online

After wrapping ComfyUI into an API, don’t go online naked. At a minimum consider:

  • Authentication.
  • Frequency limits.
  • Concurrency limits.
  • Enter size limits.
  • prompt length limit.
  • Disable user selection of arbitrary model paths.
  • Output file cleaning.
  • Failure retries and timeouts.
  • Task status persistence.

ComfyUI is very suitable as a generation engine, but the business layer needs to provide permissions, queues, auditing and resource control by itself.

FAQ

Does ComfyUI come with its own API?

have. Commonly used interfaces are /prompt, /history/{prompt_id} and /view. Actual projects usually wrap a layer of business API outside to avoid directly exposing ComfyUI.

Why can’t the exported workflow be called directly?

The export may be a normal workflow, not API format; it may also be missing models, custom nodes, or some input paths are only valid in the current environment of the Web UI. Test with the original API JSON first, then gradually replace the parameters.

Can the front end call ComfyUI directly?

Not recommended. Direct calls from the front end will expose the service address and make it difficult to perform authentication, current limiting and parameter control. What is more stable is that the front end calls your back end, and the back end calls ComfyUI.

How to handle multi-user concurrency?

Don’t let all requests go directly to ComfyUI. It is recommended to add a task queue, limit the number of concurrencies, and poll according to task status. High-cost workflows can be queued separately.

Where should the output images be stored?

The ComfyUI output directory can exist during development. After going online, it is recommended to upload it to object storage or business file service, then return to the stable URL, and clean up local temporary files regularly.

What should I do if the node ID changes?

If you re-edit the workflow, the node ID may change. It is recommended to maintain a parameter map and run a minimal API test after each workflow update.

Can multiple workflows be made into one API?

Yes, but don’t let users directly pass arbitrary workflow JSON. A safer approach is to maintain a whitelist of templates on the backend, and users can only select templates and limited parameters.

What is the difference between video workflow and image workflow?

Video workflows often take longer, put more pressure on video memory, and produce larger output files, requiring stricter queue, timeout, and file management. First connect the picture link, and then expand the video.

summary

The essence of packaging the ComfyUI workflow into an API is to turn the stable node graph into prompt JSON with replaceable parameters, then submit the task through /prompt, query the results through /history, and obtain the file through /view. The real difficulty is not in making requests, but in workflow stability, parameter boundaries, queue concurrency, file management and error handling.

It is recommended to start with the simplest Vincent diagram workflow and go through the four steps of export, submission, polling and downloading. After the minimum closed loop is stable, upload images, style templates, user queues and production-level protection will be added.

记录并分享
Built with Hugo
Theme Stack designed by Jimmy