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 athttps://cloud.comfy.org. Create 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, not on v2.
Comfy API deployments. An environment you deploy through the Developer Platform 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 for building and deploying.
Open-source ComfyUI, via the proxy. During the beta, a self-hosted ComfyUI speaks v2 through comfy-api-proxy, a small open-source service that runs alongside it:
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 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. - 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.
Base URLs
Endpoint Categories
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
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 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_aton anAssetresponse is the real expiry of theurlin that same response.getDownloadUrl()returns it alongside the URL, asexpiresAtin TypeScript andexpires_atin 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}, orgetDownloadUrl()) at the moment you render, and use that URL immediately. - Proxy it. Fetch
Output.urlfrom your own backend, which already holds the API key, and stream the bytes to your user.