From 7984a6a38eba7418dcbe6d2c977d461a84ac80f6 Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Fri, 22 May 2026 16:15:18 -0700 Subject: [PATCH] openapi: rename 55 cloud-side operationIds to match runtime (PR A of 3) (#14060) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * openapi: rename 55 cloud-side operationIds to match runtime handlers For the 55 operations below, vendor's operationId did not match the name cloud's runtime handlers expect. Generated types from vendor therefore had different names (e.g. CreateSubscription200JSONResponse) than what cloud handlers reference (Subscribe200JSONResponse), which blocks the post-cutover combined-spec codegen. All 55 renames target the cloud-runtime-authoritative name. Several of these endpoints are shared concepts (queue, settings, userdata, object_info) that OSS local also serves — the rename aligns vendor with the longstanding cloud handler-side convention to unblock the shared codegen. No request/response *shape* changes in this PR; only operationId labels. Notable categories: - Billing/subscriptions: 7 renames (subscribe, getBillingPlans, ...) - Workspace + workflows: 13 renames (createWorkflow, ...) - Hub: 3 renames - Auth/users: 5 renames - Shared OSS surface (settings, queue, view, userdata): 12 renames - Misc cloud-only: 15 renames Identified via Comfy-Org/cloud's TestCutoverSafe build-safety gate (BE-1106), which compares handler type references against codegen output from the combined spec. * fix(openapi): resolve getHistory operationId collision Spectral flagged: both /api/history (OSS local) and /api/history_v2 (cloud) had operationId 'getHistory' after the rename. Rename vendor's /api/history to 'getPromptHistory' to disambiguate. Cloud's runtime denies /api/history at the overlay level so combined codegen is unaffected by this change. * openapi: add 41 cloud-runtime schemas to components.schemas (PR B of 3) (#14061) * openapi: add 41 cloud-runtime schemas to components.schemas (cutover prep) Adds schemas that exist in Comfy-Org/cloud's hand-written ingest spec but not yet in this vendored OSS spec. All tagged x-runtime: [cloud] per the field-drift convention and prefixed with [cloud-only] in the description. These schemas are referenced by cloud's Go handlers via the generated ingest. Go type names. Codegen from the vendored spec didn't produce those types because the schemas weren't declared here. Adding them unblocks the post-cutover combined-spec codegen. Schemas added (alphabetical): AssetDownloadResponse, AssetMetadataResponse, BillingBalanceResponse, BillingPlansResponse, BillingStatusResponse, GetUserDataResponseFull, HistoryDetailEntry, HistoryDetailResponse, HistoryResponse, HubLabelInfo, HubProfileSummary, HubWorkflowListResponse, HubWorkflowStatus, HubWorkflowSummary, HubWorkflowTemplateEntry, JobStatusResponse, JobsListResponse, LabelRef, LogsResponse, Member, OAuthRegisterBadRequestResponse, PendingInvite, Plan, PlanAvailability, PlanAvailabilityReason, PlanSeatSummary, PreviewPlanInfo, PreviewSubscribeResponse, PublishedWorkflowDetail, SecretResponse, SubscriptionDuration, SubscriptionTier, UserDataResponseFull, ValidationError, ValidationResult, WorkflowForkedFrom, WorkflowResponse, WorkflowVersionContentResponse, WorkspaceAPIKeyInfo, WorkspaceSummary, WorkspaceWithRole Identified via Comfy-Org/cloud's TestCutoverSafe build-safety gate (BE-1106). Companion to PR #14060 (operationId renames). * fix(openapi): add BindingErrorResponse schema OAuthRegisterBadRequestResponse references BindingErrorResponse but that schema wasn't in the original add. Adding it now as a cloud-only schema matching the cloud runtime's binding-error shape (single 'message' string field). * openapi: add missing 4xx/5xx response bodies for cloud-emitting endpoints (#14063) Vendor declares shared endpoints (e.g. /api/queue, /api/settings, /api/assets/*, /api/billing/*) with success responses but is missing many of the 4xx/5xx error response bodies that Comfy-Org/cloud's runtime actually emits. Cloud's Go handlers reference the generated ingest.OpJSONResponse types for these missing statuses, which currently fail to resolve when codegen runs against the vendored spec. This PR adds 237 response entries across 117 operations, restoring the documented error responses that cloud emits. Bodies are copied verbatim from Comfy-Org/cloud's hand-written ingest spec (services/ingest/openapi.yaml) and reference a new ErrorResponse schema also added in this PR (matches cloud's {code, message} runtime shape, tagged x-runtime: [cloud]). ErrorResponse is intentionally separate from the existing CloudError schema. CloudError's shape ({error}) describes one runtime; cloud emits a different shape ({code, message}). Existing CloudError refs in vendor are untouched; new cloud-emitting error references use ErrorResponse. Identified via Comfy-Org/cloud's TestCutoverSafe build-safety gate (BE-1106). Companion to PR #14060 (operationId renames) and PR #14061 (cloud-only schema additions). --- openapi.yaml | 2737 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 2680 insertions(+), 57 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index 8fb769bc8..59b6817e5 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -104,6 +104,8 @@ paths: responses: "101": description: WebSocket upgrade successful + '401': + description: Unauthorized x-websocket-messages: - type: status schema: @@ -170,6 +172,18 @@ paths: application/json: schema: $ref: "#/components/schemas/PromptInfo" + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: operationId: executePrompt tags: [prompt] @@ -195,12 +209,36 @@ paths: schema: $ref: "#/components/schemas/PromptErrorResponse" + '402': + description: Payment required - Insufficient credits + content: + application/json: + schema: + $ref: '#/components/schemas/PromptErrorResponse' + '429': + description: Payment required - User has not paid + content: + application/json: + schema: + $ref: '#/components/schemas/PromptErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/PromptErrorResponse' + '503': + description: Service unavailable + content: + application/json: + schema: + $ref: '#/components/schemas/PromptErrorResponse' # --------------------------------------------------------------------------- # Queue # --------------------------------------------------------------------------- /api/queue: get: - operationId: getQueue + operationId: getQueueInfo tags: [queue] summary: Get running and pending queue items description: Returns the server's current execution queue, split into the currently-running prompt and the list of pending prompts. @@ -211,6 +249,18 @@ paths: application/json: schema: $ref: "#/components/schemas/QueueInfo" + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: operationId: manageQueue tags: [queue] @@ -226,9 +276,27 @@ paths: "200": description: Queue updated + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/interrupt: post: - operationId: interruptExecution + operationId: interruptJob tags: [queue] summary: Interrupt current execution description: Interrupts the prompt that is currently executing. The next queued prompt (if any) will start immediately after. @@ -247,6 +315,18 @@ paths: "200": description: Interrupt signal sent + '401': + description: Unauthorized - Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/free: post: operationId: freeMemory @@ -327,9 +407,21 @@ paths: pagination: $ref: "#/components/schemas/PaginationInfo" + '401': + description: Unauthorized - Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/jobs/{job_id}: get: - operationId: getJob + operationId: getJobDetail tags: [queue] summary: Get a single job by ID description: Returns the full record for a single completed prompt execution, including its outputs, status, and metadata. @@ -351,12 +443,30 @@ paths: "404": description: Job not found + '401': + description: Unauthorized - Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Forbidden - Job does not belong to user + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # History # --------------------------------------------------------------------------- /api/history: get: - operationId: getHistory + operationId: getPromptHistory tags: [history] summary: Get execution history deprecated: true @@ -388,6 +498,8 @@ paths: type: object additionalProperties: $ref: "#/components/schemas/HistoryEntry" + '404': + description: "Not Found \u2014 use /api/history_v2 instead" post: operationId: manageHistory tags: [history] @@ -409,6 +521,24 @@ paths: "200": description: History updated + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized - Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/history/{prompt_id}: get: operationId: getHistoryByPromptId @@ -438,6 +568,8 @@ paths: additionalProperties: $ref: "#/components/schemas/HistoryEntry" + '404': + description: "Not Found \u2014 use /api/jobs/{prompt_id} instead" # --------------------------------------------------------------------------- # Upload # --------------------------------------------------------------------------- @@ -481,6 +613,18 @@ paths: "400": description: No file provided or invalid request + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/upload/mask: post: operationId: uploadMask @@ -539,6 +683,18 @@ paths: "400": description: No file provided or invalid request + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # View # --------------------------------------------------------------------------- @@ -601,6 +757,33 @@ paths: "404": description: File not found + '302': + description: Redirect to GCS signed URL + headers: + Location: + description: Signed URL to access the file in GCS + schema: + type: string + Cache-Control: + description: Cache directive for the redirect response + schema: + type: string + Vary: + description: Headers that affect response caching + schema: + type: string + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/view_metadata/{folder_name}: get: operationId: viewMetadata @@ -648,6 +831,12 @@ paths: schema: $ref: "#/components/schemas/SystemStatsResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/features: get: operationId: getFeatures @@ -706,7 +895,7 @@ paths: # --------------------------------------------------------------------------- /api/object_info: get: - operationId: getObjectInfo + operationId: getNodeInfo tags: [node] summary: Get all node definitions description: | @@ -782,6 +971,8 @@ paths: items: type: string + '404': + description: "Not Found \u2014 use /api/experiment/models instead" /api/models/{folder}: get: operationId: getModelsByFolder @@ -809,7 +1000,7 @@ paths: /api/experiment/models: get: - operationId: getExperimentModels + operationId: getModelFolders tags: [model] summary: List model folders with paths description: Returns an array of model folder objects with name and folder paths. @@ -823,9 +1014,15 @@ paths: items: $ref: "#/components/schemas/ModelFolder" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/experiment/models/{folder}: get: - operationId: getExperimentModelsByFolder + operationId: getModelsInFolder tags: [model] summary: List model files with metadata description: Returns the model files in the given folder with richer metadata (path index, mtime, size) than the legacy `/api/models/{folder}` endpoint. @@ -848,6 +1045,12 @@ paths: "404": description: Unknown folder type + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/experiment/models/preview/{folder}/{path_index}/{filename}: get: operationId: getModelPreview @@ -884,12 +1087,18 @@ paths: "404": description: Preview not found + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Users # --------------------------------------------------------------------------- /api/users: get: - operationId: getUsers + operationId: getUsersInfo tags: [user] summary: Get user storage info description: | @@ -917,6 +1126,12 @@ paths: additionalProperties: type: string description: Map of user_id to directory name (multi-user) + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: operationId: createUser tags: [user] @@ -952,7 +1167,7 @@ paths: # --------------------------------------------------------------------------- /api/userdata: get: - operationId: listUserdata + operationId: getUserdata tags: [userdata] summary: List files in a userdata directory description: Lists files in the authenticated user's data directory. Returns either filename strings or full objects depending on the `full_info` query parameter. @@ -989,6 +1204,24 @@ paths: "404": description: Directory not found + '400': + description: Bad request (e.g., invalid filename). + content: + text/plain: + schema: + type: string + '401': + description: Unauthorized. + content: + text/plain: + schema: + type: string + '500': + description: General error + content: + text/plain: + schema: + type: string /api/v2/userdata: get: operationId: listUserdataV2 @@ -1025,6 +1258,8 @@ paths: type: number description: Unix timestamp + '404': + description: "Not Found \u2014 use /api/userdata instead" /api/userdata/{file}: get: operationId: getUserdataFile @@ -1049,8 +1284,26 @@ paths: format: binary "404": description: File not found + '400': + description: Bad request (e.g., invalid filename). + content: + text/plain: + schema: + type: string + '401': + description: Unauthorized. + content: + text/plain: + schema: + type: string + '500': + description: General error + content: + text/plain: + schema: + type: string post: - operationId: writeUserdataFile + operationId: postUserdataFile tags: [userdata] summary: Write or create a userdata file description: Writes (creates or replaces) a file in the authenticated user's data directory. @@ -1090,6 +1343,30 @@ paths: $ref: "#/components/schemas/UserDataResponse" "409": description: File exists and overwrite not set + '400': + description: Missing or invalid 'file' parameter. + content: + text/plain: + schema: + type: string + '401': + description: Unauthorized. + content: + text/plain: + schema: + type: string + '403': + description: The requested path is not allowed. + content: + text/plain: + schema: + type: string + '500': + description: General error + content: + text/plain: + schema: + type: string delete: operationId: deleteUserdataFile tags: [userdata] @@ -1109,6 +1386,18 @@ paths: "404": description: File not found + '401': + description: Unauthorized. + content: + text/plain: + schema: + type: string + '500': + description: Internal server error. + content: + text/plain: + schema: + type: string /api/userdata/{file}/move/{dest}: post: operationId: moveUserdataFile @@ -1151,12 +1440,30 @@ paths: "409": description: Destination exists and overwrite not set + '400': + description: Missing or invalid parameters. + content: + text/plain: + schema: + type: string + '401': + description: Unauthorized. + content: + text/plain: + schema: + type: string + '500': + description: General error + content: + text/plain: + schema: + type: string # --------------------------------------------------------------------------- # Settings # --------------------------------------------------------------------------- /api/settings: get: - operationId: getSettings + operationId: getAllSettings tags: [settings] summary: Get all user settings description: Returns all settings for the authenticated user. @@ -1170,8 +1477,14 @@ paths: schema: type: object additionalProperties: true + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: - operationId: updateSettings + operationId: updateMultipleSettings tags: [settings] summary: Update user settings (partial merge) description: Replaces the authenticated user's settings with the provided object. @@ -1189,9 +1502,21 @@ paths: "200": description: Settings updated + '400': + description: Invalid request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/settings/{id}: get: - operationId: getSetting + operationId: getSettingById tags: [settings] summary: Get a single setting by key description: Returns the value of a single setting, identified by key. @@ -1211,8 +1536,20 @@ paths: schema: nullable: true description: The setting value (any JSON type), or null if not set + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Setting not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: - operationId: updateSetting + operationId: updateSettingById tags: [settings] summary: Set a single setting value description: Sets the value of a single setting, identified by key. @@ -1234,6 +1571,18 @@ paths: "200": description: Setting updated + '400': + description: Invalid request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Extensions / Templates / i18n # --------------------------------------------------------------------------- @@ -1308,6 +1657,12 @@ paths: additionalProperties: $ref: "#/components/schemas/GlobalSubgraphInfo" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/global_subgraphs/{id}: get: operationId: getGlobalSubgraph @@ -1331,6 +1686,12 @@ paths: "404": description: Subgraph not found + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Node Replacements # --------------------------------------------------------------------------- @@ -1351,6 +1712,12 @@ paths: type: object additionalProperties: true + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Internal (x-internal: true) # --------------------------------------------------------------------------- @@ -1454,7 +1821,7 @@ paths: /internal/files/{directory_type}: get: - operationId: getInternalFiles + operationId: getFiles tags: [internal] summary: List files in a directory type description: Lists the files present in one of ComfyUI's known directories (input, output, or temp). @@ -1476,6 +1843,12 @@ paths: items: type: string + '400': + description: Invalid directory type + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Assets (x-feature-gate: enable-assets) # --------------------------------------------------------------------------- @@ -1499,6 +1872,24 @@ paths: "404": description: No asset with this hash + '400': + description: Invalid hash format + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets: get: operationId: listAssets @@ -1575,8 +1966,26 @@ paths: application/json: schema: $ref: "#/components/schemas/ListAssetsResponse" + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: - operationId: createAsset + operationId: uploadAsset tags: [assets] summary: Upload a new asset description: Uploads a new asset (binary content plus metadata) and registers it in the asset database. @@ -1664,6 +2073,60 @@ paths: schema: $ref: "#/components/schemas/AssetCreated" + '200': + description: Asset already exists (returned existing asset) + content: + application/json: + schema: + $ref: '#/components/schemas/AssetCreated' + '400': + description: Invalid request (bad file, invalid URL, invalid content type, etc.) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '403': + description: Source URL requires authentication or access denied + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Source URL not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '413': + description: File too large + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '415': + description: Unsupported media type + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Download failed due to network error or timeout + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/from-hash: post: operationId: createAssetFromHash @@ -1707,9 +2170,39 @@ paths: schema: $ref: "#/components/schemas/AssetCreated" + '200': + description: Asset reference already exists (returned existing) + content: + application/json: + schema: + $ref: '#/components/schemas/AssetCreated' + '400': + description: Invalid request (bad hash format, invalid tags, etc.) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Source asset with given hash not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/{id}: get: - operationId: getAsset + operationId: getAssetById tags: [assets] summary: Get asset metadata description: Returns the metadata for a single asset. @@ -1731,6 +2224,18 @@ paths: $ref: "#/components/schemas/Asset" "404": description: Asset not found + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' put: operationId: updateAsset tags: [assets] @@ -1775,6 +2280,30 @@ paths: application/json: schema: $ref: "#/components/schemas/AssetUpdated" + '400': + description: Invalid request (no fields provided) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Asset not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteAsset tags: [assets] @@ -1798,6 +2327,30 @@ paths: "204": description: Asset deleted + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Asset not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '409': + description: Asset cannot be deleted because it is referenced by another resource (e.g., workflow version) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/{id}/content: get: operationId: getAssetContent @@ -1859,6 +2412,36 @@ paths: application/json: schema: $ref: "#/components/schemas/TagsModificationResponse" + '400': + description: Invalid request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Asset not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error (e.g., reserved tag) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' delete: operationId: removeAssetTags tags: [assets] @@ -1894,6 +2477,36 @@ paths: schema: $ref: "#/components/schemas/TagsModificationResponse" + '400': + description: Invalid request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Asset not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error (e.g., reserved tag) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/tags: get: operationId: listTags @@ -1923,9 +2536,27 @@ paths: schema: $ref: "#/components/schemas/ListTagsResponse" + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/tags/refine: get: - operationId: refineAssetTags + operationId: getAssetTagHistogram tags: [assets] summary: Get tag counts for assets matching current filters description: Returns suggested additional tags that would refine a filtered asset query, together with the count of assets each tag would select. @@ -1986,6 +2617,24 @@ paths: schema: $ref: "#/components/schemas/AssetTagHistogramResponse" + '400': + description: Invalid request parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/seed: post: operationId: seedAssets @@ -2117,9 +2766,21 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '400': + description: Bad Request - job_id is not a valid UUID (emitted by request validation before the handler runs) + content: + application/json: + schema: + $ref: '#/components/schemas/BindingErrorResponse' + '500': + description: Internal server error - cancellation failed + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/job/{job_id}/status: get: - operationId: getCloudJobStatus + operationId: getJobStatus tags: [queue] summary: Get status of a cloud job deprecated: true @@ -2156,6 +2817,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Forbidden - job belongs to another user + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/prompt/{prompt_id}: get: operationId: getCloudPrompt @@ -2193,7 +2866,7 @@ paths: /api/history_v2: get: - operationId: getHistoryV2 + operationId: getHistory tags: [history] summary: Get paginated execution history (v2) deprecated: true @@ -2234,9 +2907,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/history_v2/{prompt_id}: get: - operationId: getHistoryV2ByPromptId + operationId: getHistoryForPrompt tags: [history] summary: Get v2 history for a specific prompt deprecated: true @@ -2273,9 +2952,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/logs: get: - operationId: getCloudLogs + operationId: getLogs tags: [system] summary: Get cloud execution logs deprecated: true @@ -2322,7 +3007,7 @@ paths: # --------------------------------------------------------------------------- /api/assets/download: post: - operationId: downloadAssets + operationId: createAssetDownload tags: [assets] summary: Download assets to cloud runtime description: "[cloud-only] Initiates a download of one or more assets to the cloud runtime environment. Returns a task ID for tracking download progress via WebSocket." @@ -2376,9 +3061,27 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '200': + description: File already exists in storage - asset created/returned immediately + content: + application/json: + schema: + $ref: '#/components/schemas/AssetCreated' + '422': + description: Validation errors + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/export: post: - operationId: exportAssets + operationId: createAssetExport tags: [assets] summary: Export assets as a downloadable archive description: "[cloud-only] Initiates a bulk export of assets. Returns a task ID for tracking progress via WebSocket. When complete, the export can be downloaded via the exports endpoint." @@ -2436,6 +3139,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/exports/{exportName}: get: operationId: getAssetExport @@ -2471,9 +3180,21 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '400': + description: Invalid export name + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/from-workflow: post: - operationId: createAssetsFromWorkflow + operationId: postAssetsFromWorkflow tags: [assets] summary: Create asset records from a workflow execution description: "[cloud-only] Registers output files from a workflow execution as assets in the asset database." @@ -2527,6 +3248,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/import: post: operationId: importPublishedAssets @@ -2561,9 +3288,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/assets/remote-metadata: get: - operationId: getAssetRemoteMetadata + operationId: getRemoteAssetMetadata tags: [assets] summary: Fetch metadata for a remote asset URL description: "[cloud-only] Fetches and returns metadata (content type, size, filename) for a remote URL without downloading the full content." @@ -2596,6 +3329,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '422': + description: Failed to retrieve metadata from source + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Custom nodes / hub (cloud) # --------------------------------------------------------------------------- @@ -2751,7 +3496,7 @@ paths: /api/hub/assets/upload-url: post: - operationId: getHubAssetUploadUrl + operationId: createHubAssetUploadUrl tags: [hub] summary: Get a pre-signed upload URL for a hub asset description: "[cloud-only] Returns a pre-signed URL that can be used to upload an asset file directly to storage." @@ -2805,6 +3550,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/hub/labels: get: operationId: listHubLabels @@ -2822,6 +3579,18 @@ paths: items: $ref: "#/components/schemas/HubLabel" + '400': + description: Bad request (e.g. invalid type parameter) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/hub/profiles: get: operationId: listHubProfiles @@ -2905,6 +3674,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/hub/profiles/{username}: get: operationId: getHubProfile @@ -2933,9 +3708,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/hub/profiles/check: get: - operationId: checkHubProfileUsername + operationId: checkHubUsername tags: [hub] summary: Check if a hub username is available description: "[cloud-only] Returns whether the given username is available for registration." @@ -2960,6 +3741,24 @@ paths: username: type: string + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/hub/profiles/me: get: operationId: getMyHubProfile @@ -2980,6 +3779,18 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '404': + description: No hub profile exists + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' put: operationId: updateMyHubProfile tags: [hub] @@ -3079,6 +3890,24 @@ paths: application/json: schema: $ref: "#/components/schemas/HubWorkflowList" + '400': + description: Bad request (e.g. malformed pagination cursor) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Profile not found (when filtering by username) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: operationId: publishHubWorkflow tags: [hub] @@ -3117,6 +3946,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/hub/workflows/{share_id}: get: operationId: getHubWorkflow @@ -3144,6 +3979,18 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '413': + description: Workflow JSON too large + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteHubWorkflow tags: [hub] @@ -3173,9 +4020,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/hub/workflows/index: get: - operationId: getHubWorkflowIndex + operationId: listHubWorkflowIndex tags: [hub] summary: Get the hub workflow index description: "[cloud-only] Returns the lightweight index of all hub workflows for client-side search and navigation." @@ -3190,12 +4043,18 @@ paths: items: $ref: "#/components/schemas/HubWorkflowIndexEntry" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Workflows (cloud) # --------------------------------------------------------------------------- /api/workflows: get: - operationId: listCloudWorkflows + operationId: listWorkflows tags: [workflows] summary: List cloud workflows description: "[cloud-only] Returns a paginated list of the authenticated user's cloud workflows." @@ -3240,8 +4099,14 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: - operationId: createCloudWorkflow + operationId: createWorkflow tags: [workflows] summary: Create a new cloud workflow description: "[cloud-only] Creates a new cloud workflow with the provided name and optional initial content." @@ -3285,9 +4150,21 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workflows/{workflow_id}: get: - operationId: getCloudWorkflow + operationId: getWorkflow tags: [workflows] summary: Get a cloud workflow by ID description: "[cloud-only] Returns the metadata for a cloud workflow." @@ -3319,8 +4196,20 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' patch: - operationId: updateCloudWorkflow + operationId: updateWorkflow tags: [workflows] summary: Update a cloud workflow description: "[cloud-only] Updates the metadata (name, description) of an existing cloud workflow." @@ -3369,8 +4258,20 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' delete: - operationId: deleteCloudWorkflow + operationId: deleteWorkflow tags: [workflows] summary: Delete a cloud workflow description: "[cloud-only] Deletes a cloud workflow and all its versions." @@ -3399,9 +4300,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workflows/{workflow_id}/content: get: - operationId: getCloudWorkflowContent + operationId: getWorkflowContent tags: [workflows] summary: Get the content of a cloud workflow description: "[cloud-only] Returns the full workflow graph JSON for the latest version of a cloud workflow." @@ -3440,6 +4347,18 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' put: operationId: updateCloudWorkflowContent tags: [workflows] @@ -3490,7 +4409,7 @@ paths: /api/workflows/{workflow_id}/fork: post: - operationId: forkCloudWorkflow + operationId: forkWorkflow tags: [workflows] summary: Fork a cloud workflow description: "[cloud-only] Creates a copy of a cloud workflow under the authenticated user's account." @@ -3533,6 +4452,24 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workflows/{workflow_id}/versions: get: operationId: listCloudWorkflowVersions @@ -3587,7 +4524,7 @@ paths: schema: $ref: "#/components/schemas/CloudError" post: - operationId: createCloudWorkflowVersion + operationId: createWorkflowVersion tags: [workflows] summary: Create a new cloud workflow version description: "[cloud-only] Creates a new workflow version with updated workflow JSON. Uses optimistic concurrency via base_version." @@ -3638,6 +4575,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workflows/published/{share_id}: get: operationId: getPublishedWorkflow @@ -3666,6 +4615,24 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '413': + description: Workflow JSON too large + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Auth / session (cloud) # --------------------------------------------------------------------------- @@ -3690,7 +4657,7 @@ paths: schema: $ref: "#/components/schemas/CloudError" post: - operationId: createAuthSession + operationId: createSession tags: [auth] summary: Create a session cookie description: "[cloud-only] Creates a session cookie from the bearer token in the Authorization header. Returns a Set-Cookie header with a secure HttpOnly session cookie. Cookie authentication is not allowed for this endpoint." @@ -3714,8 +4681,14 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' delete: - operationId: deleteAuthSession + operationId: deleteSession tags: [auth] summary: Delete session cookie (logout) description: "[cloud-only] Clears the session cookie and optionally revokes the session on the server." @@ -3728,9 +4701,15 @@ paths: schema: $ref: "#/components/schemas/DeleteSessionResponse" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/auth/token: post: - operationId: createAuthToken + operationId: exchangeToken tags: [auth] summary: Exchange credentials for an access token description: "[cloud-only] Exchanges authentication credentials (e.g. an authorization code) for an access token." @@ -3778,6 +4757,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Workspace not found or user not a member + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /.well-known/jwks.json: get: operationId: getJwks @@ -4106,9 +5097,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/events: get: - operationId: listBillingEvents + operationId: getBillingEvents tags: [billing] summary: List billing events description: "[cloud-only] Returns a paginated list of billing events (charges, credits, refunds) for the authenticated user." @@ -4143,9 +5140,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/ops/{id}: get: - operationId: getBillingOp + operationId: getBillingOpStatus tags: [billing] summary: Get a billing operation by ID description: "[cloud-only] Returns details of a specific billing operation." @@ -4177,9 +5180,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/payment-portal: post: - operationId: createPaymentPortalSession + operationId: getPaymentPortal tags: [billing] summary: Create a payment portal session description: "[cloud-only] Creates a Stripe customer portal session for managing payment methods and invoices. Returns a URL to redirect the user to." @@ -4203,9 +5212,21 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '400': + description: Bad request (e.g., missing return_url) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/plans: get: - operationId: listBillingPlans + operationId: getBillingPlans tags: [billing] summary: List available billing plans description: "[cloud-only] Returns the list of available subscription plans and their pricing." @@ -4220,9 +5241,21 @@ paths: items: $ref: "#/components/schemas/BillingPlan" + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/preview-subscribe: post: - operationId: previewSubscription + operationId: previewSubscribe tags: [billing] summary: Preview a subscription change description: "[cloud-only] Returns a preview of what a subscription change would cost, including prorations." @@ -4259,6 +5292,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/status: get: operationId: getBillingStatus @@ -4280,9 +5319,21 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Workspace not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/subscribe: post: - operationId: createSubscription + operationId: subscribe tags: [billing] summary: Subscribe to a billing plan description: "[cloud-only] Creates a new subscription to the specified billing plan." @@ -4322,6 +5373,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/subscription/cancel: post: operationId: cancelSubscription @@ -4343,6 +5400,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '400': + description: Invalid request (e.g., no active subscription) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/subscription/resubscribe: post: operationId: resubscribe @@ -4364,9 +5433,21 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '400': + description: Invalid request (e.g., no active subscription, not in cancellation grace period) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/billing/topup: post: - operationId: topUpCredits + operationId: createTopup tags: [billing] summary: Purchase additional credits description: "[cloud-only] Purchases a one-time credit top-up using the user's payment method on file." @@ -4403,12 +5484,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # Workspace (cloud) # --------------------------------------------------------------------------- /api/workspace/api-keys: get: - operationId: listWorkspaceApiKeys + operationId: listWorkspaceAPIKeys tags: [workspace] summary: List workspace API keys description: "[cloud-only] Returns the list of API keys for the current workspace." @@ -4434,8 +5521,14 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: - operationId: createWorkspaceApiKey + operationId: createWorkspaceAPIKey tags: [workspace] summary: Create a workspace API key description: "[cloud-only] Creates a new API key for the current workspace." @@ -4482,9 +5575,33 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Workspace not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '429': + description: Key limit reached + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspace/api-keys/{id}: delete: - operationId: deleteWorkspaceApiKey + operationId: revokeWorkspaceAPIKey tags: [workspace] summary: Delete a workspace API key description: "[cloud-only] Revokes and deletes a workspace API key." @@ -4518,6 +5635,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspace/invites: get: operationId: listWorkspaceInvites @@ -4546,6 +5669,12 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: operationId: createWorkspaceInvite tags: [workspace] @@ -4601,9 +5730,27 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Workspace not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspace/invites/{inviteId}: delete: - operationId: deleteWorkspaceInvite + operationId: revokeWorkspaceInvite tags: [workspace] summary: Cancel a workspace invite description: "[cloud-only] Cancels a pending workspace invitation." @@ -4637,6 +5784,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspace/leave: post: operationId: leaveWorkspace @@ -4660,6 +5813,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Workspace not found or not a member + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspace/members: get: operationId: listWorkspaceMembers @@ -4689,6 +5854,24 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Workspace not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspace/members/{user_id}/api-keys: get: operationId: listMemberApiKeys @@ -4731,7 +5914,7 @@ paths: schema: $ref: "#/components/schemas/CloudError" delete: - operationId: bulkRevokeMemberApiKeys + operationId: bulkRevokeWorkspaceMemberAPIKeys tags: [workspace] summary: Bulk revoke a member's API keys description: "[cloud-only] Revokes all active API keys for a specific workspace member. Only workspace owners can perform this action." @@ -4764,6 +5947,18 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '422': + description: Validation error (e.g. empty user_id) + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspace/members/{userId}: patch: operationId: updateWorkspaceMember @@ -4857,6 +6052,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspaces: get: operationId: listWorkspaces @@ -4879,6 +6080,18 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Feature not enabled for user + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: operationId: createWorkspace tags: [workspace] @@ -4917,6 +6130,24 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '404': + description: Feature not enabled for user + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/workspaces/{id}: get: operationId: getWorkspace @@ -4956,6 +6187,12 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' patch: operationId: updateWorkspace tags: [workspace] @@ -5010,6 +6247,18 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteWorkspace tags: [workspace] @@ -5045,6 +6294,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' # --------------------------------------------------------------------------- # User / settings / misc (cloud) # --------------------------------------------------------------------------- @@ -5101,6 +6356,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/files/mask-layers: get: operationId: getMaskLayers @@ -5199,9 +6460,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/invites/{token}/accept: post: - operationId: acceptInvite + operationId: acceptWorkspaceInvite tags: [workspace] summary: Accept a workspace invitation description: "[cloud-only] Accepts a workspace invitation using the invite token. The authenticated user is added to the workspace." @@ -5239,6 +6506,24 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Email does not match invite + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '409': + description: Already a member of this workspace + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/secrets: get: operationId: listSecrets @@ -5261,6 +6546,18 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '503': + description: Service unavailable - feature is disabled + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: operationId: createSecret tags: [settings] @@ -5303,6 +6600,30 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '409': + description: Conflict - secret with this name or provider already exists + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '422': + description: Validation error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '503': + description: Service unavailable - secrets feature disabled + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/secrets/{id}: get: operationId: getSecret @@ -5337,6 +6658,24 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Forbidden - user does not own this secret + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '503': + description: Service unavailable - secrets feature disabled + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' patch: operationId: updateSecret tags: [settings] @@ -5388,6 +6727,24 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Forbidden - user does not own this secret + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '503': + description: Service unavailable - secrets feature disabled + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' delete: operationId: deleteSecret tags: [settings] @@ -5417,9 +6774,27 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '403': + description: Forbidden - user does not own this secret + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '503': + description: Service unavailable - secrets feature disabled + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/user: get: - operationId: getCloudUser + operationId: getUser tags: [user] summary: Get the authenticated cloud user description: "[cloud-only] Returns the profile and account information for the currently authenticated user." @@ -5508,8 +6883,14 @@ paths: application/json: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' post: - operationId: publishUserdataFile + operationId: postUserdataFilePublish tags: [userdata] summary: Publish a userdata file to the cloud description: "[cloud-only] Makes a userdata file available via a public URL for sharing or embedding." @@ -5546,9 +6927,21 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/vhs/queryvideo: get: - operationId: queryVhsVideo + operationId: getVhsQueryVideo tags: [view] summary: Query VHS video metadata description: "[cloud-only] Returns metadata about a video file processed by the VHS (Video Helper Suite) integration." @@ -5592,6 +6985,15 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '400': + description: 'Missing required query parameter. Produced by the oapi-codegen + wrapper via echo.NewHTTPError, so the body shape matches Echo''s + default HTTPError serialization rather than ErrorResponse. + ' + content: + application/json: + schema: + $ref: '#/components/schemas/BindingErrorResponse' /api/vhs/viewaudio: get: operationId: viewVhsAudio @@ -5812,6 +7214,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' /api/tasks/{task_id}: get: operationId: getTask @@ -5847,6 +7255,12 @@ paths: schema: $ref: "#/components/schemas/CloudError" + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' components: parameters: ComfyUserHeader: @@ -8755,4 +10169,1213 @@ components: items: $ref: "#/components/schemas/TaskEntry" pagination: - $ref: "#/components/schemas/PaginationInfo" \ No newline at end of file + $ref: "#/components/schemas/PaginationInfo" + + # ===== Cloud-only schemas (Comfy-Org/cloud runtime, BE-1106) ===== + AssetDownloadResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Acknowledgement of an async asset download task; clients poll GET /api/tasks/{task_id} for status.' + required: + - task_id + - status + properties: + task_id: + type: string + format: uuid + description: Task ID for tracking download progress via GET /api/tasks/{task_id} + status: + type: string + enum: + - created + - running + - completed + - failed + description: Current task status + message: + type: string + description: Human-readable message + example: Download task created. Use task_id to track progress. + + AssetMetadataResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Metadata for a remotely hosted asset resolved by URL.' + required: + - content_length + properties: + content_length: + type: integer + format: int64 + description: Size of the asset in bytes (-1 if unknown) + example: 4294967296 + content_type: + type: string + description: MIME type of the asset + example: application/octet-stream + filename: + type: string + description: Suggested filename for the asset from source + example: realistic-vision-v5.safetensors + name: + type: string + description: Display name or title for the asset from source + example: Realistic Vision v5.0 + tags: + type: array + items: + type: string + description: Tags for categorization from source + example: + - models + - checkpoint + preview_image: + type: string + description: Preview image as base64-encoded data URL + example: data:image/jpeg;base64,/9j/4AAQSkZJRg... + validation: + description: Validation results for the file + allOf: + - $ref: '#/components/schemas/ValidationResult' + + BillingBalanceResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Current credit balance and usage details for a workspace.' + required: + - amount_micros + - currency + properties: + amount_micros: + type: number + format: double + description: The total remaining balance in microamount (1/1,000,000 of the currency unit) + prepaid_balance_micros: + type: number + format: double + description: The remaining balance from prepaid commits in microamount + cloud_credit_balance_micros: + type: number + format: double + description: The remaining balance from cloud credits in microamount + pending_charges_micros: + type: number + format: double + description: The total amount of pending/unbilled charges from draft invoices in microamount + effective_balance_micros: + type: number + format: double + description: The effective balance (total balance minus pending charges). Can be negative if pending charges exceed + the balance. + currency: + type: string + example: usd + description: Currency code + + BillingPlansResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] List of available billing plans for subscription.' + required: + - plans + properties: + current_plan_slug: + type: string + description: Current plan slug if subscribed + plans: + type: array + items: + $ref: '#/components/schemas/Plan' + + BillingStatusResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Current billing and subscription status for a workspace.' + required: + - is_active + - has_funds + properties: + is_active: + type: boolean + description: Whether the workspace has an active subscription + subscription_status: + type: string + enum: + - active + - ended + - canceled + description: Subscription activity status (scheduled subscriptions are not returned) + subscription_tier: + $ref: '#/components/schemas/SubscriptionTier' + subscription_duration: + $ref: '#/components/schemas/SubscriptionDuration' + plan_slug: + type: string + description: Plan identifier (e.g., standard-monthly, team-pro-annual) + billing_status: + $ref: '#/components/schemas/BillingStatus' + has_funds: + type: boolean + description: Whether the workspace has available credits + cancel_at: + type: string + format: date-time + description: When the subscription will become inactive (if canceled) + renewal_date: + type: string + format: date-time + description: When the current billing period ends and the next one begins + + GetUserDataResponseFull: + type: array + x-runtime: [cloud] + description: '[cloud-only] List of user data file entries (each with path, size, and modification time) returned when full_info=true.' + items: + $ref: '#/components/schemas/GetUserDataResponseFullFile' + + HistoryDetailEntry: + type: object + x-runtime: [cloud] + description: '[cloud-only] History entry with full prompt data' + properties: + prompt: + type: object + description: Full prompt execution data + properties: + priority: + type: number + format: double + description: Execution priority + prompt_id: + type: string + description: The prompt ID + prompt: + type: object + description: The workflow nodes + additionalProperties: true + extra_data: + type: object + description: Additional execution data + additionalProperties: true + outputs_to_execute: + type: array + items: + type: string + description: Output nodes to execute + outputs: + type: object + description: Output data from execution (generated images, files, etc.) + additionalProperties: true + status: + type: object + description: Execution status and timeline information + additionalProperties: true + meta: + type: object + description: Metadata about the execution and nodes + additionalProperties: true + + HistoryDetailResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Detailed execution history response for a specific prompt. + + Returns a dictionary with prompt_id as key and full history data as value. + + ' + additionalProperties: + $ref: '#/components/schemas/HistoryDetailEntry' + + HistoryResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Execution history response with history array. + + Returns an object with a "history" key containing an array of history entries. + + Each entry includes prompt_id as a property along with execution data. + + ' + required: + - history + properties: + history: + type: array + description: Array of history entries ordered by creation time (newest first) + items: + $ref: '#/components/schemas/HistoryEntry' + + HubLabelInfo: + type: object + x-runtime: [cloud] + description: '[cloud-only] Metadata for a single Hub label.' + required: + - name + - display_name + - type + properties: + name: + type: string + description: Slug identifier. + display_name: + type: string + description: Human-readable display name. + description: + type: string + description: Optional description of the label. + type: + type: string + enum: + - tag + - model + - custom_node + description: Label category. + + HubProfileSummary: + type: object + x-runtime: [cloud] + description: '[cloud-only] Abbreviated Hub profile used in workflow listings.' + required: + - username + properties: + username: + type: string + display_name: + type: string + avatar_url: + type: string + description: Public URL of the profile avatar image. + + HubWorkflowListResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Paginated list of Hub workflows matching search criteria.' + required: + - workflows + properties: + workflows: + type: array + items: + anyOf: + - $ref: '#/components/schemas/HubWorkflowSummary' + - $ref: '#/components/schemas/HubWorkflowDetail' + description: Array of HubWorkflowSummary (default) or HubWorkflowDetail (when detail=true). + next_cursor: + type: string + description: Cursor for the next page, empty if no more results. + + HubWorkflowStatus: + type: string + x-runtime: [cloud] + description: '[cloud-only] Public workflow status. NULL in the database is represented as pending in API responses.' + enum: + - pending + - approved + - rejected + - deprecated + + HubWorkflowSummary: + type: object + x-runtime: [cloud] + description: '[cloud-only] Abbreviated Hub workflow metadata used in search and listing results.' + required: + - share_id + - name + - profile + - status + properties: + share_id: + type: string + name: + type: string + status: + $ref: '#/components/schemas/HubWorkflowStatus' + description: + type: string + tags: + type: array + items: + $ref: '#/components/schemas/LabelRef' + models: + type: array + items: + $ref: '#/components/schemas/LabelRef' + custom_nodes: + type: array + items: + $ref: '#/components/schemas/LabelRef' + thumbnail_type: + type: string + enum: + - image + - video + - image_comparison + thumbnail_url: + type: string + thumbnail_comparison_url: + type: string + publish_time: + type: string + format: date-time + nullable: true + profile: + $ref: '#/components/schemas/HubProfileSummary' + metadata: + type: object + additionalProperties: true + tutorial_url: + type: string + sample_image_urls: + type: array + items: + type: string + + HubWorkflowTemplateEntry: + type: object + x-runtime: [cloud] + description: '[cloud-only] Entry in the curated workflow template gallery shown on the home page.' + required: + - name + - title + - status + properties: + name: + type: string + description: Slug identifier for the template + title: + type: string + status: + $ref: '#/components/schemas/HubWorkflowStatus' + description: + type: string + tags: + type: array + items: + type: string + models: + type: array + items: + type: string + requiresCustomNodes: + type: array + items: + type: string + thumbnailVariant: + type: string + mediaType: + type: string + mediaSubtype: + type: string + size: + type: integer + format: int64 + description: Workflow asset size in bytes. + vram: + type: integer + format: int64 + description: Approximate VRAM requirement in bytes. + usage: + type: integer + format: int64 + description: Usage count reported upstream. + searchRank: + type: integer + format: int64 + description: Search ranking score reported upstream. + isEssential: + type: boolean + description: Whether the template belongs to a module marked as essential. + openSource: + type: boolean + profile: + $ref: '#/components/schemas/HubProfileSummary' + tutorialUrl: + type: string + logos: + type: array + items: + type: object + additionalProperties: true + date: + type: string + description: Publication date in YYYY-MM-DD format + io: + type: object + properties: + inputs: + type: array + items: + type: object + additionalProperties: true + outputs: + type: array + items: + type: object + additionalProperties: true + includeOnDistributions: + type: array + items: + type: string + thumbnailUrl: + type: string + description: Public URL of the primary thumbnail + thumbnailComparisonUrl: + type: string + description: Public URL of the comparison thumbnail + shareId: + type: string + description: Share ID for linking to the hub workflow detail + extendedDescription: + type: string + description: AI-generated extended description of the workflow + metaDescription: + type: string + description: AI-generated SEO meta description (under 160 chars) + howToUse: + type: array + items: + type: string + description: AI-generated step-by-step usage instructions + suggestedUseCases: + type: array + items: + type: string + description: AI-generated suggested use cases + faqItems: + type: array + items: + type: object + required: + - question + - answer + properties: + question: + type: string + answer: + type: string + description: AI-generated FAQ items + contentTemplate: + type: string + description: Content template used for generation (tutorial, showcase, comparison, breakthrough) + + JobStatusResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Job status information' + properties: + id: + type: string + format: uuid + description: The job ID + status: + type: string + enum: + - waiting_to_dispatch + - pending + - in_progress + - completed + - error + - cancelled + description: Current job status + created_at: + type: string + format: date-time + description: When the job was created + updated_at: + type: string + format: date-time + description: When the job was last updated + last_state_update: + type: string + format: date-time + description: When the job status was last changed + assigned_inference: + type: string + nullable: true + description: The inference instance assigned to this job (if any) + error_message: + type: string + nullable: true + description: Error message if the job failed + required: + - id + - status + - created_at + - updated_at + + JobsListResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Paginated list of jobs for the authenticated user.' + required: + - jobs + - pagination + properties: + jobs: + type: array + description: Array of jobs ordered by specified sort field + items: + $ref: '#/components/schemas/JobEntry' + pagination: + $ref: '#/components/schemas/PaginationInfo' + + LabelRef: + type: object + x-runtime: [cloud] + description: '[cloud-only] Reference to a Hub label by ID.' + required: + - name + - display_name + properties: + name: + type: string + description: Slug identifier (e.g. "video-generation", "flux"). + display_name: + type: string + description: Human-readable display name (e.g. "Video Generation", "Flux"). + + LogsResponse: + type: array + x-runtime: [cloud] + description: '[cloud-only] System logs response' + items: + type: object + properties: + timestamp: + type: string + format: date-time + description: When the log entry was created + level: + type: string + enum: + - debug + - info + - warn + - error + description: Log level + message: + type: string + description: Log message + source: + type: string + description: Source of the log entry + metadata: + type: object + additionalProperties: true + description: Additional log metadata + + Member: + type: object + x-runtime: [cloud] + description: '[cloud-only] Workspace member with profile and role information.' + required: + - id + - name + - email + - role + - joined_at + properties: + id: + type: string + description: User ID + name: + type: string + description: User's display name + email: + type: string + format: email + description: User's email address + role: + type: string + enum: + - owner + - member + description: User's role in the workspace + joined_at: + type: string + format: date-time + description: When the user joined the workspace + + OAuthRegisterBadRequestResponse: + x-runtime: [cloud] + description: "[cloud-only] Union of the two 400 shapes /oauth/register can emit. `OAuthRegisterError` is the handler-shaped\ + \ RFC 7591 \xA73.2.2 error; `BindingErrorResponse` is the strict-server binding-layer error fired when the request body\ + \ fails OpenAPI-schema validation before the handler runs.\n" + oneOf: + - $ref: '#/components/schemas/OAuthRegisterError' + - $ref: '#/components/schemas/BindingErrorResponse' + + PendingInvite: + type: object + x-runtime: [cloud] + description: '[cloud-only] An outstanding workspace invitation that has not yet been accepted.' + required: + - id + - email + - invited_at + - expires_at + properties: + id: + type: string + description: Invite ID + email: + type: string + format: email + description: Email address of the invited user + token: + type: string + description: Invite token for constructing invite links. Empty for expired invites. + invited_at: + type: string + format: date-time + description: When the invite was created + expires_at: + type: string + format: date-time + description: When the invite expires + + Plan: + type: object + x-runtime: [cloud] + description: '[cloud-only] Billing plan details including pricing, limits, and features.' + required: + - slug + - tier + - duration + - price_cents + - credits_cents + - max_seats + - availability + - seat_summary + properties: + slug: + type: string + description: Plan identifier (e.g., "pro-monthly", "team-standard-annual") + example: pro-monthly + tier: + $ref: '#/components/schemas/SubscriptionTier' + duration: + $ref: '#/components/schemas/SubscriptionDuration' + price_cents: + type: integer + format: int64 + description: Per-member price in cents (base + one seat) + example: 10000 + credits_cents: + type: integer + format: int64 + description: Per-member credits in cents (base + one seat) + example: 10000 + max_seats: + type: integer + format: int64 + description: Maximum number of seats allowed for this plan + example: 20 + availability: + $ref: '#/components/schemas/PlanAvailability' + seat_summary: + $ref: '#/components/schemas/PlanSeatSummary' + + PlanAvailability: + type: object + x-runtime: [cloud] + description: '[cloud-only] Availability and eligibility information for a billing plan.' + required: + - available + properties: + available: + type: boolean + description: Whether the workspace can subscribe to this plan + reason: + $ref: '#/components/schemas/PlanAvailabilityReason' + + PlanAvailabilityReason: + type: string + x-runtime: [cloud] + enum: + - same_plan + - incompatible_transition + - requires_team + - requires_personal + - exceeds_max_seats + description: '[cloud-only] Reason why a plan is unavailable' + + PlanSeatSummary: + type: object + x-runtime: [cloud] + description: '[cloud-only] Summary of seat costs based on current workspace members' + required: + - seat_count + - total_cost_cents + - total_credits_cents + properties: + seat_count: + type: integer + description: Total number of seats (owner + members) that would be charged + example: 5 + total_cost_cents: + type: integer + format: int64 + description: Total cost for all seats in cents + example: 50000 + total_credits_cents: + type: integer + format: int64 + description: Total credits granted for all seats in cents + example: 50000 + + PreviewPlanInfo: + type: object + x-runtime: [cloud] + description: '[cloud-only] Plan information for preview display' + required: + - slug + - tier + - duration + - price_cents + - credits_cents + - seat_summary + properties: + slug: + type: string + description: Plan slug + example: team-pro-monthly + tier: + $ref: '#/components/schemas/SubscriptionTier' + duration: + $ref: '#/components/schemas/SubscriptionDuration' + price_cents: + type: integer + format: int64 + description: Per-seat price in cents + example: 10000 + credits_cents: + type: integer + format: int64 + description: Per-seat credits in cents + example: 10000 + seat_summary: + $ref: '#/components/schemas/PlanSeatSummary' + period_start: + type: string + format: date-time + description: Current billing period start (only for current_plan) + period_end: + type: string + format: date-time + description: Current billing period end (only for current_plan) + + PreviewSubscribeResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Itemized cost preview for a pending subscription change.' + required: + - allowed + - transition_type + - effective_at + - is_immediate + - cost_today_cents + - cost_next_period_cents + - credits_today_cents + - credits_next_period_cents + - new_plan + properties: + allowed: + type: boolean + description: Whether this subscription change is allowed + reason: + type: string + description: Reason why the change is not allowed (only present if allowed=false) + transition_type: + type: string + enum: + - new_subscription + - upgrade + - downgrade + - duration_change + description: Type of subscription transition + effective_at: + type: string + format: date-time + description: When the change takes effect + is_immediate: + type: boolean + description: Whether the change takes effect immediately (true) or at period end (false) + cost_today_cents: + type: integer + format: int64 + description: Amount to charge today in cents (0 for downgrades) + example: 5000 + cost_next_period_cents: + type: integer + format: int64 + description: Amount that will be charged at next billing period in cents + example: 10000 + credits_today_cents: + type: integer + format: int64 + description: Credits granted today in cents (prorated for mid-period upgrades) + example: 5000 + credits_next_period_cents: + type: integer + format: int64 + description: Credits that will be granted at next billing period in cents + example: 10000 + current_plan: + $ref: '#/components/schemas/PreviewPlanInfo' + new_plan: + $ref: '#/components/schemas/PreviewPlanInfo' + + PublishedWorkflowDetail: + type: object + x-runtime: [cloud] + description: '[cloud-only] Full detail of a publicly published workflow on the Hub.' + required: + - share_id + - workflow_id + - name + - listed + - workflow_json + - assets + properties: + share_id: + type: string + workflow_id: + type: string + name: + type: string + description: Human-readable workflow name. + listed: + type: boolean + publish_time: + type: string + format: date-time + nullable: true + workflow_json: + type: object + additionalProperties: true + description: The workflow JSON content at publish time. + assets: + type: array + description: Published assets with their library status for the caller. + items: + $ref: '#/components/schemas/AssetInfo' + + SecretResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] User secret metadata (the secret value itself is never returned after creation).' + required: + - id + - name + - created_at + - updated_at + properties: + id: + type: string + format: uuid + description: Unique identifier for the secret + name: + type: string + description: User-provided label for the secret + provider: + type: string + description: Provider identifier (e.g., huggingface, civitai) + last_used_at: + type: string + format: date-time + description: When the secret was last used for decryption + created_at: + type: string + format: date-time + description: When the secret was created + updated_at: + type: string + format: date-time + description: When the secret was last updated + + SubscriptionDuration: + type: string + x-runtime: [cloud] + enum: + - MONTHLY + - ANNUAL + description: '[cloud-only] Billing period (uppercase to match comfy-api)' + + SubscriptionTier: + type: string + x-runtime: [cloud] + enum: + - FREE + - STANDARD + - CREATOR + - PRO + - FOUNDERS_EDITION + description: '[cloud-only] Subscription tier (uppercase to match comfy-api)' + + UserDataResponseFull: + type: object + x-runtime: [cloud] + description: '[cloud-only] User data listing entry with file metadata (path, size, modification time).' + properties: + path: + type: string + size: + type: integer + modified: + type: integer + format: int64 + description: UNIX timestamp of the last modification in milliseconds. + + ValidationError: + type: object + x-runtime: [cloud] + description: '[cloud-only] Details of a single validation error encountered during asset operations.' + required: + - code + - message + - field + properties: + code: + type: string + description: Machine-readable error code + example: FORMAT_NOT_ALLOWED + message: + type: string + description: Human-readable error message + example: 'File format "PickleTensor" is not allowed. Allowed formats: [SafeTensor]' + field: + type: string + description: Field that failed validation + example: format + + ValidationResult: + type: object + x-runtime: [cloud] + description: '[cloud-only] Result of validating a set of asset operations.' + required: + - is_valid + properties: + is_valid: + type: boolean + description: Overall validation status (true if all checks passed) + example: true + errors: + type: array + items: + $ref: '#/components/schemas/ValidationError' + description: Blocking validation errors that prevent download + warnings: + type: array + items: + $ref: '#/components/schemas/ValidationError' + description: Non-blocking validation warnings (informational only) + + WorkflowForkedFrom: + type: object + x-runtime: [cloud] + description: '[cloud-only] Reference to the parent workflow from which this workflow was forked.' + properties: + workflow_id: + type: string + workflow_version_id: + type: string + + WorkflowResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Full workflow entity including metadata and version history.' + required: + - id + - latest_version + - created_by + - created_at + - updated_at + properties: + id: + type: string + name: + type: string + description: + type: string + default_view: + type: string + enum: + - workflow + - app + latest_version: + type: integer + forked_from: + $ref: '#/components/schemas/WorkflowForkedFrom' + created_by: + type: string + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + + WorkflowVersionContentResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Full workflow version including the serialized workflow JSON.' + required: + - id + - version + - workflow_json + - created_by + - created_at + properties: + id: + type: string + version: + type: integer + workflow_json: + type: object + additionalProperties: true + created_by: + type: string + created_at: + type: string + format: date-time + dependency_asset_ids: + type: array + items: + type: string + + WorkspaceAPIKeyInfo: + type: object + x-runtime: [cloud] + description: '[cloud-only] Metadata for a workspace-scoped API key (secret is never returned).' + required: + - id + - workspace_id + - user_id + - name + - description + - key_prefix + - created_at + properties: + id: + type: string + format: uuid + description: API key ID + workspace_id: + type: string + description: Workspace this key belongs to + user_id: + type: string + description: User who created this key + name: + type: string + description: User-provided label + description: + type: string + description: User-provided description of the key's purpose. Limit is byte-based (UTF-8 encoding); 5000 bytes equals + 5000 ASCII characters or fewer multi-byte characters. + maxLength: 5000 + key_prefix: + type: string + description: First 8 chars after prefix for display + expires_at: + type: string + format: date-time + description: When the key expires (if set) + last_used_at: + type: string + format: date-time + description: Last time the key was used + revoked_at: + type: string + format: date-time + description: When the key was revoked (if revoked) + created_at: + type: string + format: date-time + description: When the key was created + + WorkspaceSummary: + type: object + x-runtime: [cloud] + description: '[cloud-only] Abbreviated workspace metadata used in list responses.' + required: + - id + - name + - type + properties: + id: + type: string + example: w-a1b2c3d4-5678-90ab-cdef-1234567890ab + name: + type: string + example: My Team + type: + type: string + enum: + - personal + - team + + WorkspaceWithRole: + type: object + x-runtime: [cloud] + description: '[cloud-only] Workspace entity annotated with the requesting user''s role.' + required: + - id + - name + - type + - role + - created_at + - joined_at + properties: + id: + type: string + example: w-a1b2c3d4-5678-90ab-cdef-1234567890ab + name: + type: string + example: My Team + type: + type: string + enum: + - personal + - team + role: + type: string + enum: + - owner + - member + created_at: + type: string + format: date-time + description: When the workspace was created + joined_at: + type: string + format: date-time + description: When the user joined the workspace (same as created_at for the workspace creator) + subscription_tier: + $ref: '#/components/schemas/SubscriptionTier' + + BindingErrorResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Error shape returned when request binding or validation fails before the handler runs.' + required: + - message + properties: + message: + type: string + + ErrorResponse: + type: object + x-runtime: [cloud] + description: '[cloud-only] Standard error response from cloud endpoints with a machine-readable code and human-readable message.' + required: + - code + - message + properties: + code: + type: string + description: Machine-readable error code + message: + type: string + description: Human-readable error message