Submit a workflow for execution
Accepts the API-format workflow graph verbatim. Validation is
synchronous: graph structure, unknown node classes, and asset
references (core/ASSET objects — every referenced id must exist
and be owned by the caller). A 201 means the job is durably
recorded and queued.
UI-format workflow JSON (the export with nodes/links) is
rejected with workflow_format_ui.
Idempotency-Key is single-use (reject-on-duplicate, NOT
record-and-replay): the first request to present a given key is
processed normally; ANY later request presenting the same key — a
retry, a concurrent duplicate, or a same-key request with a different
body — is rejected 422 idempotency_key_reuse and is never
re-executed. The key is claimed only for a request that actually
reaches submission and is released if that submission definitively
fails without creating a job (a validation error, or an upstream
reject such as out-of-credits or queue-full), so a legitimate retry
with the same key can proceed. If a submission’s outcome is unknown
(an upstream timeout or 5xx where the job may or may not have been
created), the key stays claimed and the retry is rejected: poll or
list your jobs to find the possibly-created job rather than
resubmitting. Keys expire after 24h. There is no response replay and
no Idempotency-Replayed header.
Reserved for post-MVP and rejected if present today: webhook_url,
inputs.
授权
Authorization: Bearer <credential>. The credential is one of: an account-scoped API key (comfyui-…), accepted on Cloud and serverless; a Comfy Cloud session JWT; or an OAuth access token issued for the Comfy Cloud resource. Which kinds a given deployment accepts is deployment configuration — an API key always works on Cloud and serverless, and a deployment that does not accept JWT bearers answers 401 with a message saying so. Self-hosted accepts unauthenticated requests by default and can be configured with a static bearer token.
请求头
Client-generated UUID (recommended). Single-use: the first request to present a key is processed; any later request with the same key is rejected 422 idempotency_key_reuse (reject-on-duplicate, no response replay). Keys expire after 24h.
请求体
API-format workflow graph, verbatim.
Per-prompt ComfyUI extra_data, same shape as Comfy Cloud and local ComfyUI. Closed object: only the enumerated keys are accepted, keeping the contract fully typed. Forwarded to the worker per-prompt and excluded from idempotency comparison. On a deployment it is dispatch-only and never stored; on Comfy Cloud it is persisted with the prompt, because the worker needs it, and redacted on every path that returns a workflow to a caller.
Send the one credential you hold: an API key as api_key_comfy_org, or the session token an interactively signed-in client has instead as auth_token_comfy_org. Sending both is accepted and both are forwarded, but it is not a supported combination and which one a node uses is not defined here. Note a session token is short-lived and is not re-minted for you, so one submitted long before it executes may expire in the queue.
Your own labels for the job, such as which of your customers it ran for. At most 16 pairs. A key is 1 to 40 characters from A-Z a-z 0-9 _ - .; a value is a string of at most 256 bytes in UTF-8 (bytes, not characters: 200 é is 400 bytes) with no control character (U+0000 to U+001F, tab and newline included, and U+007F to U+009F) and no bidirectional embedding, override or isolate (U+202A to U+202E, U+2066 to U+2069). Anything else is refused 422 metadata_invalid and no job is created: a bad key or value is named in the message and in details.key, while more than 16 pairs is refused with the count and no details. A metadata that is not an object is refused 400 invalid_request; null is the same as none. Stored with the job, returned on it, and filterable on GET /api/v2/jobs. Set once, here: nothing changes it later. Only jobs sent to a deployment keep it today: Comfy Cloud refuses a non-empty metadata with 422 metadata_not_supported, and runs a job with empty or absent metadata as before.
响应
Job created and queued.
One execution of a workflow. Durable from creation until expires_at; outputs populates incrementally during execution.
"7f3d2c1b-9a8e-4d6f-b012-3c4d5e6f7a8b"
Lifecycle: queued → running → succeeded | failed | expired; a cancel request, or the deletion of the deployment the job is running on, moves running → canceling → canceled. Terminal states: succeeded, canceled, failed, expired.
queued, running, succeeded, canceling, canceled, failed, expired Retention deadline — a platform property, not an API constant.
The latest progress snapshot; same data the SSE stream pushes.
Execution failure detail, carried in job.error (not an HTTP error).
Embedded follow-up links — follow these, don't build URLs. A link is either an absolute URL or a host-relative reference (leading /) that already includes any prefix the serving surface is mounted under (e.g. a serverless gateway's /deployment/{deployment_id}/api/v2). Clients MUST resolve a host-relative link against the request origin (scheme + authority), never against a configured base URL — joining it to a base URL that carries the same mount prefix duplicates the prefix.
Values are nullable (a metric not yet available — e.g. execution_ms before a job starts running — is null, not omitted); the example below is deliberately all-non-null purely to work around a Spectral/nimma lint-tooling crash on a literal null inside a schema example combined with additionalProperties.nullable: true — the schema itself is unchanged and still allows null values at runtime.
The deployment the job was sent to: the id in the address it was posted at, which stays the same when the deployment moves to another release. Absent on a surface that runs jobs on no deployment.
"dep-0f19a2b3c4d5"
The release of the deployment's build that ran the job, which can differ from the release the deployment runs now. Absent where the serving surface does not report it.
"7c1e9a40-3b2d-4f6a-9e81-0c5d2a7b4f13"
The version of the release in release_id, the number its build cut it as. Absent where the serving surface does not report it or could not look it up at the time of the answer.
x >= 13
The labels the job was submitted with, exactly as sent. Absent when it was sent with none.