> ## Documentation Index
> Fetch the complete documentation index at: https://docs.comfy.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 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`.




## OpenAPI

````yaml /openapi-v2.yaml post /api/v2/jobs
openapi: 3.0.3
info:
  title: Comfy API v2
  version: 2.0.0
  description: |
    The official, versioned HTTP API for running ComfyUI workflows from
    external applications: upload inputs, submit a workflow, observe
    execution, retrieve results.

    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; job state and
      outputs are retrievable by ID until `expires_at`.
    - **UUID identity, content-addressed dedup.** Assets are UUID-identified
      records over blobs keyed by a server-computed blake3 hash. The hash is
      nullable and may be computed lazily.
    - **Follow links, don't build URLs.** Responses embed follow-up URLs.

    Additive changes only within v2; breaking changes require v3.
servers:
  - url: http://127.0.0.1:8189
    description: Self-hosted (comfy-api-proxy)
  - url: https://cloud.comfy.org
    description: Comfy Cloud
  - url: https://{deployment}.run.comfy.app
    description: Serverless deployment
    variables:
      deployment:
        description: >-
          DNS-safe deployment id (subdomain label). Staging uses
          {deployment}.stg.run.comfy.app.
        default: dep-1234abcd-56ef-7890-abcd-ef1234567890
security:
  - bearerAuth: []
  - {}
tags:
  - name: assets
    description: UUID-identified records over content-addressed blobs.
  - name: jobs
    description: One execution of a workflow — durable, pollable, cancelable.
