> ## Documentation Index
> Fetch the complete documentation index at: https://dripart-chore-mintlify-theme-mint.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Comfy API v2 Overview

> Reference for the official Comfy API v2: run ComfyUI workflows from external applications by uploading inputs, submitting jobs, and polling for results.

<Warning>
  **Beta:** Comfy API v2 is at `0.1.x` and the surface may still change. Changes within v2 will be additive; anything breaking would ship as v3.
</Warning>

The official, versioned HTTP API for running ComfyUI workflows from external applications: upload inputs, submit a workflow, observe execution, retrieve results.

Most people should start with the [Comfy SDKs](/development/api-development/sdks), which wrap this API in Python and TypeScript. Call these endpoints directly if you are working in another language. The full endpoint documentation is in the API Reference pages of this section, generated from the OpenAPI specification.

## Where v2 Runs

The same API is served by three surfaces, so one integration can move between them by changing the base URL.

**Comfy Cloud.** The managed, multi-tenant service at `https://cloud.comfy.org`. Create an [API key](/development/api-development/getting-an-api-key) and you can submit any workflow. Cloud-specific features such as credits, model browsing, and queue management live on the [v1 Cloud API](/development/cloud/overview), not on v2.

**Comfy API deployments.** An environment you deploy through the [Developer Platform](https://platform.comfy.org) gets its own dedicated endpoint at `https://{deployment}.run.comfy.app`, serving the same v2 API with the same API key. A Comfy API deployment runs workflows against one pinned environment, so it scales independently and `GET /workflow` returns the executed graph. See the [Comfy API deployment guide](/development/serverless/overview) for building and deploying.

**Open-source ComfyUI, via the proxy.** During the beta, a self-hosted ComfyUI speaks v2 through [comfy-api-proxy](https://github.com/Comfy-Org/comfy-api-proxy), a small open-source service that runs alongside it:

```bash theme={null}
pip install comfy-api-proxy
comfy-api-proxy
```

By default it proxies the ComfyUI on `127.0.0.1:8188` and serves the v2 API on `127.0.0.1:8189`, binding to loopback only. Authentication is off by default, with an optional static bearer token. The proxy is a stopgap: once v2 stabilizes it moves into ComfyUI core and the proxy is no longer needed. See [Your own ComfyUI](/development/api-development/sdks#your-own-comfyui) in the SDK guide for configuration details.

## Design Principles

* **Poll first.** Every capability is reachable via plain GET polling. The SSE stream is a live enhancement, never the source of truth.
* **Everything is resumable.** Submission is idempotent, and job state and outputs are retrievable by ID until `expires_at`. The URL you get back for an output is shorter-lived than that: see [Output URLs and How Long They Last](#output-urls-and-how-long-they-last).
* **Content-addressed assets.** Assets are UUID-identified records over blobs keyed by a server-computed blake3 hash, so identical inputs are not uploaded twice.
* **Follow links, do not build URLs.** Responses embed their follow-up URLs.

See [Design Notes](/development/api-development/sdks-design) for the reasoning behind these.

## Base URLs

| Surface                                                                          | URL                                  | Authentication                                |
| -------------------------------------------------------------------------------- | ------------------------------------ | --------------------------------------------- |
| Comfy Cloud                                                                      | `https://cloud.comfy.org`            | `Authorization: Bearer <api-key>`             |
| Comfy API deployment                                                             | `https://{deployment}.run.comfy.app` | `Authorization: Bearer <api-key>`             |
| Self-hosted, via [comfy-api-proxy](https://github.com/Comfy-Org/comfy-api-proxy) | `http://127.0.0.1:8189`              | None by default, optional static bearer token |

## Endpoint Categories

| Category | Description                                                                            |
| -------- | -------------------------------------------------------------------------------------- |
| Assets   | UUID-identified records over content-addressed blobs. Upload inputs, download outputs. |
| Jobs     | One execution of a workflow. Durable, pollable, and cancelable.                        |

## Output URLs and How Long They Last

Three different lifetimes govern "the URL for my output" and they are not the same number. Any application that shows outputs to its own users has to plan for all three.

### The Two URL Shapes

| Shape                                                 | Where you get it                                                                                                          | Can a third party open it?                                                                              | How long it lasts                                    |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| Content endpoint, `{base}/api/v2/assets/{id}/content` | `url` on each entry of a job's `outputs`                                                                                  | No. It is an authenticated route and answers `401` without your API key.                                | Stable. It resolves for as long as the asset exists. |
| Signed storage URL                                    | `url` on an `Asset` response, the `302` `Location` the content endpoint redirects to, and `getDownloadUrl()` in both SDKs | Yes. It carries its own authorization, so a browser or another service reads it with no key of its own. | Short. Roughly 6 hours on Comfy Cloud today.         |

The practical consequence: `Output.url` is not a shareable link. Put it in an `<img src>` that your users' browsers load and they get a `401`, because their browser does not carry your API key. The signed URL is the one you can hand out.

Self-hosted ComfyUI behind [comfy-api-proxy](https://github.com/Comfy-Org/comfy-api-proxy) has no signed URLs at all. The proxy serves the bytes from the content endpoint, normal authentication applies, and the SDKs report the expiry as `null` (Python: `None`).

### Reading the Signed URL's Expiry

On Comfy Cloud and Comfy API deployments a signed URL is minted with a validity of **approximately 6 hours**. That number is a server-side setting rather than part of the API contract, so treat it as an order of magnitude and never hard-code it. Read the expiry off the response you were given:

* `url_expires_at` on an `Asset` response is the real expiry of the `url` in that same response.
* `getDownloadUrl()` returns it alongside the URL, as `expiresAt` in TypeScript and `expires_at` in Python.

### `url_expires_at` on a Job Output Is a Different Number

`url_expires_at` on an entry of a job's `outputs` is **not** the signed URL's expiry. On Comfy Cloud it repeats the job's own `expires_at`, which today is the job's `created_at` plus a fixed 30 day window.

That window is a placeholder. The platform has no job retention or garbage-collection policy behind it yet, so the 30 days is a stand-in that lets the field be non-null, not a commitment about how long an output stays fetchable. Do not read it as a promise, and do not key a cache off it. This page will be updated if a real retention policy replaces it.

### Showing an Output in Your Own Product

To still be showing an output a day later, do one of these:

* **Re-host the bytes.** Download the output once and copy it into your own storage. Most applications end up here.
* **Re-mint on demand.** Persist the asset `id`, then resolve it to a fresh URL (`GET /api/v2/assets/{id}`, or `getDownloadUrl()`) at the moment you render, and use that URL immediately.
* **Proxy it.** Fetch `Output.url` from your own backend, which already holds the API key, and stream the bytes to your user.

What does not work is persisting a signed URL. It is good for hours, not days, so a stored copy keeps working through local testing and then breaks for your users once it expires.

## Comfy Router

Comfy API v2 runs workflows as durable jobs you submit and poll. For direct model calls (one partner model, one request, the model's native input and output), see the [Comfy Router](/development/comfy-router/quickstart). Review the [Router limitations](/development/comfy-router/limitations) first. Router is not generally available yet.
