Upload an asset (single-call multipart)
Single-call `multipart/form-data` upload. The platform streams the
Upload an asset (single-call multipart)
Single-call multipart/form-data upload. The platform streams the
bytes through its trusted byte-path, dedups by the server-computed hash, and mints the asset record.
The blake3 hash is always computed server-side from the received bytes — a client-declared expected_hash is verified, never trusted (on Comfy Cloud and serverless, only when sent before file — see below). If location metadata (GPS, XMP, IPTC) is removed from an image before it is stored, the asset's hash is the hash of the stored bytes and can differ from expected_hash. On Comfy Cloud, an upload whose bytes open as a JPEG, PNG, WebP or classic TIFF (including TIFF-based camera RAW such as DNG, NEF, ARW and CR2, but not BigTIFF) and that is over 50 MiB is refused with 422 validation_error, whatever its content_type and whether or not it carries location metadata. A request that declares a Content-Length over Comfy Cloud's 200 MB (200,000,000-byte) body limit is refused before that check with a plain 413 that does not use the ErrorEnvelope shape. A body sent without a declared length is cut off when it passes that limit, and no 413 is sent: a cut-off while the fields before file are read fails with 422 invalid_body, and a cut-off inside the file usually fails with 500 upstream_error. Nothing after the file field is read, so a body that only passes the limit there is uploaded normally. Deployment-scoped surfaces neither strip location metadata nor apply the 50 MiB image cap; they limit the request body to 110 MB (110,000,000 bytes). A request that declares a Content-Length over that limit is refused with the same plain 413; a body sent without a declared length is cut off when it passes the limit, and the upload then fails with an error response that is not guaranteed to be a 413. The uploaded asset is referenceable immediately; any content scanning runs in the background and does not block the response.
Send file as the last part. Comfy Cloud and serverless deployments stream it straight into storage and read the other fields only up to it, so a part sent after file is never read: a content_type or file_path sent only after it is refused as missing (422); an optional field (expected_hash or tags) is silently ignored — the upload succeeds without the hash check or the caller's tags; on serverless deployments, a trailing expires_in is likewise ignored, losing the retention override; and a second file part is dropped, so only the first part's bytes are stored. Comfy Cloud ignores expires_in wherever it is sent, before or after file. The response does not say any of these were skipped.
An upload is a single request. v1 expects files of up to ~100 MB; the hard cap is the body limit of the surface it is sent to (above). Chunked/resumable large uploads are a deliberate open question.
Cloud's hosted API caps every part sent before file at 8 KiB, including a part it does not recognise (which it otherwise ignores), so an extra field over 8 KiB, such as file bytes sent under a misspelled name, is refused with 422 invalid_body. Parts sent after file are never read: the 8 KiB cap does not apply to them, and a metadata field sent there is treated as absent, so send every metadata field before file. A declared Content-Length still counts those bytes toward the size limit above; without one, a body that only exceeds the limit there is uploaded normally, since nothing after file is read.
On Comfy Cloud an upload fails with 422 upload_timed_out when no request bytes arrive for 30 seconds, or when the whole request takes longer than 10 minutes, however steadily bytes keep arriving. On Comfy Cloud an upload can also be refused with 503 upload_busy and Retry-After when the server is busy with other uploads: nothing was stored, so the same upload can be sent again after Retry-After. On a Developer Platform deployment the same 422 upload_timed_out applies when no request bytes arrive for 30 seconds, or when the whole request takes longer than 20 minutes.
OpenAPI
````yaml /openapi-v2.yaml post /api/v2/assets 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/assets: post: tags:
- assets summary: Upload an asset (single-call multipart) description: > Single-call
multipart/form-dataupload. The platform streams the
bytes through its trusted byte-path, dedups by the server-computed
hash, and mints the asset record.
The blake3 hash is always computed server-side from the received
bytes — a client-declared expected_hash is verified, never trusted
(on Comfy Cloud and serverless, only when sent before file — see below).
If location metadata (GPS, XMP, IPTC) is removed from an image before
it is stored, the asset's hash is the hash of the stored bytes and
can differ from expected_hash. On Comfy Cloud, an upload whose
bytes open as a JPEG, PNG, WebP or classic TIFF (including TIFF-based
camera RAW such as DNG, NEF, ARW and CR2, but not BigTIFF) and that
is over 50 MiB is refused with 422 validation_error, whatever its
content_type and whether or not it carries location metadata. A
request that declares a Content-Length over Comfy Cloud's 200 MB
(200,000,000-byte) body limit is refused before that check with a
plain 413 that does not use the ErrorEnvelope shape. A body sent
without a declared length is cut off when it passes that limit, and
no 413 is sent: a cut-off while the fields before file are read
fails with 422 invalid_body, and a cut-off inside the file usually
fails with 500 upstream_error. Nothing after the file field is
read, so a body that only passes the limit there is uploaded
normally.
Deployment-scoped surfaces neither strip location metadata nor apply
the 50 MiB image cap; they limit the request body to 110 MB
(110,000,000 bytes). A request that declares a Content-Length over
that limit is refused with the same plain 413; a body sent without a
declared length is cut off when it passes the limit, and the upload
then fails with an error response that is not guaranteed to be a 413.
The uploaded asset is referenceable immediately; any content scanning
runs in the background and does not block the response.
Send file as the last part. Comfy Cloud and serverless deployments
stream it straight into storage and read the other fields only up to
it, so a part sent after file is never read: a content_type or
file_path sent only after it is refused as missing (422); an
optional field (expected_hash or tags) is silently ignored — the
upload succeeds without the hash check or the caller's tags; on
serverless deployments, a trailing expires_in is likewise ignored,
losing the retention override; and a second file part is dropped,
so only the first part's bytes are stored. Comfy Cloud ignores
expires_in wherever it is sent, before or after file. The
response does not say any of these were skipped.
An upload is a single request. v1 expects files of up to ~100 MB;
the hard cap is the body limit of the surface it is sent to (above).
Chunked/resumable large uploads are a deliberate open question.
Cloud's hosted API caps every part sent before file at 8 KiB,
including a part it does not recognise (which it otherwise
ignores), so an extra field over 8 KiB, such as file bytes sent
under a misspelled name, is refused with 422 invalid_body. Parts
sent after file are never read: the 8 KiB cap does not apply to
them, and a metadata field sent there is treated as absent, so send
every metadata field before file. A declared Content-Length
still counts those bytes toward the size limit above; without one,
a body that only exceeds the limit there is uploaded normally,
since nothing after file is read.
On Comfy Cloud an upload fails with 422 upload_timed_out when no
request bytes arrive for 30 seconds, or when the whole request takes
longer than 10 minutes, however steadily bytes keep arriving.
On Comfy Cloud an upload can also be refused with 503 upload_busy
and Retry-After when the server is busy with other uploads: nothing
was stored, so the same upload can be sent again after Retry-After.
On a Developer Platform deployment the same 422 upload_timed_out
applies when no request bytes arrive for 30 seconds, or when the whole
request takes longer than 20 minutes. operationId: postAssets parameters:
- $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: multipart/form-data: schema: type: object required:
- file
- content_type
- file_path properties: content_type: type: string example: image/png description: >- The asset's media type. On Comfy Cloud it must be valid UTF-8, not blank, at most 255 bytes, must not start or end with whitespace, and must not contain control characters (C0, DEL, C1, U+2028, U+2029) or any invisible format or default-ignorable character (every Unicode general category Cf character, including the zero-width joiners and direction marks, and the other default-ignorable code points); otherwise the request is refused with 422
invalid_bodybefore anything is stored. An accepted value is stored as sent. A deployment refuses acontent_typethat is blank, is not valid UTF-8 or contains a control character (C0 other than tab, DEL, C1) or a bidi embedding, override or isolate (U+202A-U+202E, U+2066-U+2069), has a tab outside the whitespace that opens a parameter after a;, or whose part before its first;is nottype/subtype(two RFC 9110 tokens, optionally followed by spaces), with 422invalid_requestbefore anything is stored. file_path: type: string description: >- Placement path / filename (global-namespace-root form, e.g.photo.pngormodels/checkpoints/x.safetensors). On Comfy Cloud the last segment becomes the asset name, so it must be valid UTF-8, at most 255 bytes, must not start with., and must not contain control characters (C0, DEL, C1, U+2028, U+2029) or invisible format and default-ignorable characters (Unicode general category Cf, which includes the bidi embedding, override and isolate controls, soft hyphen, zero-width space, word joiner, BOM and tag characters, plus the other default-ignorable code points such as U+034F, U+2065 and the Hangul fillers); otherwise the request is refused with 422invalid_bodybefore anything is stored. ZWNJ/ZWJ (U+200C, U+200D) are allowed only between two visible non-ASCII characters (so not first, last, next to ASCII or next to another of these invisible characters, though one may follow an allowed variation selector, one right after an Indic virama on a letter of the same script may end a word, and a ZWJ after an Arabic-script letter that joins on both sides, or after that letter's marks, may precede ASCII such as a '.' or end the name), for Persian, Indic and emoji names. The direction marks U+200E, U+200F and U+061C are allowed, for right-to-left names, and so are the visible Arabic number signs (prepended concatenation marks such as U+0600, but not U+070F); the direction marks can still change how a name is displayed. The emoji presentation selectors U+FE0E and U+FE0F are allowed only after an ASCII digit,#or*that U+20E3 (the keycap) follows, after U+2139, the punctuation emoji U+203C, U+2049, U+3030 and U+303D or the math symbols U+2194, U+25FB-U+25FE, U+2934 and U+2935, and after any other symbol of category So except a regional indicator, a skin-tone modifier, a hair component or U+2800. Other variation selectors are allowed only after a base that can have variants: the Mongolian ones after a Mongolian letter, the rest after a unified Han ideograph, plus U+FE00 after the Myanmar and Phags-pa characters it is registered for. The Mongolian and Han rules follow scripts, not the registered sequence list. The tag characters are allowed only as the tag run of the England, Scotland and Wales flag emoji. These allowed invisible characters, white space, U+2800 and combining marks must not make up the whole segment or come before a leading.. A deployment keeps the wholefile_pathas the asset name, so it must be valid UTF-8 and must not contain a control character (C0 U+0000-U+001F, including tab, CR and LF; DEL U+007F; C1 U+0080-U+009F) or a bidi embedding, override or isolate (U+202A-U+202E, U+2066-U+2069); otherwise the request is refused with 422invalid_requestbefore anything is stored. Directory segments and other characters stay allowed there. example: photo.png expected_hash: type: string description: >- Optional client-computed blake3 (blake3:<hex>) of the bytes sent. Omit the part to skip verification: on Comfy Cloud and on a deployment a part sent empty is refused with 422 as malformed. Send it beforefile: nothing after thefilefield is read, so a trailingexpected_hashis neither verified nor refused, and the response does not say the check was skipped. Verified against the server-computed blake3 of the received bytes, not of the stored bytes; mismatch is rejected with 409hash_mismatch. On serverless deployments no asset is minted and no existing asset's retention is changed; elsewhere the upload is stored before the check, so the 409 returns no asset and a retry with the corrected expectation (and the same file extension) dedups onto it. On Comfy Cloud nothing removes that asset, so when the bytes themselves were wrong they stay stored: as an asset named after the last segment offile_path(x.safetensorsformodels/checkpoints/x.safetensors), or, when the bytes deduped onto an asset you already had, as that asset under its earlier name. The rest offile_pathis not recorded. On Comfy Cloud and on a deployment, whenexpected_hashis sent more than once beforefileonly the last value is checked, but an empty one among them is still refused with 422. example: blake3:9f8a1c0d... tags: type: array items: type: string description: >- Category tags (e.g.input). A create carries at most 64 tags, each a non-empty UTF-8 string of at most 256 bytes (surrounding whitespace included) with no NUL byte. A deployment addsinputto every asset and counts it, so it takes at most 63 of the caller's own; themodel_type:tags derived for a model asset are not counted. A tag set breaking a limit is refused with 422. The rest of this paragraph describes Cloud's hosted API and a deployment, not the self-hosted proxy. Both cap the bytes of alltagsparts sent beforefilecombined: 8 KiB on Cloud's hosted API (422invalid_body) and 64 KiB on a deployment (422invalid_request). The cap counts duplicates before they are removed and JSON escapes before they are decoded, and is checked before the count and 256-byte limits above, so a tag set within them can still be refused. Aquoted-printablepart is counted and read after it is decoded; a part in any otherContent-Transfer-Encodingis read as sent, so abase64part is stored as one tag holding its encoded text, while a7bit,8bitorbinarypart is read like a part with no encoding. A part is read as a JSON array when it starts with[(after leading whitespace) and is valid JSON or continues, after optional whitespace, with":["a","b"]is two tags,[]adds no tags (nor does an empty part), and a malformed array such as[1]or["ais refused with 422. Any other non-empty part is one bare tag, kept as literal text, sofoo\ud800sent as a bare part is stored as written. Invalid UTF-8 in atagspart, or a lone surrogate escape (e.g.\ud800) in a JSON-arraytagspart, is refused with 422 (invalid_bodyon Cloud,invalid_requeston a deployment). expires_in: type: integer minimum: 60 maximum: 604800 description: >- Optional retention override in seconds (60s–7d): the asset'sexpires_atbecomes now +expires_in, replacing the platform's default retention. Implementations without configurable retention ignore it. The bounds apply to this override only — the platform default is operator-configured and may lie outside them. example: 86400 file: type: string format: binary description: >- The raw bytes. The order of properties in this schema does not set the order of parts on the wire:filemust be the last part sent (see the field-order rule above). responses: '200': description: Bytes deduped to an existing blob; asset minted over it. content: application/json: schema: $ref: '#/components/schemas/Asset' '201': description: New blob stored; asset minted. content: application/json: schema: $ref: '#/components/schemas/Asset' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '409': description: 'hash_mismatch.' headers: Retry-After: $ref: '#/components/headers/RetryAfter' content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '413': description: >- The upload is over the body limit. On Comfy Cloud (200 MB, 200,000,000 bytes) and on deployment-scoped surfaces (110 MB, 110,000,000 bytes) the request declared aContent-Lengthover it; the server's body limit sends this before the upload is handled, so the body is not anErrorEnvelopeand its shape is not part of this contract. The self-hosted proxy instead refuses a file over its configured cap (100 MiB by default) with anErrorEnvelopewhose code ispayload_too_large. '422': description: >-idempotency_key_reuse,input_blocked(the bytes are already stored and flagged by content moderation, sofile_pathis not registered for them),upload_timed_out(the client stopped sending or sent too slowly; the server cannot recover the upload, so retry it from a faster connection), or validation failure — including atagsset over the limits above or a disallowed tag (invalid_requeston a deployment or the self-hosted proxy; a deployment answers a body that is notmultipart/form-datawith a boundary with a plain 500 instead). On a deployment that includes a truncatedfilepart: the body ends inside the part, before the delimiter that ends it. A body that stops right at that delimiter, without the final--, is not rejected: the part reads as complete and is stored. Comfy Cloud's asset upload answers validation failure instead withinvalid_content_type(the request is notmultipart/form-datawith a boundary),invalid_body(a malformed multipart body or upload field) orvalidation_error(the platform refused the upload, for example an image over the size cap or a disallowed tag). Cloud refuses a malformed multipart body withinvalid_bodywhen the fault is found before thefilepart. Cloud stops parsing atfile, so parts after it are never read, and a body that ends inside the streamed file currently gets 500upstream_errorinstead. The exception is an upload withexpected_hash: if Cloud accepts the upload before the whole file is read, it reads the rest. A body that ends inside thefilepart, before its delimiter, then getsinvalid_body, and a complete body gets 500upstream_errorinstead of 201 or 409; in both cases the asset is already stored, holding only the part of the file read before the upload was accepted.invalid_bodyalso coverstagsparts over the 8 KiB combined cap described undertags, and a body sent without a declared length that is cut off at the body limit, as described for this operation. Cloud uses the same code for a missingfile; a missingcontent_type, or one that breaks the rules undercontent_type; a missingfile_path, or one that is absolute, starts with., contains.., is not already in clean form (no//, no.segment such as/./, and no trailing/) or breaks the rules underfile_path; acontent_type,file_pathorexpected_hashpart over 8 KiB; and a non-emptyexpected_hashthat is notblake3:followed by 64 lowercase hex characters. Acontent_typeorfile_pathsent only afterfilecounts as missing (see the field-order rule above). Any Content-Type other thanmultipart/form-datawith aboundary(including a missing or unparseable one) getsinvalid_content_typeon Cloud. On Comfy Cloud and on a deployment, anexpected_hashpart that is present but empty is a malformed field (invalid_bodyon Comfy Cloud,invalid_requeston a deployment), not an omitted hash. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' '429': $ref: '#/components/responses/RateLimited' '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 rejected422idempotency_key_reuse(reject-on-duplicate, no response replay). Keys expire after 24h. schemas: Asset: type: object description: >- A user-owned record identified by a server-assigned UUID, backing an immutable blob whose content carries a server-computed blake3 hash.hashmay be computed lazily: an asset record (and its retrievable bytes) can exist before its hash is filled in. On an output,job_metadatacarries the labels its producing job was submitted with, so code holding only the asset knows which run it came from. It is absent for assets no job produced, for outputs of a job sent without labels, where the serving surface keeps no job labels, and when the labels could not be read: sojob_idwithoutjob_metadatadoes not prove the job had no labels. A create whose file path and bytes match an existing output answers with that output, so itsjob_idandjob_metadataare the output's. required: - id
- hash
- size_bytes
- content_type
- created_at
- url
- url_expires_at properties: id: type: string example: 9f8a1c0d-2b3e-4f56-8a7b-1c2d3e4f5a6b hash: type: string nullable: true description: '
blake3:<hex>; null while lazily computed.' example: blake3:9f8a1c0d... size_bytes: type: integer format: int64 example: 4816293 content_type: type: string example: image/png file_path: type: string nullable: true example: photo.png created_new: type: boolean description: >- OnPOST /api/v2/assetsresponses, distinguishes a brand-new blob (true) from a dedup hit against bytes the platform already had (false). OnPOST /api/v2/assets/from-hashresponses, true means a new asset reference was created over existing bytes (201); false means an existing asset was reused (200). created_at: type: string format: date-time url: type: string format: uri description: Short-lived content URL (signed, or proxy-served). url_expires_at: type: string format: date-time expires_at: type: string format: date-time nullable: true description: >- Retention deadline for the asset itself (distinct fromurl_expires_at, the signed URL's validity). Null or absent means the asset is non-expiring. On a dedup-hit create response the deadline may be later than now + the requested/default retention: re-referencing content extends its retention, never shortens it. job_id: type: string nullable: true description: >- ID of the job that produced this asset. Absent for assets no job produced, such as a fresh upload. job_metadata: allOf: - $ref: '#/components/schemas/JobMetadata' description: >- The labels the producing job was submitted with, read through
job_idon each read. Absent for assets no job produced, for outputs of a job sent without labels, where the serving surface keeps no job labels, when the job is gone, and when the labels could not be read: sojob_idwithoutjob_metadatadoes not prove the job had no labels. 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 afterRetry-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-listlimitthat 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) andsso_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 addsinvalid_content_type(422: the request is notmultipart/form-datawith 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) andupload_busy(503 + Retry-After: the server is busy with other uploads and nothing was stored, so retry). Job labels add:metadata_invalid(422: a submittedmetadatabreaks a limit;details.keynames the key, except for too many pairs, which has nodetails),metadata_not_supported(422: this surface keeps no job labels yet),invalid_metadata_filter(400) andinvalid_cursor(400). A surface that does not list jobs yet answersnot_implemented(501). A 429 is disambiguated byerror.codealone; 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 theorganizationquery 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 carriesnode_errors, that is keyed by node id and each value is aJobNodeError, the same shape as a job'serror.node_errors, whether the refusal came at submit (for exampleunknown_node_class, a node class the deployment's build does not contain) or from ComfyUI after dispatch. Withunknown_node_classerrors it carriesunknown_node_classes, the missing classes; withwaits_for_browsererrors,browser_wait_node_classes, the classes that wait for a browser. A submit refusal names at most fifty nodes. Forinvalid_node,invalid_inputsandinvalid_class_type, when it found more than fifty,node_errors_truncatedis true andmalformed_node_countcarries the full count; forwaits_for_browser,browser_wait_node_countdoes. Forunknown_node_classit names only nodes whose class is one of the at most ten listed inunknown_node_classes; when those nodes number more than fifty,node_errors_truncatedis true andunknown_node_countis 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 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 responses: Unauthorized: description: >-
unauthorized: missing or invalid credentials. A credential that could not be checked answersauth_unavailable(503) instead. content: application/json: schema: $ref: '#/components/schemas/ErrorEnvelope' Forbidden: description: >-forbidden— authenticated but not allowed. On a serverless deployment, alsosso_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' RateLimited: description: >-rate_limited— the caller has exceeded a request rate limit for this account. Account/rate-scoped, not resource-specific — this can be returned even for a job, asset or deployment the caller doesn't own or that doesn't exist. headers: Retry-After: $ref: '#/components/headers/RetryAfter' 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 afterRetry-After. Every operation at a deployment's address can answer this way. A job submit can also answer this 503 withdatabase_unavailable: the job could not be saved just now and nothing was started, so the same request can be sent again afterRetry-After. No other operation answersdatabase_unavailable. On Comfy Cloud an asset upload can also answer this 503 withupload_busy: the server is busy with other uploads and nothing was stored, so the same upload can be sent again afterRetry-After. Any operation can also answer this 503 withauth_unavailable: the credential could not be checked just now, so the same request can be sent again afterRetry-After. A job status read can also answer it withoutput_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 afterRetry-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 answers401with a message saying so. Self-hosted accepts unauthenticated requests by default and can be configured with a static bearer token.
````