paths:
  /api/v2/jobs:
    post:
      tags:
        - jobs
      summary: Submit a workflow for execution
      description: |
        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`.
      operationId: postJobs
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - workflow
              properties:
                workflow:
                  type: object
                  description: API-format workflow graph, verbatim.
                  additionalProperties: true
                extra_data:
                  type: object
                  description: >-
                    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.
                  additionalProperties: false
                  properties:
                    api_key_comfy_org:
                      type: string
                      description: API key for partner (API) nodes.
                    auth_token_comfy_org:
                      type: string
                      description: >-
                        Session bearer token for partner (API) nodes — the
                        equivalent of `api_key_comfy_org` for a caller
                        authenticated by session rather than by key.
                    preview_method:
                      type: string
                      description: >-
                        ComfyUI's preview method for this prompt, passed to
                        ComfyUI as sent, which validates it. Used only for jobs
                        sent by Comfy Cloud's editor; ignored for other callers.
                    extra_pnginfo:
                      type: object
                      description: >-
                        ComfyUI's `extra_pnginfo` for this prompt, which carries
                        the editor's workflow into saved outputs. Used only for
                        jobs sent by Comfy Cloud's editor; ignored for other
                        callers.
                      additionalProperties: true
                metadata:
                  type: object
                  description: >-
                    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.
                  maxProperties: 16
                  additionalProperties:
                    type: string
                    description: >-
                      At most 256 bytes in UTF-8, which is what the server
                      counts. `maxLength` counts characters, so it is only an
                      upper bound: a shorter value with multi-byte characters
                      can still be refused.
                    maxLength: 256
                  x-go-type: interface{}
                  example:
                    client: acme
                    batch: '2026-10-05'
      responses:
        '201':
          description: Job created and queued.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          description: >-
            `invalid_request`: `metadata` is not an object. A body that is not
            JSON at all, or whose `workflow` or `extra_data` is not an object,
            is a `400` too, answered by the request decoder before any of these
            checks, with a bare `message` body rather than this envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: '`insufficient_credits` (Cloud / serverless only).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: >-
            `not_found`: on a deployment's address, no deployment there that the
            caller's workspace owns.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '422':
          description: >-
            `invalid_workflow` (with per-node details), `workflow_format_ui`,
            `missing_asset`, `idempotency_key_reuse`, `metadata_invalid` (for a
            bad key or value, the message and `details.key` name the key; for
            more than 16 pairs, the message gives the count and there are no
            `details`), or `metadata_not_supported` (a surface that keeps no job
            labels yet).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: >-
            `queue_full` (bounded queue depth reached) or, on deployment-scoped
            surfaces, `deployment_not_ready` (deployment still
            provisioning/starting) or `deployment_unavailable` (the deployment
            is ready but its GPU provider is not taking work on it yet), or
            `rate_limited` (the caller is past a request rate limit).
            Disambiguate by `error.code`; all four mean back off and retry after
            `Retry-After`.
          headers:
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/DeploymentLookupUnavailable'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
      description: >-
        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.
  schemas:
    Job:
      type: object
      description: >-
        One execution of a workflow. Durable from creation until `expires_at`;
        `outputs` populates incrementally during execution.
      required:
        - id
        - status
        - created_at
        - started_at
        - completed_at
        - expires_at
        - queue_position
        - progress
        - outputs
        - error
        - urls
      properties:
        id:
          type: string
          example: 7f3d2c1b-9a8e-4d6f-b012-3c4d5e6f7a8b
        status:
          $ref: '#/components/schemas/JobStatus'
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
          nullable: true
        completed_at:
          type: string
          format: date-time
          nullable: true
        expires_at:
          type: string
          format: date-time
          description: Retention deadline — a platform property, not an API constant.
        queue_position:
          type: integer
          nullable: true
        progress:
          allOf:
            - $ref: '#/components/schemas/Progress'
          nullable: true
          description: The latest progress snapshot; same data the SSE stream pushes.
        outputs:
          type: array
          items:
            $ref: '#/components/schemas/Output'
        error:
          allOf:
            - $ref: '#/components/schemas/JobError'
          nullable: true
        metrics:
          type: object
          description: >-
            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.
          additionalProperties:
            type: integer
            nullable: true
          example:
            queue_ms: 9000
            execution_ms: 42000
        urls:
          $ref: '#/components/schemas/JobUrls'
        deployment_id:
          type: string
          description: >-
            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.
          example: dep-0f19a2b3c4d5
        release_id:
          type: string
          description: >-
            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.
          example: 7c1e9a40-3b2d-4f6a-9e81-0c5d2a7b4f13
        release_version:
          type: integer
          minimum: 1
          description: >-
            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.
          example: 3
        metadata:
          $ref: '#/components/schemas/JobMetadata'
    ErrorEnvelope:
      type: object
      description: |
        Shared error envelope with machine-readable codes. Core codes (v1):
        `invalid_workflow` (422), `workflow_format_ui` (422),
        `missing_asset` (422), `hash_mismatch` (409), `blob_not_found`
        (404), `idempotency_key_reuse` (422), `upload_timed_out` (422: an
        asset upload stopped sending or was too slow; retry from a faster
        connection),
        `queue_full` (429 + Retry-After), `rate_limited` (429 + Retry-After:
        the caller is past a request rate limit; retry), `insufficient_credits`
        (402), `not_found` (404), `unauthorized` (401), `forbidden` (403).
        Deployment-scoped surfaces add: `deployment_not_ready` (429 +
        Retry-After — the deployment can still reach ready; retry),
        `deployment_unavailable` (429 + Retry-After: the deployment is ready
        but its GPU provider is not taking work on it yet; retry),
        `deployment_lookup_unavailable` (503 + Retry-After, on any
        operation: the deployment the address names could not be looked up
        just now; nothing was done, so retry), `database_unavailable` (503 +
        Retry-After, only on a job submit: the job could not be saved just
        now and nothing was started, so retry), `auth_unavailable` (503 +
        Retry-After, on any operation: the credential could not be checked
        just now, which says nothing about the credential, so retry),
        `output_unavailable` (503 + Retry-After, only on a job status read: an
        output of the job could not be prepared just now; the job is
        unchanged, so retry after `Retry-After`, and report the job if it
        keeps answering),
        `deployment_stopped` (422 — terminal deployment state; a retry
        cannot succeed without operator action), `invalid_request` (422:
        a malformed asset upload or asset-from-hash field, or a jobs-list
        `limit` that is not a positive integer), `validation_error` (422,
        Cloud: an asset upload or asset-from-hash field was refused, e.g. a
        tag over the tag limits), `content_blocked` (451:
        content moderation flagged the asset's bytes) and `sso_required` (403:
        the key is valid, but the account must sign in through its
        organization's single sign-on, which does not accept this key).
        Comfy Cloud's asset upload adds `invalid_content_type` (422: the
        request is not `multipart/form-data` with a boundary),
        `invalid_body` (422: a malformed multipart body or upload field),
        `validation_error` (422: the platform refused the upload, for example
        an image over the size cap or a disallowed tag) and `upload_busy`
        (503 + Retry-After: the server is busy with other uploads and nothing
        was stored, so retry).
        Job labels add: `metadata_invalid` (422: a submitted `metadata` breaks a
        limit; `details.key` names the key, except for too many pairs, which
        has no `details`), `metadata_not_supported` (422:
        this surface keeps no job labels yet), `invalid_metadata_filter` (400)
        and `invalid_cursor` (400). A surface that does not list jobs yet
        answers `not_implemented` (501). A 429 is disambiguated
        by `error.code` alone; clients should treat any 429 + Retry-After
        as "back off and retry".
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              example: invalid_workflow
            message:
              type: string
              example: 'Node 12 (KSampler): required input ''model'' is not connected'
            organization_id:
              type: string
              description: >-
                On `sso_required`: the organization whose single sign-on governs
                this key, the one that holds the account, else the one that
                holds the key's workspace. It is the `organization` query
                parameter of Comfy Cloud's single sign-on start; treat it as
                opaque. Absent when the organization is unknown, and on every
                other code.
              example: org_01HXYZEXAMPLE
            details:
              type: object
              nullable: true
              additionalProperties: true
              description: >-
                Machine-readable detail for the code. When it carries
                `node_errors`, that is keyed by node id and each value is a
                `JobNodeError`, the same shape as a job's `error.node_errors`,
                whether the refusal came at submit (for example
                `unknown_node_class`, a node class the deployment's build does
                not contain) or from ComfyUI after dispatch. With
                `unknown_node_class` errors it carries `unknown_node_classes`,
                the missing classes; with `waits_for_browser` errors,
                `browser_wait_node_classes`, the classes that wait for a
                browser. A submit refusal names at most fifty nodes. For
                `invalid_node`, `invalid_inputs` and `invalid_class_type`, when
                it found more than fifty, `node_errors_truncated` is true and
                `malformed_node_count` carries the full count; for
                `waits_for_browser`, `browser_wait_node_count` does. For
                `unknown_node_class` it names only nodes whose class is one of
                the at most ten listed in `unknown_node_classes`; when those
                nodes number more than fifty, `node_errors_truncated` is true
                and `unknown_node_count` is how many nodes have a listed class.
                Nodes whose class is past those ten are neither named nor
                counted.
              example:
                node_errors:
                  '12':
                    class_type: SomeCustomNode
                    errors:
                      - type: unknown_node_class
                        message: >-
                          this deployment's build does not contain the node
                          class SomeCustomNode.
                unknown_node_classes:
                  - SomeCustomNode
    JobStatus:
      type: string
      enum:
        - queued
        - running
        - succeeded
        - canceling
        - canceled
        - failed
        - expired
      description: |
        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.
    Progress:
      type: object
      description: >-
        Server-computed progress snapshot (node-count and sampler-step
        weighted). Complete per snapshot — one fully re-syncs a client.
      required:
        - value
        - nodes_done
        - nodes_total
      properties:
        value:
          type: number
          format: double
          minimum: 0
          maximum: 1
          description: Overall fraction, server-computed.
          example: 0.42
        nodes_done:
          type: integer
          example: 11
        nodes_total:
          type: integer
          example: 31
        current_node:
          type: string
          nullable: true
          example: '12'
        current_node_class:
          type: string
          nullable: true
          example: KSampler
        step:
          type: integer
          nullable: true
          example: 21
        steps:
          type: integer
          nullable: true
          example: 50
        message:
          type: string
          nullable: true
          example: KSampler 21/50
    Output:
      type: object
      description: >-
        A committed job output. Outputs are assets: `id` is the asset UUID,
        retrievable via GET /api/v2/assets/{id} for as long as the job is
        retained. `hash` is lazily computed and may be null on the retrieval hot
        path.
      required:
        - node_id
        - name
        - type
        - content_type
        - size_bytes
        - id
        - hash
        - url
        - url_expires_at
      properties:
        node_id:
          type: string
          description: >-
            The workflow node that reported this file; empty when the worker
            named none.
          example: '9'
        name:
          type: string
          example: ComfyUI_00001_.png
        type:
          $ref: '#/components/schemas/OutputType'
        content_type:
          type: string
          example: image/png
        size_bytes:
          type: integer
          format: int64
          example: 1848320
        id:
          type: string
          description: Asset UUID.
          example: 9f8a1c0d-2b3e-4f56-...
        hash:
          type: string
          nullable: true
          description: '`blake3:<hex>`; null until lazily computed.'
        url:
          type: string
          format: uri
        url_expires_at:
          type: string
          format: date-time
        job_id:
          type: string
          nullable: true
          description: ID of the job that produced this output.
    JobError:
      type: object
      description: Execution failure detail, carried in `job.error` (not an HTTP error).
      required:
        - code
        - message
      properties:
        code:
          type: string
          example: node_execution_error
        message:
          type: string
          description: >-
            Why the job failed, written for a person to read. On a serverless
            deployment, where ComfyUI refused the workflow, it names the
            rejected nodes it has room for and their reasons, which
            `node_errors` carries in full. Its wording may change; read `code`
            and `node_errors` rather than matching this text.
        node_id:
          type: string
          nullable: true
        class_type:
          type: string
          nullable: true
        traceback:
          type: string
          nullable: true
        node_errors:
          type: object
          description: >-
            Every node ComfyUI rejected when it refused the workflow before
            running any of it (a value outside its allowed range, a model the
            deployment does not contain, a graph that loops back on itself),
            keyed by node id, under the names ComfyUI gave them. Absent when the
            workflow ran and a node raised: `node_id`, `class_type` and
            `traceback` describe that failure instead.
          additionalProperties:
            $ref: '#/components/schemas/JobNodeError'
          example:
            '22':
              class_type: LoraLoader
              errors:
                - type: value_not_in_list
                  message: Value not in list
                  details: >-
                    lora_name: 'sdxl\Hyper-SDXL-8steps-lora.safetensors' not in
                    (list of length 40)
    JobUrls:
      type: object
      description: >-
        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.
      required:
        - self
        - events
        - cancel
      properties:
        self:
          type: string
          format: uri-reference
        events:
          type: string
          format: uri-reference
        cancel:
          type: string
          format: uri-reference
        logs:
          type: string
          format: uri-reference
          description: >-
            Where to read what this run printed. Present on any surface that
            captures execution logs, which is why it is the one link here that
            is optional: absent means this surface captures none, for any job,
            so a client can stop looking without spending a request on an answer
            it already has.

            Follow this link rather than building the path from the job id. The
            two are not interchangeable: a surface may be mounted under a prefix
            this link already carries and a hand-built path would not, and a
            surface that does not implement the operation at all answers a
            routing `404` — indistinguishable, to the client, from the `404`
            that means the job itself is gone. Present does NOT mean this job
            has a log, and it is deliberately not a signal about one: a surface
            that captures logs offers the link on every job, including those it
            will answer `204` for and those whose log it withholds. Read the
            log, not the link.
    JobMetadata:
      type: object
      description: >-
        The labels the job was submitted with, exactly as sent. Absent when it
        was sent with none.
      additionalProperties:
        type: string
      example:
        client: acme
    OutputType:
      type: string
      enum:
        - image
        - video
        - audio
        - text
        - file
        - latent
      description: Normalized output kind — nothing silently dropped.
    JobNodeError:
      type: object
      description: >-
        One node that was rejected, and why: by ComfyUI when it refused the
        workflow after dispatch, or by the gateway when it refused the workflow
        at submit.
      required:
        - errors
      properties:
        class_type:
          type: string
        errors:
          type: array
          items:
            $ref: '#/components/schemas/JobNodeErrorReason'
    JobNodeErrorReason:
      type: object
      description: >-
        One problem found with a node. `type` is the code for it: ComfyUI's (for
        example `value_not_in_list`, `value_bigger_than_max`,
        `dependency_cycle`), or one of the gateway's, sent where its submit
        checks are switched on: `unknown_node_class` (a node class the
        deployment's build does not contain), `waits_for_browser` (a node the
        workflow would run whose class waits for a browser tab to answer while
        the job runs, which a deployment never has), `invalid_node` (the node is
        not a JSON object), `invalid_inputs` (its `inputs` is present but not an
        object, refused only where the deployment's ComfyUI would fail such a
        node anyway, so no workflow that runs today is refused), or
        `invalid_class_type` (its `class_type` is missing or is not a non-empty
        string). ComfyUI's `missing_node_type` means the same as
        `unknown_node_class`, found after dispatch rather than at submit. For
        either, `message` ends naming the node pack that provides the class
        where the Comfy node registry knows one. `details` usually starts with
        the input it is about.
      required:
        - type
        - message
      properties:
        type:
          type: string
          example: value_not_in_list
        message:
          type: string
          example: Value not in list
        details:
          type: string
  responses:
    Unauthorized:
      description: >-
        `unauthorized`: missing or invalid credentials. A credential that could
        not be checked answers `auth_unavailable` (503) instead.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Forbidden:
      description: >-
        `forbidden` — authenticated but not allowed. On a serverless deployment,
        also `sso_required` — the key is valid, but the account must sign in
        through its organization's single sign-on, which does not accept this
        key; it can come back on any operation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    UpstreamError:
      description: >-
        `upstream_error` — an unexpected failure reaching or processing the
        request in this implementation's backing services. The message is always
        a generic, safe-to-display string; implementation detail (the specific
        upstream, its error text, transport failures) is never included here —
        see each implementation's own error-mapping notes. Every operation in
        this contract can fail this way.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    DeploymentLookupUnavailable:
      description: >-
        On deployment-scoped surfaces, `deployment_lookup_unavailable`: the
        deployment this address names could not be looked up just now. The
        request was refused before it did anything (nothing was created, read,
        changed or canceled), so the same request can be sent again after
        `Retry-After`. Every operation at a deployment's address can answer this
        way. A job submit can also answer this 503 with `database_unavailable`:
        the job could not be saved just now and nothing was started, so the same
        request can be sent again after `Retry-After`. No other operation
        answers `database_unavailable`. On Comfy Cloud an asset upload can also
        answer this 503 with `upload_busy`: the server is busy with other
        uploads and nothing was stored, so the same upload can be sent again
        after `Retry-After`. Any operation can also answer this 503 with
        `auth_unavailable`: the credential could not be checked just now, so the
        same request can be sent again after `Retry-After`. A job status read
        can also answer it with `output_unavailable`: an output of the job could
        not be prepared just now, and the job is unchanged. A transient storage
        failure clears on a later read after `Retry-After`; an output whose
        stored address is broken answers it on every read until the platform
        repairs the output.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  headers:
    RetryAfter:
      schema:
        type: integer
      description: Seconds to wait before retrying.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        `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.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.