mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-08-12 04:43:45 +08:00
* 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.<Schema> 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.Op<StatusCode>JSONResponse 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).
11382 lines
345 KiB
YAML
11382 lines
345 KiB
YAML
openapi: 3.1.0
|
||
info:
|
||
title: ComfyUI API
|
||
description: |
|
||
API for ComfyUI - A powerful and modular stable diffusion GUI and backend.
|
||
|
||
This API allows you to interact with ComfyUI programmatically, including:
|
||
- Submitting and managing workflow executions
|
||
- Querying node/object information
|
||
- Uploading and viewing files
|
||
- Managing user settings and data
|
||
- Asset management (feature-gated)
|
||
|
||
## Dual-path routing
|
||
Every route registered via `self.routes` in the ComfyUI server is available at
|
||
both its bare path (e.g. `/prompt`) and an `/api`-prefixed path (e.g. `/api/prompt`).
|
||
This spec uses the `/api`-prefixed versions as canonical.
|
||
|
||
## Multi-user mode
|
||
When ComfyUI is started with `--multi-user`, the `Comfy-User` header identifies
|
||
the active user for settings, userdata, and history isolation. This is **not** a
|
||
security mechanism — it is an organisational convenience with no authentication
|
||
or authorisation behind it.
|
||
version: 1.0.0
|
||
license:
|
||
name: GNU General Public License v3.0
|
||
url: https://github.com/comfyanonymous/ComfyUI/blob/master/LICENSE
|
||
|
||
servers:
|
||
- url: /
|
||
description: Default ComfyUI server (typically http://127.0.0.1:8188)
|
||
|
||
tags:
|
||
- name: prompt
|
||
description: Workflow submission and prompt info
|
||
- name: queue
|
||
description: Queue inspection and management
|
||
- name: history
|
||
description: Execution history
|
||
- name: upload
|
||
description: File upload endpoints
|
||
- name: view
|
||
description: File viewing / download
|
||
- name: system
|
||
description: System stats and feature flags
|
||
- name: node
|
||
description: Node / object_info definitions
|
||
- name: model
|
||
description: Model folder and file listing
|
||
- name: user
|
||
description: User management (multi-user mode)
|
||
- name: userdata
|
||
description: Per-user file storage
|
||
- name: settings
|
||
description: Per-user settings
|
||
- name: extensions
|
||
description: Frontend extension JS files
|
||
- name: subgraph
|
||
description: Global subgraph blueprints
|
||
- name: internal
|
||
description: Internal / debug endpoints
|
||
- name: assets
|
||
description: Asset management (feature-gated behind enable-assets)
|
||
|
||
- name: auth
|
||
description: Authentication and session management (cloud-only)
|
||
- name: billing
|
||
description: Billing, subscriptions, and payment management (cloud-only)
|
||
- name: workspace
|
||
description: Workspace and team management (cloud-only)
|
||
- name: hub
|
||
description: "ComfyUI Hub: profiles, shared workflows, and labels (cloud-only)"
|
||
- name: workflows
|
||
description: Cloud workflow management and versioning (cloud-only)
|
||
- name: task
|
||
description: Background task management (cloud-only)
|
||
- name: runtime-only
|
||
description: Operations served exclusively by the cloud runtime with no local equivalent
|
||
|
||
paths:
|
||
# ---------------------------------------------------------------------------
|
||
# WebSocket
|
||
# ---------------------------------------------------------------------------
|
||
/ws:
|
||
get:
|
||
operationId: connectWebSocket
|
||
tags: [system]
|
||
summary: WebSocket connection for real-time updates
|
||
description: |
|
||
Upgrades to a WebSocket connection that streams execution progress,
|
||
node status, and output messages. The server sends an initial `status`
|
||
message with the session ID (SID) on connect.
|
||
|
||
## Message types (server → client)
|
||
The server sends JSON messages with a `type` field. See the
|
||
`x-websocket-messages` list below for the schema of each message type.
|
||
parameters:
|
||
- name: clientId
|
||
in: query
|
||
required: false
|
||
schema:
|
||
type: string
|
||
description: Client identifier. If omitted the server assigns one.
|
||
responses:
|
||
"101":
|
||
description: WebSocket upgrade successful
|
||
'401':
|
||
description: Unauthorized
|
||
x-websocket-messages:
|
||
- type: status
|
||
schema:
|
||
$ref: "#/components/schemas/StatusWsMessage"
|
||
- type: progress
|
||
schema:
|
||
$ref: "#/components/schemas/ProgressWsMessage"
|
||
- type: progress_text
|
||
schema:
|
||
$ref: "#/components/schemas/ProgressTextWsMessage"
|
||
- type: progress_state
|
||
schema:
|
||
$ref: "#/components/schemas/ProgressStateWsMessage"
|
||
- type: executing
|
||
schema:
|
||
$ref: "#/components/schemas/ExecutingWsMessage"
|
||
- type: executed
|
||
schema:
|
||
$ref: "#/components/schemas/ExecutedWsMessage"
|
||
- type: execution_start
|
||
schema:
|
||
$ref: "#/components/schemas/ExecutionStartWsMessage"
|
||
- type: execution_success
|
||
schema:
|
||
$ref: "#/components/schemas/ExecutionSuccessWsMessage"
|
||
- type: execution_cached
|
||
schema:
|
||
$ref: "#/components/schemas/ExecutionCachedWsMessage"
|
||
- type: execution_interrupted
|
||
schema:
|
||
$ref: "#/components/schemas/ExecutionInterruptedWsMessage"
|
||
- type: execution_error
|
||
schema:
|
||
$ref: "#/components/schemas/ExecutionErrorWsMessage"
|
||
- type: logs
|
||
schema:
|
||
$ref: "#/components/schemas/LogsWsMessage"
|
||
- type: notification
|
||
schema:
|
||
$ref: "#/components/schemas/NotificationWsMessage"
|
||
- type: feature_flags
|
||
schema:
|
||
$ref: "#/components/schemas/FeatureFlagsWsMessage"
|
||
- type: asset_download
|
||
schema:
|
||
$ref: "#/components/schemas/AssetDownloadWsMessage"
|
||
- type: asset_export
|
||
schema:
|
||
$ref: "#/components/schemas/AssetExportWsMessage"
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Prompt
|
||
# ---------------------------------------------------------------------------
|
||
/api/prompt:
|
||
get:
|
||
operationId: getPromptInfo
|
||
tags: [prompt]
|
||
summary: Get queue status
|
||
description: Returns how many items remain in the execution queue.
|
||
responses:
|
||
"200":
|
||
description: Queue info
|
||
content:
|
||
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]
|
||
summary: Submit a workflow for execution
|
||
description: Submits a workflow for execution. The server validates the graph, assigns a `prompt_id`, and enqueues it. Clients listen on `/ws` for execution progress and output messages.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PromptRequest"
|
||
responses:
|
||
"200":
|
||
description: Prompt accepted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PromptResponse"
|
||
"400":
|
||
description: Validation or node errors
|
||
content:
|
||
application/json:
|
||
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: 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.
|
||
responses:
|
||
"200":
|
||
description: Queue contents
|
||
content:
|
||
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]
|
||
summary: Clear or delete items from the queue
|
||
description: Mutates the execution queue. Supports clearing all queued prompts or deleting individual prompts by ID.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/QueueManageRequest"
|
||
responses:
|
||
"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: 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.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
prompt_id:
|
||
type: string
|
||
format: uuid
|
||
description: "If provided, only interrupts this specific running prompt. Otherwise interrupts all."
|
||
responses:
|
||
"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
|
||
tags: [queue]
|
||
summary: Free GPU memory and/or unload models
|
||
description: Frees GPU memory by unloading models and/or freeing the resident model cache, controlled by the request flags.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
unload_models:
|
||
type: boolean
|
||
description: Unload all models from VRAM/RAM
|
||
free_memory:
|
||
type: boolean
|
||
description: Run garbage collection and free cached memory
|
||
responses:
|
||
"200":
|
||
description: Memory freed
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Jobs
|
||
# ---------------------------------------------------------------------------
|
||
/api/jobs:
|
||
get:
|
||
operationId: listJobs
|
||
tags: [queue]
|
||
summary: List jobs with filtering and pagination
|
||
description: Returns a paginated list of completed prompt executions, newest first.
|
||
parameters:
|
||
- name: status
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by job status
|
||
- name: workflow_id
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by workflow ID
|
||
- name: sort_by
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Field to sort by
|
||
- name: sort_order
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [asc, desc]
|
||
description: Sort direction
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Maximum number of results (default is unlimited/None)
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 0
|
||
description: Pagination offset
|
||
responses:
|
||
"200":
|
||
description: Jobs list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
jobs:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/JobEntry"
|
||
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: 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.
|
||
parameters:
|
||
- name: job_id
|
||
in: path
|
||
description: The job (prompt) ID to fetch.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Job detail
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/JobDetailResponse"
|
||
"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: getPromptHistory
|
||
tags: [history]
|
||
summary: Get execution history
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** Superseded by `GET /api/jobs`, which returns the same
|
||
execution records in a paginated, filterable format. Planned for removal
|
||
no earlier than a future major release; sunset timeline TBD.
|
||
|
||
Returns a dictionary keyed by prompt_id. Each value is a HistoryEntry
|
||
containing prompt metadata, outputs, status, and node meta.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: max_items
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Maximum number of history entries to return
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Pagination offset (number of entries to skip)
|
||
responses:
|
||
"200":
|
||
description: History dictionary keyed by prompt_id
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
$ref: "#/components/schemas/HistoryEntry"
|
||
'404':
|
||
description: "Not Found \u2014 use /api/history_v2 instead"
|
||
post:
|
||
operationId: manageHistory
|
||
tags: [history]
|
||
summary: Clear or delete history entries
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** Superseded by the forthcoming job-management endpoints
|
||
under `/api/jobs`. Planned for removal no earlier than a future major
|
||
release; sunset timeline TBD.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HistoryManageRequest"
|
||
responses:
|
||
"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
|
||
tags: [history]
|
||
summary: Get history for a specific prompt
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** Superseded by `GET /api/jobs/{job_id}`, which returns
|
||
the same execution record. Planned for removal no earlier than a future
|
||
major release; sunset timeline TBD.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: prompt_id
|
||
in: path
|
||
description: The prompt ID to fetch history for.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Single-entry history dictionary. Returns an empty object `{}` if the prompt_id is not found.
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
$ref: "#/components/schemas/HistoryEntry"
|
||
|
||
'404':
|
||
description: "Not Found \u2014 use /api/jobs/{prompt_id} instead"
|
||
# ---------------------------------------------------------------------------
|
||
# Upload
|
||
# ---------------------------------------------------------------------------
|
||
/api/upload/image:
|
||
post:
|
||
operationId: uploadImage
|
||
tags: [upload]
|
||
summary: Upload an image file
|
||
description: Uploads an image file into one of the input/output/temp directories so it can be referenced by workflow nodes.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- image
|
||
properties:
|
||
image:
|
||
type: string
|
||
format: binary
|
||
description: Image file to upload
|
||
type:
|
||
type: string
|
||
enum: [input, temp, output]
|
||
default: input
|
||
description: Target directory type
|
||
overwrite:
|
||
type: string
|
||
description: 'Set to "true" to overwrite existing files'
|
||
subfolder:
|
||
type: string
|
||
description: Subfolder within the target directory
|
||
responses:
|
||
"200":
|
||
description: Upload result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/UploadResult"
|
||
"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
|
||
tags: [upload]
|
||
deprecated: true
|
||
summary: Upload a mask image (deprecated)
|
||
description: |
|
||
Deprecated. Clients should composite the mask onto the source image
|
||
client-side and upload the resulting image via POST /api/upload/image
|
||
instead. This endpoint will continue to function for older clients,
|
||
but will not receive new features.
|
||
|
||
Uploads a mask image associated with a previously-uploaded reference image.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- image
|
||
- original_ref
|
||
properties:
|
||
image:
|
||
type: string
|
||
format: binary
|
||
description: Mask image (alpha channel is used)
|
||
original_ref:
|
||
type: object
|
||
description: Reference to the original image file
|
||
required:
|
||
- filename
|
||
properties:
|
||
filename:
|
||
type: string
|
||
description: Filename of the original image
|
||
additionalProperties: true
|
||
type:
|
||
type: string
|
||
enum: [input, temp, output]
|
||
default: input
|
||
description: Target directory type
|
||
overwrite:
|
||
type: string
|
||
description: 'Set to "true" to overwrite existing files'
|
||
subfolder:
|
||
type: string
|
||
description: Subfolder within the target directory
|
||
responses:
|
||
"200":
|
||
description: Upload result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/UploadResult"
|
||
"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
|
||
# ---------------------------------------------------------------------------
|
||
/api/view:
|
||
get:
|
||
operationId: viewFile
|
||
tags: [view]
|
||
summary: View or download a file
|
||
description: Serves a file (image, audio, or video) from the input/output/temp directory identified by the query parameters.
|
||
parameters:
|
||
- name: filename
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Name of the file to view
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [input, output, temp]
|
||
default: output
|
||
description: Directory type
|
||
- name: subfolder
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Subfolder within the directory
|
||
- name: preview
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Preview format hint (e.g. "webp;90")
|
||
- name: channel
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [rgba, rgb, a]
|
||
description: Channel extraction mode
|
||
responses:
|
||
"200":
|
||
description: File content
|
||
content:
|
||
image/*:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
video/*:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
audio/*:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
application/octet-stream:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
"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
|
||
tags: [view]
|
||
summary: Get metadata for a file (e.g. safetensors header)
|
||
description: Returns embedded metadata parsed from a file in the given folder — for example, the header of a safetensors model.
|
||
parameters:
|
||
- name: folder_name
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Folder type (output, input, temp, etc.)
|
||
- name: filename
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Filename to read metadata from
|
||
responses:
|
||
"200":
|
||
description: File metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
"404":
|
||
description: File or metadata not found
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# System
|
||
# ---------------------------------------------------------------------------
|
||
/api/system_stats:
|
||
get:
|
||
operationId: getSystemStats
|
||
tags: [system]
|
||
summary: Get system statistics
|
||
description: Returns hardware, Python, VRAM, and runtime statistics for the running ComfyUI process.
|
||
responses:
|
||
"200":
|
||
description: System stats
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/SystemStatsResponse"
|
||
|
||
'401':
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/features:
|
||
get:
|
||
operationId: getFeatures
|
||
tags: [system]
|
||
summary: Get enabled feature flags
|
||
description: Returns a dictionary of feature flag names to their enabled state. Cloud deployments may include additional typed fields alongside the boolean flags.
|
||
responses:
|
||
"200":
|
||
description: Feature flags
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
type: boolean
|
||
properties:
|
||
max_upload_size:
|
||
type: integer
|
||
format: int64
|
||
minimum: 0
|
||
description: "Maximum file upload size in bytes."
|
||
free_tier_credits:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Credits available to free-tier users. Local ComfyUI returns null."
|
||
posthog_api_host:
|
||
type: string
|
||
format: uri
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] PostHog analytics proxy URL for frontend telemetry. Local ComfyUI returns null."
|
||
max_concurrent_jobs:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Maximum concurrent jobs the authenticated user can run. Local ComfyUI returns null."
|
||
workflow_templates_version:
|
||
type: string
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Version identifier for the workflow templates bundle. Local ComfyUI returns null."
|
||
workflow_templates_source:
|
||
type: string
|
||
nullable: true
|
||
enum: [dynamic_config_override, workflow_templates_version_json]
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] How the templates version was resolved. Local ComfyUI returns null."
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Node / Object Info
|
||
# ---------------------------------------------------------------------------
|
||
/api/object_info:
|
||
get:
|
||
operationId: getNodeInfo
|
||
tags: [node]
|
||
summary: Get all node definitions
|
||
description: |
|
||
Returns a dictionary of every registered node class, keyed by class name.
|
||
Each value is a NodeInfo object describing inputs, outputs, category, etc.
|
||
responses:
|
||
"200":
|
||
description: All node definitions
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
$ref: "#/components/schemas/NodeInfo"
|
||
|
||
/api/object_info/{node_class}:
|
||
get:
|
||
operationId: getObjectInfoByClass
|
||
tags: [node]
|
||
summary: Get a single node definition
|
||
description: Returns the `NodeInfo` definition for a single registered node class.
|
||
parameters:
|
||
- name: node_class
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Node class name (e.g. "KSampler")
|
||
responses:
|
||
"200":
|
||
description: Single node definition
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
$ref: "#/components/schemas/NodeInfo"
|
||
"404":
|
||
description: Node class not found
|
||
|
||
/api/embeddings:
|
||
get:
|
||
operationId: getEmbeddings
|
||
tags: [node]
|
||
summary: List available embedding names
|
||
description: Returns the list of text-encoder embeddings available on disk.
|
||
responses:
|
||
"200":
|
||
description: Embedding names
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Models
|
||
# ---------------------------------------------------------------------------
|
||
/api/models:
|
||
get:
|
||
operationId: getModelTypes
|
||
tags: [model]
|
||
summary: List model folder type names
|
||
description: Returns an array of model type names (e.g. checkpoints, loras, vae).
|
||
responses:
|
||
"200":
|
||
description: Model type names
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
'404':
|
||
description: "Not Found \u2014 use /api/experiment/models instead"
|
||
/api/models/{folder}:
|
||
get:
|
||
operationId: getModelsByFolder
|
||
tags: [model]
|
||
summary: List model filenames in a folder
|
||
description: Returns the names of model files in the given folder. This endpoint predates `/api/experiment/models/{folder}` and returns names only — prefer the experiment endpoint for new integrations.
|
||
parameters:
|
||
- name: folder
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Model folder type name
|
||
responses:
|
||
"200":
|
||
description: Model filenames
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
"404":
|
||
description: Unknown folder type
|
||
|
||
/api/experiment/models:
|
||
get:
|
||
operationId: getModelFolders
|
||
tags: [model]
|
||
summary: List model folders with paths
|
||
description: Returns an array of model folder objects with name and folder paths.
|
||
responses:
|
||
"200":
|
||
description: Model folders
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ModelFolder"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/experiment/models/{folder}:
|
||
get:
|
||
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.
|
||
parameters:
|
||
- name: folder
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Model folder type name
|
||
responses:
|
||
"200":
|
||
description: Model files with metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ModelFile"
|
||
"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
|
||
tags: [model]
|
||
summary: Get model preview image
|
||
description: Returns the preview image associated with a model file, if one exists alongside the model on disk.
|
||
parameters:
|
||
- name: folder
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Model folder type name
|
||
- name: path_index
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: integer
|
||
description: Path index within the folder
|
||
- name: filename
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Model filename
|
||
responses:
|
||
"200":
|
||
description: Preview image (WebP)
|
||
content:
|
||
image/webp:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
"404":
|
||
description: Preview not found
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
# ---------------------------------------------------------------------------
|
||
# Users
|
||
# ---------------------------------------------------------------------------
|
||
/api/users:
|
||
get:
|
||
operationId: getUsersInfo
|
||
tags: [user]
|
||
summary: Get user storage info
|
||
description: |
|
||
Returns user storage configuration. In single-user mode returns
|
||
`{"storage": "server", "migrated": true/false}`. In multi-user mode
|
||
returns `{"storage": "server", "users": {"user_id": "user_dir", ...}}`.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
responses:
|
||
"200":
|
||
description: User info
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
storage:
|
||
type: string
|
||
description: Storage backend type (always "server")
|
||
migrated:
|
||
type: boolean
|
||
description: Whether migration from browser storage is complete (single-user)
|
||
users:
|
||
type: object
|
||
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]
|
||
summary: Create a new user (multi-user mode)
|
||
description: Creates a new user entry. Only meaningful when ComfyUI is running in multi-user mode.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- username
|
||
properties:
|
||
username:
|
||
type: string
|
||
description: Username for the new user
|
||
responses:
|
||
"200":
|
||
description: Created user ID
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: string
|
||
description: The generated user_id
|
||
"400":
|
||
description: Username already exists or invalid
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Userdata
|
||
# ---------------------------------------------------------------------------
|
||
/api/userdata:
|
||
get:
|
||
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.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: dir
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Directory path relative to the user's data folder
|
||
- name: recurse
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Recurse into subdirectories
|
||
- name: full_info
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Return full file info objects instead of just names
|
||
- name: split
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Split paths into directory components
|
||
responses:
|
||
"200":
|
||
description: File listing
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ListUserdataResponse"
|
||
"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
|
||
tags: [userdata]
|
||
summary: List files in userdata (v2 format)
|
||
description: Lists files in the authenticated user's data directory using the v2 response shape, which always returns full objects.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: path
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Directory path relative to user data root
|
||
responses:
|
||
"200":
|
||
description: File listing with metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
path:
|
||
type: string
|
||
type:
|
||
type: string
|
||
enum: [file, directory]
|
||
size:
|
||
type: integer
|
||
modified:
|
||
type: number
|
||
description: Unix timestamp
|
||
|
||
'404':
|
||
description: "Not Found \u2014 use /api/userdata instead"
|
||
/api/userdata/{file}:
|
||
get:
|
||
operationId: getUserdataFile
|
||
tags: [userdata]
|
||
summary: Read a userdata file
|
||
description: Reads the contents of a file from the authenticated user's data directory.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: file
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: File path relative to user data directory
|
||
responses:
|
||
"200":
|
||
description: File content
|
||
content:
|
||
application/octet-stream:
|
||
schema:
|
||
type: string
|
||
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: postUserdataFile
|
||
tags: [userdata]
|
||
summary: Write or create a userdata file
|
||
description: Writes (creates or replaces) a file in the authenticated user's data directory.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: file
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: File path relative to user data directory
|
||
- name: overwrite
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Allow overwriting existing files
|
||
- name: full_info
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Return full file info in response
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/octet-stream:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
application/json:
|
||
schema: {}
|
||
responses:
|
||
"200":
|
||
description: File written
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$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]
|
||
summary: Delete a userdata file
|
||
description: Deletes a file from the authenticated user's data directory.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: file
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: File path relative to user data directory
|
||
responses:
|
||
"204":
|
||
description: File deleted
|
||
"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
|
||
tags: [userdata]
|
||
summary: Move or rename a userdata file
|
||
description: Renames or moves a file within the authenticated user's data directory.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: file
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Source file path
|
||
- name: dest
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Destination file path
|
||
- name: overwrite
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Allow overwriting at destination
|
||
- name: full_info
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Return full file info in response
|
||
responses:
|
||
"200":
|
||
description: File moved
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/UserDataResponse"
|
||
"404":
|
||
description: Source file not found
|
||
"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: getAllSettings
|
||
tags: [settings]
|
||
summary: Get all user settings
|
||
description: Returns all settings for the authenticated user.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
responses:
|
||
"200":
|
||
description: Settings object
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
'401':
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
post:
|
||
operationId: updateMultipleSettings
|
||
tags: [settings]
|
||
summary: Update user settings (partial merge)
|
||
description: Replaces the authenticated user's settings with the provided object.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Partial settings to merge
|
||
responses:
|
||
"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: getSettingById
|
||
tags: [settings]
|
||
summary: Get a single setting by key
|
||
description: Returns the value of a single setting, identified by key.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Setting key
|
||
responses:
|
||
"200":
|
||
description: Setting value (null if the setting does not exist)
|
||
content:
|
||
application/json:
|
||
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: updateSettingById
|
||
tags: [settings]
|
||
summary: Set a single setting value
|
||
description: Sets the value of a single setting, identified by key.
|
||
parameters:
|
||
- $ref: "#/components/parameters/ComfyUserHeader"
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Setting key
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
description: The setting value (any JSON type)
|
||
responses:
|
||
"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
|
||
# ---------------------------------------------------------------------------
|
||
/api/extensions:
|
||
get:
|
||
operationId: getExtensions
|
||
tags: [extensions]
|
||
summary: List frontend extension JS file paths
|
||
description: Returns the list of frontend extension JS URLs registered by custom nodes, to be loaded by the frontend on startup.
|
||
responses:
|
||
"200":
|
||
description: Array of JS file paths
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Relative path to extension JS file
|
||
|
||
/api/workflow_templates:
|
||
get:
|
||
operationId: getWorkflowTemplates
|
||
tags: [extensions]
|
||
summary: Get workflow template mappings
|
||
description: Returns a map of custom node names to their provided workflow template names.
|
||
responses:
|
||
"200":
|
||
description: Template mappings
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Map of node pack name to array of template names
|
||
|
||
/api/i18n:
|
||
get:
|
||
operationId: getI18n
|
||
tags: [extensions]
|
||
summary: Get internationalisation translation strings
|
||
description: Returns the URLs of translation files contributed by custom nodes, keyed by locale.
|
||
responses:
|
||
"200":
|
||
description: Translation map
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Nested map of locale to translation key-value pairs
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Subgraphs
|
||
# ---------------------------------------------------------------------------
|
||
/api/global_subgraphs:
|
||
get:
|
||
operationId: getGlobalSubgraphs
|
||
tags: [subgraph]
|
||
summary: List global subgraph blueprints
|
||
description: Returns a dictionary of subgraph IDs to their metadata.
|
||
responses:
|
||
"200":
|
||
description: Subgraph metadata dictionary
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
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
|
||
tags: [subgraph]
|
||
summary: Get a global subgraph with full data
|
||
description: Returns the blueprint for a globally-registered subgraph, used by the frontend to materialize the subgraph node.
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Subgraph identifier
|
||
responses:
|
||
"200":
|
||
description: Full subgraph data
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/GlobalSubgraphData"
|
||
"404":
|
||
description: Subgraph not found
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
# ---------------------------------------------------------------------------
|
||
# Node Replacements
|
||
# ---------------------------------------------------------------------------
|
||
/api/node_replacements:
|
||
get:
|
||
operationId: getNodeReplacements
|
||
tags: [node]
|
||
summary: Get node replacement mappings
|
||
description: |
|
||
Returns a dictionary mapping deprecated or replaced node class names
|
||
to their replacement node information.
|
||
responses:
|
||
"200":
|
||
description: Replacement mappings
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
# ---------------------------------------------------------------------------
|
||
# Internal (x-internal: true)
|
||
# ---------------------------------------------------------------------------
|
||
/internal/logs:
|
||
get:
|
||
operationId: getInternalLogs
|
||
tags: [internal]
|
||
summary: Get server logs as text
|
||
description: Returns structured ComfyUI log entries from the in-memory log buffer.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Log text
|
||
content:
|
||
text/plain:
|
||
schema:
|
||
type: string
|
||
|
||
/internal/logs/raw:
|
||
get:
|
||
operationId: getInternalLogsRaw
|
||
tags: [internal]
|
||
summary: Get raw structured log entries
|
||
description: Returns the raw ComfyUI log buffer as text, together with metadata about the current size limit.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Structured log data
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
entries:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
t:
|
||
type: number
|
||
description: Timestamp
|
||
m:
|
||
type: string
|
||
description: Message
|
||
size:
|
||
type: object
|
||
properties:
|
||
cols:
|
||
type: integer
|
||
rows:
|
||
type: integer
|
||
|
||
/internal/logs/subscribe:
|
||
patch:
|
||
operationId: subscribeToLogs
|
||
tags: [internal]
|
||
summary: Subscribe or unsubscribe a WebSocket client to log streaming
|
||
description: Subscribes or unsubscribes the current client from live log streaming over the WebSocket.
|
||
x-internal: true
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- clientId
|
||
- enabled
|
||
properties:
|
||
clientId:
|
||
type: string
|
||
description: WebSocket client ID
|
||
enabled:
|
||
type: boolean
|
||
description: Enable or disable log streaming for this client
|
||
responses:
|
||
"200":
|
||
description: Subscription updated
|
||
|
||
/internal/folder_paths:
|
||
get:
|
||
operationId: getInternalFolderPaths
|
||
tags: [internal]
|
||
summary: Get configured folder paths
|
||
description: Returns the filesystem paths ComfyUI is configured to load models and other assets from, keyed by folder type.
|
||
x-internal: true
|
||
responses:
|
||
"200":
|
||
description: Dictionary of folder type to paths
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
type: array
|
||
items:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Map of folder type name to list of [path, ...] entries
|
||
|
||
/internal/files/{directory_type}:
|
||
get:
|
||
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).
|
||
x-internal: true
|
||
parameters:
|
||
- name: directory_type
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Directory type (e.g. output, input, temp)
|
||
responses:
|
||
"200":
|
||
description: Array of filenames
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
'400':
|
||
description: Invalid directory type
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
# ---------------------------------------------------------------------------
|
||
# Assets (x-feature-gate: enable-assets)
|
||
# ---------------------------------------------------------------------------
|
||
/api/assets/hash/{hash}:
|
||
head:
|
||
operationId: checkAssetByHash
|
||
tags: [assets]
|
||
summary: Check if an asset with the given hash exists
|
||
description: Returns 204 if an asset with the given content hash already exists, 404 otherwise. Used by clients to deduplicate uploads before transferring bytes.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: hash
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: "Blake3 hash of the asset (e.g. blake3:abc123...)"
|
||
responses:
|
||
"200":
|
||
description: Asset exists
|
||
"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
|
||
tags: [assets]
|
||
summary: List assets with filtering and pagination
|
||
description: Returns a paginated list of assets, optionally filtered by tags, name, or other query parameters.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 50
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 0
|
||
- name: include_tags
|
||
in: query
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
style: form
|
||
explode: true
|
||
description: Tags that assets must have (AND logic)
|
||
- name: exclude_tags
|
||
in: query
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
style: form
|
||
explode: true
|
||
description: Tags that assets must not have
|
||
- name: name_contains
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter assets whose name contains this substring
|
||
- name: metadata_filter
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: JSON-encoded metadata key/value filter
|
||
- name: sort
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Field to sort by
|
||
- name: order
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [asc, desc]
|
||
description: Sort direction
|
||
- name: include_public
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Include workspace-public assets in addition to the caller's own."
|
||
- name: asset_hash
|
||
in: query
|
||
schema:
|
||
type: string
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Filter by exact content hash."
|
||
responses:
|
||
"200":
|
||
description: Asset list
|
||
content:
|
||
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: uploadAsset
|
||
tags: [assets]
|
||
summary: Upload a new asset
|
||
description: Uploads a new asset (binary content plus metadata) and registers it in the asset database.
|
||
x-feature-gate: enable-assets
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- file
|
||
properties:
|
||
file:
|
||
type: string
|
||
format: binary
|
||
description: Asset file to upload
|
||
name:
|
||
type: string
|
||
description: Display name for the asset
|
||
tags:
|
||
type: string
|
||
description: Comma-separated tags
|
||
user_metadata:
|
||
type: string
|
||
description: JSON-encoded user metadata
|
||
hash:
|
||
type: string
|
||
description: "Blake3 hash of the file content (e.g. blake3:abc123...)"
|
||
mime_type:
|
||
type: string
|
||
description: MIME type of the file (overrides auto-detected type)
|
||
preview_id:
|
||
type: string
|
||
format: uuid
|
||
description: ID of an existing asset to use as the preview image
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Client-supplied asset ID for idempotent creation. If an asset with this ID already exists, the existing asset is returned."
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] URL-based asset upload. Caller supplies a URL instead of a file body; the server fetches the content."
|
||
required:
|
||
- url
|
||
properties:
|
||
url:
|
||
type: string
|
||
format: uri
|
||
description: "[cloud-only] URL of the file to import as an asset"
|
||
name:
|
||
type: string
|
||
description: Display name for the asset
|
||
tags:
|
||
type: string
|
||
description: Comma-separated tags
|
||
user_metadata:
|
||
type: string
|
||
description: JSON-encoded user metadata
|
||
hash:
|
||
type: string
|
||
description: "Blake3 hash of the file content (e.g. blake3:abc123...)"
|
||
mime_type:
|
||
type: string
|
||
description: MIME type of the file (overrides auto-detected type)
|
||
preview_id:
|
||
type: string
|
||
format: uuid
|
||
description: ID of an existing asset to use as the preview image
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Client-supplied asset ID for idempotent creation. If an asset with this ID already exists, the existing asset is returned."
|
||
responses:
|
||
"201":
|
||
description: Asset created
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [assets]
|
||
summary: Create an asset reference from an existing hash
|
||
description: Registers a new asset that references existing content by hash, without re-uploading the bytes.
|
||
x-feature-gate: enable-assets
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- hash
|
||
- name
|
||
properties:
|
||
hash:
|
||
type: string
|
||
description: Blake3 hash of existing content
|
||
name:
|
||
type: string
|
||
description: Display name
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
user_metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
mime_type:
|
||
type: string
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] MIME type of the content, so the type is preserved without re-inspecting content. Ignored by local ComfyUI."
|
||
responses:
|
||
"201":
|
||
description: Asset created from hash
|
||
content:
|
||
application/json:
|
||
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: getAssetById
|
||
tags: [assets]
|
||
summary: Get asset metadata
|
||
description: Returns the metadata for a single asset.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
description: The asset ID.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Asset metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$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]
|
||
summary: Update asset metadata
|
||
description: Updates the mutable metadata of an asset (name, tags, etc.). Binary content is immutable.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
description: The asset ID.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: New display name for the asset
|
||
user_metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Custom user metadata to set
|
||
preview_id:
|
||
type: string
|
||
format: uuid
|
||
description: ID of the asset to use as the preview
|
||
mime_type:
|
||
type: string
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] MIME type override when auto-detection was wrong. Ignored by local ComfyUI."
|
||
responses:
|
||
"200":
|
||
description: Asset updated
|
||
content:
|
||
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]
|
||
summary: Delete an asset
|
||
description: Removes an asset entry. Depending on the server configuration, the underlying content may also be deleted.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
description: The asset ID.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
- name: delete_content
|
||
in: query
|
||
schema:
|
||
type: boolean
|
||
description: Also delete the underlying content file
|
||
responses:
|
||
"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
|
||
tags: [assets]
|
||
summary: Download asset file content
|
||
description: Returns the binary content of an asset. Supports range requests.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
description: The asset ID.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
responses:
|
||
"200":
|
||
description: Asset file content
|
||
content:
|
||
application/octet-stream:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
"404":
|
||
description: Asset not found
|
||
|
||
/api/assets/{id}/tags:
|
||
post:
|
||
operationId: addAssetTags
|
||
tags: [assets]
|
||
summary: Add tags to an asset
|
||
description: Adds one or more tags to an asset.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
description: The asset ID.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- tags
|
||
properties:
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Tags added
|
||
content:
|
||
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]
|
||
summary: Remove tags from an asset
|
||
description: Removes one or more tags from an asset.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
description: The asset ID.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- tags
|
||
properties:
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Tags removed
|
||
content:
|
||
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'
|
||
/api/tags:
|
||
get:
|
||
operationId: listTags
|
||
tags: [assets]
|
||
summary: List all known tags with counts
|
||
description: Returns the list of all tags known to the asset database, with counts.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
- name: search
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Search term for tag name
|
||
responses:
|
||
"200":
|
||
description: Tag list
|
||
content:
|
||
application/json:
|
||
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: 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.
|
||
x-feature-gate: enable-assets
|
||
parameters:
|
||
- name: include_tags
|
||
in: query
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
style: form
|
||
explode: true
|
||
description: Tags that assets must have (AND logic)
|
||
- name: exclude_tags
|
||
in: query
|
||
schema:
|
||
type: array
|
||
items:
|
||
type: string
|
||
style: form
|
||
explode: true
|
||
description: Tags that assets must not have
|
||
- name: name_contains
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter assets whose name contains this substring
|
||
- name: metadata_filter
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: JSON-encoded metadata key/value filter
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
- name: sort
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Field to sort by
|
||
- name: order
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [asc, desc]
|
||
description: Sort direction
|
||
responses:
|
||
"200":
|
||
description: Tag histogram
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [assets]
|
||
summary: Trigger asset scan/seed from filesystem
|
||
description: Starts a background job that scans the configured directories and registers any assets not yet present in the asset database.
|
||
x-feature-gate: enable-assets
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
roots:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Root folder paths to scan (if omitted, scans all)
|
||
responses:
|
||
"200":
|
||
description: Seed started
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
status:
|
||
type: string
|
||
|
||
/api/assets/seed/status:
|
||
get:
|
||
operationId: getAssetSeedStatus
|
||
tags: [assets]
|
||
summary: Get asset scan progress
|
||
description: Returns the progress and status of the most recently-started asset seed job.
|
||
x-feature-gate: enable-assets
|
||
responses:
|
||
"200":
|
||
description: Scan progress
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Scan progress details (files scanned, total, status, etc.)
|
||
|
||
/api/assets/seed/cancel:
|
||
post:
|
||
operationId: cancelAssetSeed
|
||
tags: [assets]
|
||
summary: Cancel an in-progress asset scan
|
||
description: Requests cancellation of the currently-running asset seed job.
|
||
x-feature-gate: enable-assets
|
||
responses:
|
||
"200":
|
||
description: Scan cancelled
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
status:
|
||
type: string
|
||
|
||
/api/assets/prune:
|
||
post:
|
||
operationId: pruneAssets
|
||
tags: [assets]
|
||
summary: Mark assets whose backing files no longer exist on disk
|
||
description: Starts a background job that removes asset entries whose underlying content no longer exists on disk.
|
||
x-feature-gate: enable-assets
|
||
responses:
|
||
"200":
|
||
description: Prune result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
status:
|
||
type: string
|
||
marked:
|
||
type: integer
|
||
description: Number of assets marked as missing
|
||
|
||
# ===========================================================================
|
||
# Cloud-runtime FE-facing operations
|
||
#
|
||
# These operations are served by the cloud runtime. The local runtime returns
|
||
# 404 for all of these paths. Each operation is tagged x-runtime: [cloud].
|
||
# ===========================================================================
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Jobs / prompts (cloud)
|
||
# ---------------------------------------------------------------------------
|
||
/api/jobs/{job_id}/cancel:
|
||
post:
|
||
operationId: cancelJob
|
||
tags: [queue]
|
||
summary: Cancel a running or pending job
|
||
description: "[cloud-only] Requests cancellation of a job. If the job is currently executing, execution is interrupted. If it is pending in the queue, it is removed."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: job_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The job ID to cancel.
|
||
responses:
|
||
"200":
|
||
description: Cancellation accepted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudJobStatus"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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: getJobStatus
|
||
tags: [queue]
|
||
summary: Get status of a cloud job
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** This endpoint is superseded by `GET /api/jobs/{job_id}`.
|
||
Clients should migrate; the endpoint is retained for backward
|
||
compatibility but will be removed in a future release.
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: job_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The job ID to check status for.
|
||
responses:
|
||
"200":
|
||
description: Job status
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudJobStatus"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [prompt]
|
||
summary: Get a cloud prompt by ID
|
||
description: "[cloud-only] Returns the full prompt record for a cloud-executed prompt, including the submitted workflow graph and execution metadata."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: prompt_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The prompt ID to fetch.
|
||
responses:
|
||
"200":
|
||
description: Cloud prompt detail
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudPrompt"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/history_v2:
|
||
get:
|
||
operationId: getHistory
|
||
tags: [history]
|
||
summary: Get paginated execution history (v2)
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** This endpoint is superseded by `GET /api/jobs`.
|
||
Clients should migrate; the endpoint is retained for backward
|
||
compatibility but will be removed in a future release.
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 20
|
||
description: Maximum number of results
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 0
|
||
description: Pagination offset
|
||
- name: status
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by execution status
|
||
responses:
|
||
"200":
|
||
description: History list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HistoryV2Response"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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: getHistoryForPrompt
|
||
tags: [history]
|
||
summary: Get v2 history for a specific prompt
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** This endpoint is superseded by `GET /api/jobs/{prompt_id}`.
|
||
Clients should migrate; the endpoint is retained for backward
|
||
compatibility but will be removed in a future release.
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: prompt_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The prompt ID to fetch history for.
|
||
responses:
|
||
"200":
|
||
description: History entry
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HistoryV2Entry"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/logs:
|
||
get:
|
||
operationId: getLogs
|
||
tags: [system]
|
||
summary: Get cloud execution logs
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** This endpoint returns a static placeholder response and
|
||
provides no real log data. It is retained only to avoid breaking clients
|
||
that still call it. Clients should remove their dependency; the endpoint
|
||
will be removed in a future release.
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: job_id
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter logs by job ID
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 100
|
||
description: Maximum number of log entries
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
default: 0
|
||
description: Pagination offset
|
||
responses:
|
||
"200":
|
||
description: Log entries
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudLogsResponse"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Assets extensions (cloud)
|
||
# ---------------------------------------------------------------------------
|
||
/api/assets/download:
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- assets
|
||
properties:
|
||
assets:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AssetDownloadRequest"
|
||
description: Assets to download
|
||
responses:
|
||
"202":
|
||
description: Download task accepted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- task_id
|
||
- status
|
||
properties:
|
||
task_id:
|
||
type: string
|
||
format: uuid
|
||
description: ID of the download task; use to poll status.
|
||
status:
|
||
type: string
|
||
enum: [created, running, completed, failed]
|
||
description: Current task status (typically `created` on initial creation).
|
||
message:
|
||
type: string
|
||
description: Human-readable task message.
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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: 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."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- asset_ids
|
||
properties:
|
||
asset_ids:
|
||
type: array
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
description: IDs of assets to export
|
||
export_name:
|
||
type: string
|
||
description: Name for the export archive
|
||
responses:
|
||
"202":
|
||
description: Export task accepted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- task_id
|
||
- status
|
||
properties:
|
||
task_id:
|
||
type: string
|
||
format: uuid
|
||
description: ID of the export task; use to poll status.
|
||
status:
|
||
type: string
|
||
enum: [created, running, completed, failed]
|
||
description: Current task status (typically `created` on initial creation).
|
||
message:
|
||
type: string
|
||
description: Human-readable task message.
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [assets]
|
||
summary: Download a completed asset export
|
||
description: "[cloud-only] Returns the archive file for a completed asset export."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: exportName
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Name of the export to download
|
||
responses:
|
||
"200":
|
||
description: Export archive file
|
||
content:
|
||
application/zip:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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: 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."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- prompt_id
|
||
properties:
|
||
prompt_id:
|
||
type: string
|
||
format: uuid
|
||
description: Prompt ID whose outputs should be registered as assets
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Tags to apply to the created assets
|
||
responses:
|
||
"200":
|
||
description: Assets created or referenced
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
assets:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/Asset"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/assets/import:
|
||
post:
|
||
operationId: importPublishedAssets
|
||
tags: [assets]
|
||
summary: "[cloud-only] Import published assets into the caller's library"
|
||
description: |
|
||
[cloud-only] Imports the specified published assets into the caller's asset library. New DB records reference the same storage objects; no file copying occurs. Assets the caller already owns (by hash) are deduplicated. The `id` field on each returned `AssetInfo` is the caller's newly-created private asset ID, not the published asset ID supplied in the request.
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ImportPublishedAssetsRequest"
|
||
responses:
|
||
"200":
|
||
description: Successfully imported assets
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ImportPublishedAssetsResponse"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/assets/remote-metadata:
|
||
get:
|
||
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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: url
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uri
|
||
description: URL to inspect
|
||
responses:
|
||
"200":
|
||
description: Remote metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/RemoteAssetMetadata"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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)
|
||
# ---------------------------------------------------------------------------
|
||
/api/experiment/nodes:
|
||
get:
|
||
operationId: getNodeInfoSchema
|
||
tags: [runtime-only]
|
||
summary: Get pre-rendered node info schema
|
||
description: "[cloud-only] Returns the static ComfyUI object_info schema, identical for every caller, rendered once at startup with empty model/user-file context. Served by a raw HTTP handler that writes pre-rendered bytes with ETag + Cache-Control validators for RFC 7232 conditional GETs."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: If-None-Match
|
||
in: header
|
||
required: false
|
||
schema:
|
||
type: string
|
||
description: Entity tag previously returned by this endpoint. When present and matching, the server returns 304 Not Modified.
|
||
responses:
|
||
"200":
|
||
description: Node info schema
|
||
headers:
|
||
ETag:
|
||
schema:
|
||
type: string
|
||
description: Entity tag for conditional request validation
|
||
Cache-Control:
|
||
schema:
|
||
type: string
|
||
description: Cache directives for the response
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties:
|
||
$ref: "#/components/schemas/NodeInfo"
|
||
"304":
|
||
description: Not Modified — returned when the client sends a matching If-None-Match header
|
||
post:
|
||
operationId: installCloudNode
|
||
tags: [node]
|
||
summary: Install a custom node package
|
||
description: "[cloud-only] Installs a custom node package in the cloud runtime by ID or repository URL."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- id
|
||
properties:
|
||
id:
|
||
type: string
|
||
description: Node package ID or repository URL
|
||
version:
|
||
type: string
|
||
description: Specific version to install
|
||
responses:
|
||
"200":
|
||
description: Node installed
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudNode"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/experiment/nodes/{id}:
|
||
get:
|
||
operationId: getNodeByID
|
||
tags: [runtime-only]
|
||
summary: Get a single node definition by ID
|
||
description: "[cloud-only] Returns one node's definition from the pre-indexed object_info schema. Served by a raw HTTP handler that writes pre-rendered bytes with ETag + Cache-Control validators for RFC 7232 conditional GETs."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Node class identifier
|
||
- name: If-None-Match
|
||
in: header
|
||
required: false
|
||
schema:
|
||
type: string
|
||
description: Entity tag previously returned by this endpoint. When present and matching, the server returns 304 Not Modified.
|
||
responses:
|
||
"200":
|
||
description: Single node definition
|
||
headers:
|
||
ETag:
|
||
schema:
|
||
type: string
|
||
description: Entity tag for conditional request validation
|
||
Cache-Control:
|
||
schema:
|
||
type: string
|
||
description: Cache directives for the response
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/NodeInfo"
|
||
"304":
|
||
description: Not Modified — returned when the client sends a matching If-None-Match header
|
||
"404":
|
||
description: Node not found
|
||
delete:
|
||
operationId: uninstallCloudNode
|
||
tags: [node]
|
||
summary: Uninstall a custom node package
|
||
description: "[cloud-only] Removes a custom node package from the cloud runtime."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Custom node package ID
|
||
responses:
|
||
"204":
|
||
description: Node uninstalled
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/hub/assets/upload-url:
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- filename
|
||
- content_type
|
||
properties:
|
||
filename:
|
||
type: string
|
||
description: Name of the file to upload
|
||
content_type:
|
||
type: string
|
||
description: MIME type of the file
|
||
size:
|
||
type: integer
|
||
format: int64
|
||
description: File size in bytes
|
||
responses:
|
||
"200":
|
||
description: Upload URL
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
upload_url:
|
||
type: string
|
||
format: uri
|
||
description: Pre-signed upload URL
|
||
asset_url:
|
||
type: string
|
||
format: uri
|
||
description: Public URL after upload completes
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [hub]
|
||
summary: List available hub labels
|
||
description: "[cloud-only] Returns the list of labels/categories available for tagging hub content."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Label list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
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
|
||
tags: [hub]
|
||
summary: List hub user profiles
|
||
description: "[cloud-only] Returns a paginated list of public hub user profiles."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Maximum number of results
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Pagination offset
|
||
- name: search
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Search by username or display name
|
||
responses:
|
||
"200":
|
||
description: Profile list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
profiles:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/HubProfile"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
post:
|
||
operationId: createHubProfile
|
||
tags: [hub]
|
||
summary: Create a Hub profile
|
||
description: "[cloud-only] Creates a hub profile for the specified workspace. Username is immutable after creation."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CreateHubProfileRequest"
|
||
responses:
|
||
"201":
|
||
description: Hub profile created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HubProfile"
|
||
"400":
|
||
description: Bad request (e.g. invalid username)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"409":
|
||
description: Username already taken or profile already exists
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [hub]
|
||
summary: Get a hub profile by username
|
||
description: "[cloud-only] Returns the public hub profile for the given username."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: username
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Hub username
|
||
responses:
|
||
"200":
|
||
description: Profile
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HubProfile"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/hub/profiles/check:
|
||
get:
|
||
operationId: checkHubUsername
|
||
tags: [hub]
|
||
summary: Check if a hub username is available
|
||
description: "[cloud-only] Returns whether the given username is available for registration."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: username
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Username to check
|
||
responses:
|
||
"200":
|
||
description: Availability result
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
available:
|
||
type: boolean
|
||
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
|
||
tags: [hub]
|
||
summary: Get the authenticated user's hub profile
|
||
description: "[cloud-only] Returns the hub profile of the currently authenticated user."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Profile
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HubProfile"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
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]
|
||
summary: Update the authenticated user's hub profile
|
||
description: "[cloud-only] Updates the hub profile of the currently authenticated user."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
username:
|
||
type: string
|
||
display_name:
|
||
type: string
|
||
bio:
|
||
type: string
|
||
avatar_url:
|
||
type: string
|
||
format: uri
|
||
links:
|
||
type: array
|
||
items:
|
||
type: string
|
||
format: uri
|
||
responses:
|
||
"200":
|
||
description: Updated profile
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HubProfile"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"409":
|
||
description: Conflict
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/hub/workflows:
|
||
get:
|
||
operationId: listHubWorkflows
|
||
tags: [hub]
|
||
summary: List published hub workflows
|
||
description: "[cloud-only] Returns a paginated list of publicly shared workflows on the hub."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Maximum number of results
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Pagination offset
|
||
- name: sort
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Sort field (e.g. created_at, likes)
|
||
- name: order
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [asc, desc]
|
||
description: Sort direction
|
||
- name: search
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Search by title or description
|
||
- name: labels
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by label IDs (comma-separated)
|
||
responses:
|
||
"200":
|
||
description: Hub workflow list
|
||
content:
|
||
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]
|
||
summary: Publish a workflow to the hub
|
||
description: "[cloud-only] Publishes a workflow to the hub with metadata, thumbnail, and sample images."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/PublishHubWorkflowRequest"
|
||
responses:
|
||
"200":
|
||
description: Workflow published to hub
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HubWorkflowDetail"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Workflow or profile not found
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [hub]
|
||
summary: Get a published hub workflow by share ID
|
||
description: "[cloud-only] Returns the full details of a published workflow on the hub."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: share_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Workflow share ID
|
||
responses:
|
||
"200":
|
||
description: Hub workflow
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/HubWorkflow"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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]
|
||
summary: Unpublish a workflow from the hub
|
||
description: "[cloud-only] Removes a workflow from the hub listing."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: share_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Workflow share ID
|
||
responses:
|
||
"204":
|
||
description: Successfully unpublished
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Workflow not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/hub/workflows/index:
|
||
get:
|
||
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."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Workflow index
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/HubWorkflowIndexEntry"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
# ---------------------------------------------------------------------------
|
||
# Workflows (cloud)
|
||
# ---------------------------------------------------------------------------
|
||
/api/workflows:
|
||
get:
|
||
operationId: listWorkflows
|
||
tags: [workflows]
|
||
summary: List cloud workflows
|
||
description: "[cloud-only] Returns a paginated list of the authenticated user's cloud workflows."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Maximum number of results
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Pagination offset
|
||
- name: sort
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Sort field
|
||
- name: order
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [asc, desc]
|
||
description: Sort direction
|
||
- name: search
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Search by workflow name
|
||
responses:
|
||
"200":
|
||
description: Workflow list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudWorkflowList"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- name
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Workflow name
|
||
description:
|
||
type: string
|
||
description: Workflow description
|
||
content:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Initial workflow graph JSON
|
||
responses:
|
||
"201":
|
||
description: Workflow created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudWorkflow"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
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'
|
||
/api/workflows/{workflow_id}:
|
||
get:
|
||
operationId: getWorkflow
|
||
tags: [workflows]
|
||
summary: Get a cloud workflow by ID
|
||
description: "[cloud-only] Returns the metadata for a cloud workflow."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID.
|
||
responses:
|
||
"200":
|
||
description: Workflow detail
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudWorkflow"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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: updateWorkflow
|
||
tags: [workflows]
|
||
summary: Update a cloud workflow
|
||
description: "[cloud-only] Updates the metadata (name, description) of an existing cloud workflow."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
responses:
|
||
"200":
|
||
description: Workflow updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudWorkflow"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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: deleteWorkflow
|
||
tags: [workflows]
|
||
summary: Delete a cloud workflow
|
||
description: "[cloud-only] Deletes a cloud workflow and all its versions."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID.
|
||
responses:
|
||
"204":
|
||
description: Workflow deleted
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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: 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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID.
|
||
- name: version_id
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Specific version ID to fetch
|
||
responses:
|
||
"200":
|
||
description: Workflow content
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
description: The full workflow graph JSON
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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]
|
||
summary: Update the content of a cloud workflow
|
||
description: "[cloud-only] Saves new workflow graph JSON as a new version of the cloud workflow."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
description: The workflow graph JSON to save
|
||
responses:
|
||
"200":
|
||
description: Content updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudWorkflowVersion"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/workflows/{workflow_id}/fork:
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID to fork.
|
||
requestBody:
|
||
required: false
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Name for the forked workflow (defaults to original name)
|
||
responses:
|
||
"201":
|
||
description: Forked workflow
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudWorkflow"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [workflows]
|
||
summary: List versions of a cloud workflow
|
||
description: "[cloud-only] Returns the version history of a cloud workflow."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID.
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Maximum number of results
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Pagination offset
|
||
responses:
|
||
"200":
|
||
description: Version list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
versions:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/CloudWorkflowVersion"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: workflow_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The workflow ID.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CreateWorkflowVersionRequest"
|
||
responses:
|
||
"201":
|
||
description: Version created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/WorkflowVersionResponse"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden — not the workflow owner
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"409":
|
||
description: Version conflict — base_version does not match latest
|
||
content:
|
||
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'
|
||
/api/workflows/published/{share_id}:
|
||
get:
|
||
operationId: getPublishedWorkflow
|
||
tags: [workflows]
|
||
summary: Get a published workflow by share ID
|
||
description: "[cloud-only] Returns a publicly published cloud workflow by its share identifier."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: share_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The workflow share ID.
|
||
responses:
|
||
"200":
|
||
description: Published workflow
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudWorkflow"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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)
|
||
# ---------------------------------------------------------------------------
|
||
/api/auth/session:
|
||
get:
|
||
operationId: getAuthSession
|
||
tags: [auth]
|
||
summary: Get the current authentication session
|
||
description: "[cloud-only] Returns the current session state for the authenticated user, including user identity and active workspace."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Session info
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AuthSession"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Session created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CreateSessionResponse"
|
||
"400":
|
||
description: Bad request — invalid or expired ID token
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
delete:
|
||
operationId: deleteSession
|
||
tags: [auth]
|
||
summary: Delete session cookie (logout)
|
||
description: "[cloud-only] Clears the session cookie and optionally revokes the session on the server."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Session deleted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/DeleteSessionResponse"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/auth/token:
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- grant_type
|
||
properties:
|
||
grant_type:
|
||
type: string
|
||
enum: [authorization_code, refresh_token]
|
||
description: OAuth2 grant type
|
||
code:
|
||
type: string
|
||
description: Authorization code (for authorization_code grant)
|
||
refresh_token:
|
||
type: string
|
||
description: Refresh token (for refresh_token grant)
|
||
redirect_uri:
|
||
type: string
|
||
format: uri
|
||
description: Redirect URI used in the authorization request
|
||
responses:
|
||
"200":
|
||
description: Token response
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/AuthTokenResponse"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [auth]
|
||
summary: Get JSON Web Key Set
|
||
description: "[cloud-only] Returns the JSON Web Key Set (JWKS) used to verify JWTs issued by the cloud authentication service."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: JWKS
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/JwksResponse"
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# OAuth 2.1 / RFC 7591 Dynamic Client Registration (cloud)
|
||
# ---------------------------------------------------------------------------
|
||
/.well-known/oauth-authorization-server:
|
||
get:
|
||
operationId: getOAuthAuthorizationServer
|
||
tags: [auth]
|
||
summary: "[cloud-only] OAuth 2.1 authorization-server metadata (RFC 8414)"
|
||
description: "[cloud-only] Public metadata document for OAuth 2.1 clients. Cached 5 minutes."
|
||
x-runtime: [cloud]
|
||
security: []
|
||
responses:
|
||
"200":
|
||
description: Authorization-server metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthAuthorizationServerMetadata"
|
||
"404":
|
||
description: OAuth disabled
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/.well-known/oauth-protected-resource:
|
||
get:
|
||
operationId: getOAuthProtectedResource
|
||
tags: [auth]
|
||
summary: "[cloud-only] OAuth 2.1 protected-resource metadata (RFC 9728)"
|
||
description: "[cloud-only] Public metadata describing the currently advertised protected resource. Cached 5 minutes."
|
||
x-runtime: [cloud]
|
||
security: []
|
||
responses:
|
||
"200":
|
||
description: Protected-resource metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthProtectedResourceMetadata"
|
||
"404":
|
||
description: OAuth disabled or no active resource configured
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/oauth/authorize:
|
||
get:
|
||
operationId: getOAuthAuthorize
|
||
tags: [auth]
|
||
summary: "[cloud-only] Begin or resume an OAuth 2.1 authorization request"
|
||
description: |
|
||
[cloud-only] Two modes:
|
||
- **Initial entry** (OAuth params present): validates client/redirect/resource/scopes, persists a server-side authorization-request row, and either redirects (no session / unverified email) to the configured frontend login URL carrying only the opaque `oauth_request_id`, or returns the JSON consent challenge for the frontend to render.
|
||
- **Resume** (`oauth_request_id` present): loads the server-side row, fails closed if expired/consumed/unknown, returns the JSON consent challenge. Browser-replayed OAuth params are intentionally ignored.
|
||
|
||
The frontend renders the consent UI from the JSON payload and POSTs the user's decision back to this endpoint.
|
||
x-runtime: [cloud]
|
||
security: []
|
||
parameters:
|
||
- { name: response_type, in: query, required: false, schema: { type: string } }
|
||
- { name: client_id, in: query, required: false, schema: { type: string } }
|
||
- { name: redirect_uri, in: query, required: false, schema: { type: string } }
|
||
- { name: scope, in: query, required: false, schema: { type: string } }
|
||
- name: state
|
||
in: query
|
||
required: false
|
||
schema: { type: string }
|
||
description: |
|
||
RFC 6749 §10.12 marks `state` as RECOMMENDED. Cloud hardening makes it REQUIRED on the initial-entry path (omitted only on the resume path where `oauth_request_id` is supplied instead). This parameter is `required: false` at the spec level only because the operation is dual-mode (initial entry vs. resume); the runtime rejects empty `state` on the initial-entry path with a stable `invalid_request` 400.
|
||
- { name: code_challenge, in: query, required: false, schema: { type: string } }
|
||
- { name: code_challenge_method, in: query, required: false, schema: { type: string } }
|
||
- { name: resource, in: query, required: false, schema: { type: string } }
|
||
- { name: oauth_request_id, in: query, required: false, schema: { type: string } }
|
||
responses:
|
||
"200":
|
||
description: Consent challenge payload (session present, email verified). Frontend renders the consent UI from this payload and POSTs back to /oauth/authorize.
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthConsentChallenge"
|
||
"302":
|
||
description: Redirect to login (no session / unverified email) or to registered redirect_uri (pre-validated client error)
|
||
headers:
|
||
Location:
|
||
schema:
|
||
type: string
|
||
"400":
|
||
description: Invalid authorize request (pre-redirect failure — unknown client, redirect mismatch, malformed params)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: OAuth disabled
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
post:
|
||
operationId: postOAuthAuthorize
|
||
tags: [auth]
|
||
summary: "[cloud-only] Submit OAuth consent decision"
|
||
description: |
|
||
[cloud-only] JSON-only consent submission. The handler verifies the per-row CSRF token, atomically marks the authorization request consumed (single-use covers both allow and deny paths), then returns the redirect URL the browser must navigate to. The URL contains either `code` + original `state` for allow, or the RFC 6749 §5.2 error and `state` for deny.
|
||
|
||
Workspace membership is re-checked at submission time. Consent is persisted keyed by `(user_id, client_id, resource_id, workspace_id)`; broadening the previously approved scope set requires a fresh consent flow.
|
||
x-runtime: [cloud]
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [oauth_request_id, csrf_token, decision, workspace_id]
|
||
properties:
|
||
oauth_request_id: { type: string, format: uuid }
|
||
csrf_token: { type: string }
|
||
decision: { type: string, enum: [allow, deny] }
|
||
workspace_id: { type: string }
|
||
responses:
|
||
"200":
|
||
description: Redirect URL for the frontend to navigate to (allow → with code+state; deny → with error+state)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthAuthorizeRedirectResponse"
|
||
"400":
|
||
description: Bad request (CSRF mismatch, expired/consumed request, inaccessible workspace)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Scope broadening on consent re-grant — fresh consent flow required
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: OAuth disabled
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/oauth/token:
|
||
post:
|
||
operationId: postOAuthToken
|
||
tags: [auth]
|
||
summary: "[cloud-only] Exchange authorization code or refresh token for a resource-bound access token"
|
||
description: |
|
||
[cloud-only] OAuth 2.1 token endpoint (RFC 6749 §3.2). Public clients only — `client_secret` is rejected.
|
||
|
||
Two grant types are supported:
|
||
- `authorization_code` — exchanges the code minted by `/oauth/authorize` (with PKCE verifier) for an access token + first refresh token. Single-use; reuse fails closed.
|
||
- `refresh_token` — rotates the refresh token. Old token immediately invalid; presenting an already-rotated token revokes the entire token family and emits a security metric.
|
||
|
||
Both grant types re-validate canonical user state, current workspace membership, and the resource's active flag at every mint. A code or refresh token bound to a deactivated resource fails closed.
|
||
|
||
Errors follow RFC 6749 §5.2. Logs never contain raw codes, refresh tokens, or minted tokens.
|
||
|
||
Per RFC 6749 §5.1, every 200 and 400 response carries `Cache-Control: no-store` and `Pragma: no-cache` so intermediaries cannot cache token-bearing or state-change-reason responses.
|
||
x-runtime: [cloud]
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/x-www-form-urlencoded:
|
||
schema:
|
||
type: object
|
||
required: [grant_type, client_id]
|
||
properties:
|
||
grant_type: { type: string, enum: [authorization_code, refresh_token] }
|
||
client_id: { type: string }
|
||
code: { type: string }
|
||
redirect_uri: { type: string }
|
||
code_verifier: { type: string }
|
||
refresh_token: { type: string }
|
||
scope: { type: string }
|
||
client_secret: { type: string }
|
||
responses:
|
||
"200":
|
||
description: New token pair
|
||
headers:
|
||
Cache-Control:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-store" per RFC 6749 §5.1'
|
||
Pragma:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-cache" per RFC 6749 §5.1'
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthTokenResponse"
|
||
"400":
|
||
description: RFC 6749 §5.2 error
|
||
headers:
|
||
Cache-Control:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-store" per RFC 6749 §5.1'
|
||
Pragma:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-cache" per RFC 6749 §5.1'
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthTokenError"
|
||
"404":
|
||
description: OAuth disabled
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/oauth/register:
|
||
post:
|
||
operationId: postOAuthRegister
|
||
tags: [auth]
|
||
summary: "[cloud-only] Dynamic Client Registration (RFC 7591)"
|
||
description: |
|
||
[cloud-only] Public, unauthenticated, insert-only RFC 7591 §3.1 client registration. Used by MCP-spec-compliant clients to self-register a public OAuth client without operator involvement.
|
||
|
||
Policy:
|
||
|
||
- Public clients only — `token_endpoint_auth_method` is forced to `none`. Confidential-client registration is out of scope this phase.
|
||
- Server-owned `resource_grants`. Caller-supplied `scope` or `resource_grants` is rejected as `invalid_client_metadata` (would be a privilege-escalation surface). Dynamic clients receive the same scopes the active resource publishes.
|
||
- Application-type-aware redirect URI policy. `application_type=native` accepts loopback (`127.0.0.1`, `::1`, `localhost`) and reverse-DNS-shaped custom schemes; `application_type=web` accepts HTTPS to hosts in an operator-controlled allowlist only. `application_type` is REQUIRED on the request — missing or empty rejects with `invalid_client_metadata`.
|
||
- Anti-impersonation: reserved client names are rejected from third parties via NFKC-folded compare.
|
||
- Generated `client_id` carries a stable prefix to distinguish dynamic from seeded clients in audit logs.
|
||
- Cache-Control: `no-store` on every 201 and 400 response (the response carries fresh credentials and rejection reasons).
|
||
x-runtime: [cloud]
|
||
security: []
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthRegisterRequest"
|
||
responses:
|
||
"201":
|
||
description: Registered. Body echoes the metadata RFC 7591 §3.2.1 requires.
|
||
headers:
|
||
Cache-Control:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-store"'
|
||
Pragma:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-cache"'
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthRegisterResponse"
|
||
"400":
|
||
description: RFC 7591 §3.2.2 invalid client metadata
|
||
headers:
|
||
Cache-Control:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-store"'
|
||
Pragma:
|
||
schema:
|
||
type: string
|
||
description: 'Always "no-cache"'
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/OAuthRegisterError"
|
||
"404":
|
||
description: OAuth disabled
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"503":
|
||
description: No active resource is configured — DCR cannot mint a usable client until an active resource row is seeded.
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# Billing (cloud)
|
||
# ---------------------------------------------------------------------------
|
||
/api/billing/balance:
|
||
get:
|
||
operationId: getBillingBalance
|
||
tags: [billing]
|
||
summary: Get current credit balance
|
||
description: "[cloud-only] Returns the authenticated user's current credit balance and usage summary."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Balance info
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingBalance"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/billing/events:
|
||
get:
|
||
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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Maximum number of results
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
description: Pagination offset
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by event type
|
||
responses:
|
||
"200":
|
||
description: Billing events
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingEventList"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/billing/ops/{id}:
|
||
get:
|
||
operationId: getBillingOpStatus
|
||
tags: [billing]
|
||
summary: Get a billing operation by ID
|
||
description: "[cloud-only] Returns details of a specific billing operation."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The billing operation ID.
|
||
responses:
|
||
"200":
|
||
description: Billing operation
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingOp"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/billing/payment-portal:
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Portal session
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
url:
|
||
type: string
|
||
format: uri
|
||
description: Stripe portal URL
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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: getBillingPlans
|
||
tags: [billing]
|
||
summary: List available billing plans
|
||
description: "[cloud-only] Returns the list of available subscription plans and their pricing."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Plan list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
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: previewSubscribe
|
||
tags: [billing]
|
||
summary: Preview a subscription change
|
||
description: "[cloud-only] Returns a preview of what a subscription change would cost, including prorations."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- plan_id
|
||
properties:
|
||
plan_id:
|
||
type: string
|
||
description: ID of the plan to preview
|
||
responses:
|
||
"200":
|
||
description: Subscription preview
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/SubscriptionPreview"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/billing/status:
|
||
get:
|
||
operationId: getBillingStatus
|
||
tags: [billing]
|
||
summary: Get billing status
|
||
description: "[cloud-only] Returns the authenticated user's current billing and subscription status."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Billing status
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingStatus"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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: subscribe
|
||
tags: [billing]
|
||
summary: Subscribe to a billing plan
|
||
description: "[cloud-only] Creates a new subscription to the specified billing plan."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- plan_id
|
||
properties:
|
||
plan_id:
|
||
type: string
|
||
description: ID of the plan to subscribe to
|
||
payment_method_id:
|
||
type: string
|
||
description: Stripe payment method ID
|
||
responses:
|
||
"200":
|
||
description: Subscription created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingSubscription"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [billing]
|
||
summary: Cancel the active subscription
|
||
description: "[cloud-only] Cancels the authenticated user's active subscription. The subscription remains active until the end of the current billing period."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Subscription cancelled
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingSubscription"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [billing]
|
||
summary: Resubscribe after cancellation
|
||
description: "[cloud-only] Reactivates a subscription that was previously cancelled but has not yet expired."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Subscription reactivated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingSubscription"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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: 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."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- amount
|
||
properties:
|
||
amount:
|
||
type: integer
|
||
description: Number of credits to purchase
|
||
responses:
|
||
"200":
|
||
description: Top-up successful
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BillingBalance"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [workspace]
|
||
summary: List workspace API keys
|
||
description: "[cloud-only] Returns the list of API keys for the current workspace."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: API key list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/WorkspaceApiKey"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
post:
|
||
operationId: createWorkspaceAPIKey
|
||
tags: [workspace]
|
||
summary: Create a workspace API key
|
||
description: "[cloud-only] Creates a new API key for the current workspace."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- name
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Display name for the API key
|
||
description:
|
||
type: string
|
||
description: User-provided description of the key's purpose
|
||
maxLength: 5000
|
||
responses:
|
||
"201":
|
||
description: API key created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/WorkspaceApiKeyCreated"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
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: revokeWorkspaceAPIKey
|
||
tags: [workspace]
|
||
summary: Delete a workspace API key
|
||
description: "[cloud-only] Revokes and deletes a workspace API key."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The API key ID.
|
||
responses:
|
||
"204":
|
||
description: API key deleted
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/workspace/invites:
|
||
get:
|
||
operationId: listWorkspaceInvites
|
||
tags: [workspace]
|
||
summary: List pending workspace invites
|
||
description: "[cloud-only] Returns the list of pending invitations for the current workspace."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Invite list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/WorkspaceInvite"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
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]
|
||
summary: Invite a user to the workspace
|
||
description: "[cloud-only] Creates an invitation for a user to join the current workspace."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- email
|
||
properties:
|
||
email:
|
||
type: string
|
||
format: email
|
||
description: Email address to invite
|
||
role:
|
||
type: string
|
||
enum: [admin, member]
|
||
description: Role to assign
|
||
responses:
|
||
"201":
|
||
description: Invite created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/WorkspaceInvite"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"409":
|
||
description: Conflict
|
||
content:
|
||
application/json:
|
||
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: revokeWorkspaceInvite
|
||
tags: [workspace]
|
||
summary: Cancel a workspace invite
|
||
description: "[cloud-only] Cancels a pending workspace invitation."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: inviteId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The invite ID.
|
||
responses:
|
||
"204":
|
||
description: Invite cancelled
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/workspace/leave:
|
||
post:
|
||
operationId: leaveWorkspace
|
||
tags: [workspace]
|
||
summary: Leave the current workspace
|
||
description: "[cloud-only] Removes the authenticated user from the current workspace."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"204":
|
||
description: Left workspace
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [workspace]
|
||
summary: List workspace members
|
||
description: "[cloud-only] Returns the list of members in the current workspace."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Member list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/WorkspaceMember"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [workspace]
|
||
summary: List API keys for a workspace member
|
||
description: "[cloud-only] Returns the API keys belonging to a specific workspace member. Requires admin role."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: user_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The member's user ID.
|
||
responses:
|
||
"200":
|
||
description: API key list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/WorkspaceApiKey"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
delete:
|
||
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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: user_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
minLength: 1
|
||
description: The member's user ID.
|
||
responses:
|
||
"200":
|
||
description: Keys revoked
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BulkRevokeAPIKeysResponse"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden — must be workspace owner
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [workspace]
|
||
summary: Update a workspace member's role
|
||
description: "[cloud-only] Updates the role of a workspace member. Requires admin role."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: userId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The member's user ID.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- role
|
||
properties:
|
||
role:
|
||
type: string
|
||
enum: [admin, member]
|
||
description: New role to assign
|
||
responses:
|
||
"200":
|
||
description: Member updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/WorkspaceMember"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
delete:
|
||
operationId: removeWorkspaceMember
|
||
tags: [workspace]
|
||
summary: Remove a member from the workspace
|
||
description: "[cloud-only] Removes a member from the current workspace. Requires admin role."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: userId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The member's user ID.
|
||
responses:
|
||
"204":
|
||
description: Member removed
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/workspaces:
|
||
get:
|
||
operationId: listWorkspaces
|
||
tags: [workspace]
|
||
summary: List workspaces the user belongs to
|
||
description: "[cloud-only] Returns the list of workspaces the authenticated user is a member of."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Workspace list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/Workspace"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
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]
|
||
summary: Create a new workspace
|
||
description: "[cloud-only] Creates a new workspace. The authenticated user becomes the owner."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- name
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Workspace name
|
||
responses:
|
||
"201":
|
||
description: Workspace created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/Workspace"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [workspace]
|
||
summary: Get a workspace by ID
|
||
description: "[cloud-only] Returns details of a workspace the user is a member of."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The workspace ID.
|
||
responses:
|
||
"200":
|
||
description: Workspace detail
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/Workspace"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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]
|
||
summary: Update workspace settings
|
||
description: "[cloud-only] Updates the name or settings of a workspace. Requires admin role."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The workspace ID.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: New workspace name
|
||
responses:
|
||
"200":
|
||
description: Workspace updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/Workspace"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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]
|
||
summary: Delete a workspace
|
||
description: "[cloud-only] Soft-deletes a workspace. Requires owner role. Personal workspaces cannot be deleted."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The workspace ID.
|
||
responses:
|
||
"204":
|
||
description: Workspace deleted
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"403":
|
||
description: Forbidden — must be workspace owner
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
# ---------------------------------------------------------------------------
|
||
# User / settings / misc (cloud)
|
||
# ---------------------------------------------------------------------------
|
||
/api/feedback:
|
||
post:
|
||
operationId: submitFeedback
|
||
tags: [user]
|
||
summary: Submit user feedback
|
||
description: "[cloud-only] Submits feedback from the user about their experience with the cloud runtime."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- message
|
||
properties:
|
||
message:
|
||
type: string
|
||
description: Feedback message
|
||
rating:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 5
|
||
description: Optional satisfaction rating
|
||
context:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Additional context metadata
|
||
responses:
|
||
"201":
|
||
description: Feedback submitted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
id:
|
||
type: string
|
||
status:
|
||
type: string
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [assets]
|
||
summary: Get related mask layer filenames
|
||
description: "[cloud-only] Given a mask file (any of the 4 layers), returns all related mask layer filenames. Used by the mask editor to load the paint, mask, and painted layers when reopening a previously edited mask."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: filename
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Hash filename of any mask layer file
|
||
responses:
|
||
"200":
|
||
description: Related mask layers
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
mask:
|
||
type: string
|
||
description: Filename of the mask layer
|
||
nullable: true
|
||
paint:
|
||
type: string
|
||
description: Filename of the paint strokes layer
|
||
nullable: true
|
||
painted:
|
||
type: string
|
||
description: Filename of the painted image layer
|
||
nullable: true
|
||
painted_masked:
|
||
type: string
|
||
description: Filename of the final composite layer
|
||
nullable: true
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: File not found or not a mask file
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/internal/cloud_analytics:
|
||
post:
|
||
operationId: postCloudAnalytics
|
||
tags: [internal]
|
||
summary: Post client analytics events
|
||
description: "[cloud-only] Receives analytics events from the frontend for processing by the cloud analytics pipeline."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- events
|
||
properties:
|
||
events:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required:
|
||
- event_name
|
||
properties:
|
||
event_name:
|
||
type: string
|
||
timestamp:
|
||
type: string
|
||
format: date-time
|
||
properties:
|
||
type: object
|
||
additionalProperties: true
|
||
responses:
|
||
"200":
|
||
description: Events accepted
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
/api/invites/{token}/accept:
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: token
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The invitation token.
|
||
responses:
|
||
"200":
|
||
description: Invite accepted
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/Workspace"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [settings]
|
||
summary: List user secrets
|
||
description: "[cloud-only] Returns the list of secrets (API keys for third-party services) stored for the authenticated user. Secret values are redacted."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: Secret list
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/SecretMeta"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
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]
|
||
summary: Create or update a secret
|
||
description: "[cloud-only] Stores a new secret or updates an existing one. Secrets are encrypted at rest."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required:
|
||
- name
|
||
- value
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Secret name (unique per user)
|
||
value:
|
||
type: string
|
||
description: Secret value
|
||
responses:
|
||
"201":
|
||
description: Secret created
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/SecretMeta"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [settings]
|
||
summary: Get secret metadata
|
||
description: "[cloud-only] Returns metadata for a specific secret. Does not return the plaintext secret value."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The secret ID.
|
||
responses:
|
||
"200":
|
||
description: Secret metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/SecretMeta"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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]
|
||
summary: Update a secret
|
||
description: "[cloud-only] Updates an existing secret's name and/or value. Both fields are optional; only provided fields are updated."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: The secret ID.
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/UpdateSecretRequest"
|
||
responses:
|
||
"200":
|
||
description: Secret updated
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/SecretMeta"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"409":
|
||
description: Conflict — a secret with this name already exists
|
||
content:
|
||
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]
|
||
summary: Delete a secret
|
||
description: "[cloud-only] Permanently deletes a stored secret."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: The secret ID.
|
||
responses:
|
||
"204":
|
||
description: Secret deleted
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
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'
|
||
/api/user:
|
||
get:
|
||
operationId: getUser
|
||
tags: [user]
|
||
summary: Get the authenticated cloud user
|
||
description: "[cloud-only] Returns the profile and account information for the currently authenticated user."
|
||
x-runtime: [cloud]
|
||
responses:
|
||
"200":
|
||
description: User profile
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudUser"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
put:
|
||
operationId: updateCloudUser
|
||
tags: [user]
|
||
summary: Update the authenticated cloud user profile
|
||
description: "[cloud-only] Updates the profile information for the currently authenticated user."
|
||
x-runtime: [cloud]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
display_name:
|
||
type: string
|
||
avatar_url:
|
||
type: string
|
||
format: uri
|
||
responses:
|
||
"200":
|
||
description: Updated profile
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudUser"
|
||
"400":
|
||
description: Bad request
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/userdata/{file}/publish:
|
||
get:
|
||
operationId: getUserdataFilePublish
|
||
tags: [userdata]
|
||
summary: Get publish info for a userdata file
|
||
description: "[cloud-only] Returns the publish status and share info for a userdata workflow file."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: file
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: File path relative to user data directory
|
||
responses:
|
||
"200":
|
||
description: Publish info (publish_time is null if never published)
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/WorkflowPublishInfo"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Workflow not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
post:
|
||
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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: file
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: File path relative to user data directory
|
||
responses:
|
||
"200":
|
||
description: Published file URL
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
url:
|
||
type: string
|
||
format: uri
|
||
description: Public URL of the published file
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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: 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."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: filename
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Video filename
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [input, output, temp]
|
||
description: Directory type
|
||
- name: subfolder
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Subfolder within the directory
|
||
responses:
|
||
"200":
|
||
description: Video metadata
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [view]
|
||
summary: View or download VHS audio
|
||
description: "[cloud-only] Returns audio content from a VHS-processed file."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: filename
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Audio filename
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [input, output, temp]
|
||
description: Directory type
|
||
- name: subfolder
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Subfolder within the directory
|
||
responses:
|
||
"200":
|
||
description: Audio content
|
||
content:
|
||
audio/*:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/vhs/viewvideo:
|
||
get:
|
||
operationId: viewVhsVideo
|
||
tags: [view]
|
||
summary: View or download VHS video
|
||
description: "[cloud-only] Returns video content from a VHS-processed file."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: filename
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Video filename
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [input, output, temp]
|
||
description: Directory type
|
||
- name: subfolder
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Subfolder within the directory
|
||
responses:
|
||
"200":
|
||
description: Video content
|
||
content:
|
||
video/*:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/viewvideo:
|
||
get:
|
||
operationId: viewVideo
|
||
tags: [view]
|
||
summary: View or download a video file
|
||
deprecated: true
|
||
description: |
|
||
**Deprecated.** This endpoint is an alias of `GET /api/view` added for
|
||
legacy history-queue video playback. Callers should use `/api/view`
|
||
directly; the endpoint is retained for backward compatibility but will
|
||
be removed in a future release.
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: filename
|
||
in: query
|
||
required: true
|
||
schema:
|
||
type: string
|
||
description: Video filename
|
||
- name: type
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [input, output, temp]
|
||
description: Directory type
|
||
- name: subfolder
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Subfolder within the directory
|
||
responses:
|
||
"200":
|
||
description: Video content
|
||
content:
|
||
video/*:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
/api/tasks:
|
||
get:
|
||
operationId: listTasks
|
||
tags: [task]
|
||
summary: List background tasks
|
||
description: "[cloud-only] Retrieve a paginated list of background tasks for the authenticated user. Supports filtering by task type, status, and creation time."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: task_name
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by task type name (exact match).
|
||
- name: idempotency_key
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by idempotency key (exact match).
|
||
- name: status
|
||
in: query
|
||
schema:
|
||
type: string
|
||
description: Filter by one or more statuses (comma-separated).
|
||
- name: created_after
|
||
in: query
|
||
schema:
|
||
type: string
|
||
format: date-time
|
||
description: Filter tasks created after this timestamp.
|
||
- name: created_before
|
||
in: query
|
||
schema:
|
||
type: string
|
||
format: date-time
|
||
description: Filter tasks created before this timestamp.
|
||
- name: sort_order
|
||
in: query
|
||
schema:
|
||
type: string
|
||
enum: [asc, desc]
|
||
default: desc
|
||
description: Sort direction by create_time.
|
||
- name: offset
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 0
|
||
default: 0
|
||
description: Pagination offset (0-based).
|
||
- name: limit
|
||
in: query
|
||
schema:
|
||
type: integer
|
||
minimum: 1
|
||
maximum: 100
|
||
default: 20
|
||
description: Maximum items per page (1-100).
|
||
responses:
|
||
"200":
|
||
description: Tasks retrieved
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/TasksListResponse"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"422":
|
||
description: Validation error
|
||
content:
|
||
application/json:
|
||
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
|
||
tags: [task]
|
||
summary: Get task details
|
||
description: "[cloud-only] Retrieve full details for a specific background task."
|
||
x-runtime: [cloud]
|
||
parameters:
|
||
- name: task_id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
description: Task identifier (UUID).
|
||
responses:
|
||
"200":
|
||
description: Task details
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/TaskResponse"
|
||
"401":
|
||
description: Unauthorized
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
"404":
|
||
description: Task not found
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CloudError"
|
||
|
||
'500':
|
||
description: Internal server error
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: '#/components/schemas/ErrorResponse'
|
||
components:
|
||
parameters:
|
||
ComfyUserHeader:
|
||
name: Comfy-User
|
||
in: header
|
||
required: false
|
||
schema:
|
||
type: string
|
||
description: |
|
||
Identifies the active user in multi-user mode. Used for settings,
|
||
userdata, and history isolation. This is not a security mechanism —
|
||
it is an organisational convenience with no authentication behind it.
|
||
|
||
schemas:
|
||
# -------------------------------------------------------------------
|
||
# Prompt
|
||
# -------------------------------------------------------------------
|
||
PromptRequest:
|
||
type: object
|
||
description: A workflow submission. Wraps the prompt graph plus optional client identifier and extra per-request data.
|
||
required:
|
||
- prompt
|
||
properties:
|
||
prompt:
|
||
type: object
|
||
description: |
|
||
The workflow graph to execute. Keys are node IDs (strings);
|
||
values are objects with class_type and inputs.
|
||
additionalProperties: true
|
||
number:
|
||
type: number
|
||
description: Priority number for the queue (lower numbers have higher priority)
|
||
front:
|
||
type: boolean
|
||
description: If true, adds the prompt to the front of the queue
|
||
extra_data:
|
||
type: object
|
||
description: Extra data associated with the prompt (e.g. extra_pnginfo)
|
||
additionalProperties: true
|
||
client_id:
|
||
type: string
|
||
description: WebSocket client ID to receive progress updates
|
||
prompt_id:
|
||
type: string
|
||
format: uuid
|
||
description: "Client-supplied prompt ID. Server generates a UUID if omitted."
|
||
partial_execution_targets:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: List of node IDs to execute (partial graph execution)
|
||
workflow_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Cloud workflow entity ID for tracking and gallery association. Ignored by local ComfyUI."
|
||
workflow_version_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Cloud workflow version ID for pinning execution to a specific version. Ignored by local ComfyUI."
|
||
|
||
PromptResponse:
|
||
type: object
|
||
description: Server acknowledgement of a workflow submission. Includes the assigned `prompt_id` and current queue position.
|
||
properties:
|
||
prompt_id:
|
||
type: string
|
||
format: uuid
|
||
description: Unique identifier for the prompt execution
|
||
number:
|
||
type: number
|
||
description: Priority number in the queue
|
||
node_errors:
|
||
type: object
|
||
description: Validation errors keyed by node ID
|
||
additionalProperties:
|
||
$ref: "#/components/schemas/NodeError"
|
||
error:
|
||
description: Top-level prompt error (string message or structured error)
|
||
oneOf:
|
||
- type: string
|
||
- $ref: "#/components/schemas/PromptError"
|
||
|
||
PromptErrorResponse:
|
||
type: object
|
||
description: Error response when prompt validation fails
|
||
additionalProperties: true
|
||
|
||
PromptError:
|
||
type: object
|
||
description: Structured prompt validation error
|
||
properties:
|
||
type:
|
||
type: string
|
||
message:
|
||
type: string
|
||
details:
|
||
type: string
|
||
|
||
Error:
|
||
type: object
|
||
description: Detailed node-level error
|
||
properties:
|
||
type:
|
||
type: string
|
||
message:
|
||
type: string
|
||
details:
|
||
type: string
|
||
extra_info:
|
||
type: object
|
||
properties:
|
||
input_name:
|
||
type: string
|
||
additionalProperties: true
|
||
|
||
NodeError:
|
||
type: object
|
||
description: Error details for a single node
|
||
properties:
|
||
errors:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/Error"
|
||
class_type:
|
||
type: string
|
||
description: The node's class type
|
||
dependent_outputs:
|
||
type: array
|
||
items: {}
|
||
|
||
PromptInfo:
|
||
type: object
|
||
description: Summary of a queued or recently-executed prompt, as returned by the queue and history endpoints.
|
||
properties:
|
||
exec_info:
|
||
type: object
|
||
properties:
|
||
queue_remaining:
|
||
type: integer
|
||
description: Number of items remaining in the queue
|
||
|
||
# -------------------------------------------------------------------
|
||
# Queue
|
||
# -------------------------------------------------------------------
|
||
QueueInfo:
|
||
type: object
|
||
description: Queue information with pending and running items
|
||
properties:
|
||
queue_running:
|
||
type: array
|
||
description: Currently running queue items
|
||
items:
|
||
type: array
|
||
description: |
|
||
Queue item tuple: [number, prompt_id, prompt, extra_data, outputs_to_execute, sensitive]
|
||
items: {}
|
||
prefixItems:
|
||
- type: number
|
||
description: Priority number
|
||
- type: string
|
||
format: uuid
|
||
description: prompt_id
|
||
- type: object
|
||
description: prompt graph
|
||
additionalProperties: true
|
||
- type: object
|
||
description: extra_data
|
||
additionalProperties: true
|
||
- type: array
|
||
description: outputs_to_execute (list of output node IDs)
|
||
items:
|
||
type: string
|
||
- type: object
|
||
description: sensitive data (may be omitted)
|
||
additionalProperties: true
|
||
queue_pending:
|
||
type: array
|
||
description: Pending queue items (oldest first)
|
||
items:
|
||
type: array
|
||
description: |
|
||
Queue item tuple: [number, prompt_id, prompt, extra_data, outputs_to_execute, sensitive]
|
||
items: {}
|
||
prefixItems:
|
||
- type: number
|
||
description: Priority number
|
||
- type: string
|
||
format: uuid
|
||
description: prompt_id
|
||
- type: object
|
||
description: prompt graph
|
||
additionalProperties: true
|
||
- type: object
|
||
description: extra_data
|
||
additionalProperties: true
|
||
- type: array
|
||
description: outputs_to_execute (list of output node IDs)
|
||
items:
|
||
type: string
|
||
- type: object
|
||
description: sensitive data (may be omitted)
|
||
additionalProperties: true
|
||
|
||
QueueManageRequest:
|
||
type: object
|
||
description: Request to clear or delete from queue
|
||
properties:
|
||
clear:
|
||
type: boolean
|
||
description: If true, clear all pending items
|
||
delete:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Array of prompt IDs to delete from queue
|
||
|
||
# -------------------------------------------------------------------
|
||
# History
|
||
# -------------------------------------------------------------------
|
||
HistoryEntry:
|
||
type: object
|
||
description: A single execution history entry
|
||
properties:
|
||
prompt:
|
||
type: array
|
||
description: |
|
||
Prompt tuple: [number, prompt_id, prompt_graph, extra_data, output_node_ids]
|
||
items: {}
|
||
outputs:
|
||
type: object
|
||
description: Output data from execution keyed by node ID
|
||
additionalProperties: true
|
||
status:
|
||
type: object
|
||
description: Execution status (status_str, completed, messages, etc.)
|
||
additionalProperties: true
|
||
meta:
|
||
type: object
|
||
description: Metadata about the execution and nodes
|
||
additionalProperties: true
|
||
|
||
HistoryManageRequest:
|
||
type: object
|
||
description: Request to clear or delete history entries
|
||
properties:
|
||
clear:
|
||
type: boolean
|
||
description: If true, clear all history
|
||
delete:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Array of prompt IDs to delete from history
|
||
|
||
# -------------------------------------------------------------------
|
||
# Jobs
|
||
# -------------------------------------------------------------------
|
||
JobEntry:
|
||
type: object
|
||
description: Lightweight job data for list views
|
||
required:
|
||
- id
|
||
- status
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
description: Unique job identifier (same as prompt_id)
|
||
status:
|
||
type: string
|
||
description: Current job status
|
||
create_time:
|
||
type: integer
|
||
format: int64
|
||
description: Job creation timestamp (Unix milliseconds).
|
||
execution_start_time:
|
||
type: integer
|
||
format: int64
|
||
description: Workflow execution start timestamp (Unix milliseconds, terminal states only).
|
||
execution_end_time:
|
||
type: integer
|
||
format: int64
|
||
description: Workflow execution end timestamp (Unix milliseconds, terminal states only).
|
||
preview_output:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Primary preview output
|
||
outputs_count:
|
||
type: integer
|
||
description: Total number of output files
|
||
|
||
JobDetailResponse:
|
||
type: object
|
||
description: Full job details including workflow and outputs
|
||
required:
|
||
- id
|
||
- status
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
status:
|
||
type: string
|
||
workflow:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Full ComfyUI workflow
|
||
outputs:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Full outputs object from execution
|
||
execution_error:
|
||
$ref: "#/components/schemas/ExecutionError"
|
||
create_time:
|
||
type: integer
|
||
format: int64
|
||
description: Job creation timestamp (Unix milliseconds).
|
||
update_time:
|
||
type: integer
|
||
format: int64
|
||
description: Last state-change timestamp (Unix milliseconds).
|
||
execution_start_time:
|
||
type: integer
|
||
format: int64
|
||
description: Workflow execution start timestamp (Unix milliseconds, terminal states only).
|
||
execution_end_time:
|
||
type: integer
|
||
format: int64
|
||
description: Workflow execution end timestamp (Unix milliseconds, terminal states only).
|
||
preview_output:
|
||
type: object
|
||
additionalProperties: true
|
||
outputs_count:
|
||
type: integer
|
||
execution_status:
|
||
type: object
|
||
additionalProperties: true
|
||
execution_meta:
|
||
type: object
|
||
additionalProperties: true
|
||
|
||
ExecutionError:
|
||
type: object
|
||
description: Detailed execution error from ComfyUI
|
||
properties:
|
||
node_id:
|
||
type: string
|
||
description: ID of the node that failed
|
||
node_type:
|
||
type: string
|
||
description: Type name of the node
|
||
exception_message:
|
||
type: string
|
||
description: Human-readable error message
|
||
exception_type:
|
||
type: string
|
||
description: Python exception type
|
||
traceback:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Traceback lines
|
||
current_inputs:
|
||
type: object
|
||
additionalProperties: true
|
||
current_outputs:
|
||
type: object
|
||
additionalProperties: true
|
||
|
||
PaginationInfo:
|
||
type: object
|
||
description: Pagination metadata returned alongside list responses.
|
||
properties:
|
||
offset:
|
||
type: integer
|
||
limit:
|
||
type: integer
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
# -------------------------------------------------------------------
|
||
# Upload / View
|
||
# -------------------------------------------------------------------
|
||
UploadResult:
|
||
type: object
|
||
description: Response body returned by the image/mask upload endpoints, describing where the uploaded file now lives.
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Saved filename (may be renamed to avoid collisions)
|
||
subfolder:
|
||
type: string
|
||
description: Subfolder the file was saved to
|
||
type:
|
||
type: string
|
||
description: Directory type (input, temp)
|
||
|
||
# -------------------------------------------------------------------
|
||
# System
|
||
# -------------------------------------------------------------------
|
||
DeviceStats:
|
||
type: object
|
||
description: GPU/compute device statistics
|
||
required:
|
||
- name
|
||
- type
|
||
- index
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Device name
|
||
type:
|
||
type: string
|
||
description: Device type (cuda, mps, cpu, etc.)
|
||
index:
|
||
type: number
|
||
nullable: true
|
||
description: |
|
||
Device index within its type (e.g. CUDA ordinal for `cuda:0`,
|
||
`cuda:1`). `null` for devices with no index, including the CPU
|
||
device returned in `--cpu` mode (PyTorch's `torch.device('cpu').index`
|
||
is `None`).
|
||
vram_total:
|
||
type: number
|
||
description: Total VRAM in bytes
|
||
vram_free:
|
||
type: number
|
||
description: Free VRAM in bytes
|
||
torch_vram_total:
|
||
type: number
|
||
description: Total PyTorch-managed VRAM in bytes
|
||
torch_vram_free:
|
||
type: number
|
||
description: Free PyTorch-managed VRAM in bytes
|
||
|
||
SystemStatsResponse:
|
||
type: object
|
||
description: Hardware, VRAM, Python, and ComfyUI version information for the running process.
|
||
required:
|
||
- system
|
||
- devices
|
||
properties:
|
||
system:
|
||
type: object
|
||
required:
|
||
- os
|
||
- python_version
|
||
- embedded_python
|
||
- comfyui_version
|
||
- pytorch_version
|
||
- argv
|
||
- ram_total
|
||
- ram_free
|
||
properties:
|
||
os:
|
||
type: string
|
||
description: Operating system
|
||
python_version:
|
||
type: string
|
||
description: Python version
|
||
embedded_python:
|
||
type: boolean
|
||
description: Whether using embedded Python
|
||
comfyui_version:
|
||
type: string
|
||
description: ComfyUI version string
|
||
pytorch_version:
|
||
type: string
|
||
description: PyTorch version
|
||
required_frontend_version:
|
||
type: string
|
||
description: Required frontend version
|
||
argv:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Command line arguments
|
||
ram_total:
|
||
type: number
|
||
description: Total RAM in bytes
|
||
ram_free:
|
||
type: number
|
||
description: Free RAM in bytes
|
||
installed_templates_version:
|
||
type: string
|
||
nullable: true
|
||
description: Version of the currently installed workflow templates
|
||
required_templates_version:
|
||
type: string
|
||
nullable: true
|
||
description: Minimum required workflow templates version for this ComfyUI build
|
||
comfy_package_versions:
|
||
type: array
|
||
description: Installed and required versions for every comfy* package pinned in requirements.txt
|
||
items:
|
||
type: object
|
||
required:
|
||
- name
|
||
- installed
|
||
- required
|
||
properties:
|
||
name:
|
||
type: string
|
||
installed:
|
||
type: string
|
||
nullable: true
|
||
required:
|
||
type: string
|
||
nullable: true
|
||
devices:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/DeviceStats"
|
||
|
||
# -------------------------------------------------------------------
|
||
# Node / Object Info
|
||
# -------------------------------------------------------------------
|
||
NodeInfo:
|
||
type: object
|
||
description: 'Definition of a registered node class: its inputs, outputs, category, and display metadata.'
|
||
properties:
|
||
input:
|
||
type: object
|
||
description: Input specifications (required and optional groups)
|
||
additionalProperties: true
|
||
input_order:
|
||
type: object
|
||
description: Ordered input names per group
|
||
additionalProperties:
|
||
type: array
|
||
items:
|
||
type: string
|
||
output:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Output type names
|
||
output_is_list:
|
||
type: array
|
||
items:
|
||
type: boolean
|
||
description: Whether each output is a list
|
||
output_name:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Display names of outputs
|
||
name:
|
||
type: string
|
||
description: Internal class name
|
||
display_name:
|
||
type: string
|
||
description: Human-readable display name
|
||
description:
|
||
type: string
|
||
description: Node description
|
||
python_module:
|
||
type: string
|
||
description: Python module implementing the node
|
||
category:
|
||
type: string
|
||
description: Node category path
|
||
output_node:
|
||
type: boolean
|
||
description: Whether this is an output node
|
||
output_tooltips:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Tooltips for each output
|
||
deprecated:
|
||
type: boolean
|
||
description: Whether the node is deprecated
|
||
experimental:
|
||
type: boolean
|
||
description: Whether the node is experimental
|
||
api_node:
|
||
type: boolean
|
||
description: Whether this is an API node
|
||
is_input_list:
|
||
type: boolean
|
||
description: Whether the node accepts list inputs
|
||
dev_only:
|
||
type: boolean
|
||
description: Whether the node is developer-only (hidden in production UI)
|
||
has_intermediate_output:
|
||
type: boolean
|
||
description: Whether the node emits intermediate output during execution
|
||
search_aliases:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Alternative search terms for finding this node
|
||
essentials_category:
|
||
type: string
|
||
nullable: true
|
||
description: |
|
||
Category override used by the essentials pack. The
|
||
`essentials_category` key may be present with a string value,
|
||
present and `null`, or absent entirely:
|
||
|
||
- V1 nodes: `essentials_category` is **omitted** when the node
|
||
class doesn't define an `ESSENTIALS_CATEGORY` attribute, and
|
||
**`null`** if the attribute is explicitly set to `None`.
|
||
- V3 nodes (`comfy_api.latest.io`): `essentials_category` is
|
||
**always present**, and **`null`** for nodes whose `Schema`
|
||
doesn't populate it.
|
||
|
||
# -------------------------------------------------------------------
|
||
# Models
|
||
# -------------------------------------------------------------------
|
||
ModelFolder:
|
||
type: object
|
||
description: A configured model folder and the list of disk paths it resolves to.
|
||
required:
|
||
- name
|
||
- folders
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Model folder type name (e.g. "checkpoints")
|
||
folders:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Filesystem paths for this model type
|
||
|
||
ModelFile:
|
||
type: object
|
||
description: A single model file in a folder, with filesystem metadata.
|
||
required:
|
||
- name
|
||
- pathIndex
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: Model filename
|
||
pathIndex:
|
||
type: integer
|
||
description: Index into the folder's paths array
|
||
modified:
|
||
type: number
|
||
description: File modification timestamp
|
||
created:
|
||
type: number
|
||
description: File creation timestamp
|
||
size:
|
||
type: integer
|
||
format: int64
|
||
description: File size in bytes
|
||
|
||
# -------------------------------------------------------------------
|
||
# Subgraphs
|
||
# -------------------------------------------------------------------
|
||
GlobalSubgraphInfo:
|
||
type: object
|
||
description: Metadata for a global subgraph blueprint (without full data)
|
||
required:
|
||
- source
|
||
- name
|
||
- info
|
||
properties:
|
||
source:
|
||
type: string
|
||
description: Source type ("templates" or "custom_node")
|
||
name:
|
||
type: string
|
||
description: Display name of the subgraph blueprint
|
||
info:
|
||
type: object
|
||
description: Additional information about the subgraph
|
||
required:
|
||
- node_pack
|
||
properties:
|
||
node_pack:
|
||
type: string
|
||
description: The node pack/module providing this subgraph
|
||
data:
|
||
type: string
|
||
description: The full subgraph JSON data (may be empty in list view)
|
||
|
||
GlobalSubgraphData:
|
||
type: object
|
||
description: Full data for a global subgraph blueprint
|
||
required:
|
||
- source
|
||
- name
|
||
- info
|
||
- data
|
||
properties:
|
||
source:
|
||
type: string
|
||
description: Source type ("templates" or "custom_node")
|
||
name:
|
||
type: string
|
||
description: Display name of the subgraph blueprint
|
||
info:
|
||
type: object
|
||
description: Additional information about the subgraph
|
||
required:
|
||
- node_pack
|
||
properties:
|
||
node_pack:
|
||
type: string
|
||
description: The node pack/module providing this subgraph
|
||
data:
|
||
type: string
|
||
description: The full subgraph JSON data as a string
|
||
|
||
# -------------------------------------------------------------------
|
||
# Userdata
|
||
# -------------------------------------------------------------------
|
||
UserDataResponse:
|
||
description: |
|
||
Response body for the POST endpoints `/api/userdata/{file}` and
|
||
`/api/userdata/{file}/move/{dest}`. Returns a single item whose
|
||
shape depends on the `full_info` query parameter.
|
||
x-variant-selector:
|
||
full_info=true: file-info object (`GetUserDataResponseFullFile`)
|
||
default: relative path string
|
||
oneOf:
|
||
- $ref: "#/components/schemas/GetUserDataResponseFullFile"
|
||
- type: string
|
||
description: Relative path of the written or moved file. Returned when `full_info` is absent or false.
|
||
|
||
ListUserdataResponse:
|
||
description: |
|
||
Response body for `GET /api/userdata`. The array item shape is
|
||
determined by the `full_info` and `split` query parameters.
|
||
x-variant-selector:
|
||
full_info=true: array of file-info objects (`GetUserDataResponseFullFile`)
|
||
split=true: array of `[relative_path, ...path_components]` arrays
|
||
default: array of relative path strings
|
||
oneOf:
|
||
- type: array
|
||
items:
|
||
$ref: "#/components/schemas/GetUserDataResponseFullFile"
|
||
description: Returned when `full_info=true`.
|
||
- type: array
|
||
items:
|
||
type: array
|
||
items:
|
||
type: string
|
||
minItems: 2
|
||
description: |
|
||
Returned when `split=true` and `full_info=false`. Each inner
|
||
array is `[relative_path, ...path_components]`.
|
||
- type: array
|
||
items:
|
||
type: string
|
||
description: Default shape — array of file paths relative to the user data root.
|
||
|
||
GetUserDataResponseFullFile:
|
||
type: object
|
||
description: A single entry in a full-info user data listing.
|
||
properties:
|
||
path:
|
||
type: string
|
||
description: File name or path relative to the user directory
|
||
created:
|
||
type: number
|
||
description: Unix timestamp of file creation
|
||
size:
|
||
type: integer
|
||
description: File size in bytes
|
||
modified:
|
||
type: integer
|
||
format: int64
|
||
description: Unix timestamp of last modification in milliseconds
|
||
|
||
# -------------------------------------------------------------------
|
||
# Assets
|
||
# -------------------------------------------------------------------
|
||
Asset:
|
||
type: object
|
||
description: A registered asset — an input/output file tracked in the asset database with content hash and metadata.
|
||
required:
|
||
- id
|
||
- name
|
||
- size
|
||
- created_at
|
||
- updated_at
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
description: Unique identifier for the asset
|
||
name:
|
||
type: string
|
||
description: Name of the asset file
|
||
hash:
|
||
type: string
|
||
nullable: true
|
||
description: Blake3 content hash of the asset (preferred over asset_hash)
|
||
pattern: "^blake3:[a-f0-9]{64}$"
|
||
asset_hash:
|
||
type: string
|
||
nullable: true
|
||
deprecated: true
|
||
description: "Deprecated: use `hash` instead. Blake3 hash of the asset content."
|
||
pattern: "^blake3:[a-f0-9]{64}$"
|
||
size:
|
||
type: integer
|
||
format: int64
|
||
description: Size of the asset in bytes
|
||
mime_type:
|
||
type: string
|
||
description: MIME type of the asset
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Tags associated with the asset
|
||
user_metadata:
|
||
type: object
|
||
description: Custom user metadata
|
||
additionalProperties: true
|
||
metadata:
|
||
type: object
|
||
description: System-managed metadata (read-only)
|
||
additionalProperties: true
|
||
readOnly: true
|
||
preview_url:
|
||
type: string
|
||
format: uri
|
||
description: URL for asset preview/thumbnail
|
||
preview_id:
|
||
type: string
|
||
format: uuid
|
||
description: ID of the preview asset if available
|
||
prompt_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
deprecated: true
|
||
description: "Deprecated: use job_id instead. ID of the prompt that created this asset."
|
||
job_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
description: ID of the job that created this asset
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
last_access_time:
|
||
type: string
|
||
format: date-time
|
||
is_immutable:
|
||
type: boolean
|
||
description: Whether this asset is immutable
|
||
|
||
AssetCreated:
|
||
description: Response body returned after successfully registering a new asset.
|
||
allOf:
|
||
- $ref: "#/components/schemas/Asset"
|
||
- type: object
|
||
required:
|
||
- created_new
|
||
properties:
|
||
created_new:
|
||
type: boolean
|
||
description: Whether this was a new creation (true) or returned existing (false)
|
||
|
||
AssetUpdated:
|
||
type: object
|
||
description: Response body returned after updating an asset's metadata.
|
||
required:
|
||
- id
|
||
- updated_at
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
name:
|
||
type: string
|
||
hash:
|
||
type: string
|
||
nullable: true
|
||
description: Blake3 content hash of the asset (preferred over asset_hash)
|
||
pattern: "^blake3:[a-f0-9]{64}$"
|
||
asset_hash:
|
||
type: string
|
||
nullable: true
|
||
deprecated: true
|
||
description: "Deprecated: use `hash` instead. Blake3 hash of the asset content."
|
||
pattern: "^blake3:[a-f0-9]{64}$"
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
mime_type:
|
||
type: string
|
||
user_metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
prompt_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
deprecated: true
|
||
description: "Deprecated: use job_id instead. ID of the prompt that created this asset."
|
||
job_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
description: ID of the job that created this asset
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
ListAssetsResponse:
|
||
type: object
|
||
description: Paginated list of assets.
|
||
required:
|
||
- assets
|
||
- total
|
||
- has_more
|
||
properties:
|
||
assets:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/Asset"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
TagInfo:
|
||
type: object
|
||
description: A tag known to the asset database, with the number of assets bearing it.
|
||
required:
|
||
- name
|
||
- count
|
||
properties:
|
||
name:
|
||
type: string
|
||
count:
|
||
type: integer
|
||
|
||
ListTagsResponse:
|
||
type: object
|
||
description: Flat list of all tags, with counts.
|
||
required:
|
||
- tags
|
||
- total
|
||
- has_more
|
||
properties:
|
||
tags:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/TagInfo"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
AssetTagHistogramResponse:
|
||
type: object
|
||
description: Tags that would refine a filtered asset query, with the count of assets each tag would additionally select.
|
||
required:
|
||
- tag_counts
|
||
properties:
|
||
tag_counts:
|
||
type: object
|
||
additionalProperties:
|
||
type: integer
|
||
description: Map of tag names to occurrence counts
|
||
|
||
TagsModificationResponse:
|
||
type: object
|
||
description: Response body returned after adding or removing tags on an asset.
|
||
required:
|
||
- total_tags
|
||
properties:
|
||
added:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Tags successfully added
|
||
removed:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Tags successfully removed
|
||
already_present:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Tags already present (for add)
|
||
not_present:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Tags not present (for remove)
|
||
total_tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: All tags on the asset after the operation
|
||
|
||
# -------------------------------------------------------------------
|
||
# Result / Output types
|
||
# -------------------------------------------------------------------
|
||
ResultItem:
|
||
type: object
|
||
description: A single output file reference
|
||
properties:
|
||
filename:
|
||
type: string
|
||
subfolder:
|
||
type: string
|
||
type:
|
||
type: string
|
||
enum: [input, output, temp]
|
||
display_name:
|
||
type: string
|
||
|
||
NodeOutputs:
|
||
type: object
|
||
description: |
|
||
Outputs from a single node execution. Known keys are listed below,
|
||
but custom nodes may add arbitrary keys (additionalProperties).
|
||
properties:
|
||
images:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ResultItem"
|
||
audio:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ResultItem"
|
||
video:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/ResultItem"
|
||
animated:
|
||
type: array
|
||
items:
|
||
type: boolean
|
||
text:
|
||
oneOf:
|
||
- type: string
|
||
- type: array
|
||
items:
|
||
type: string
|
||
additionalProperties: true
|
||
|
||
TerminalSize:
|
||
type: object
|
||
description: Terminal dimensions
|
||
properties:
|
||
cols:
|
||
type: number
|
||
row:
|
||
type: number
|
||
|
||
LogEntry:
|
||
type: object
|
||
description: A single log entry
|
||
properties:
|
||
t:
|
||
type: string
|
||
description: Timestamp
|
||
m:
|
||
type: string
|
||
description: Log message
|
||
|
||
StatusWsMessageStatus:
|
||
type: object
|
||
description: Inner payload of a `status` WebSocket message, describing the execution queue state.
|
||
properties:
|
||
exec_info:
|
||
type: object
|
||
required:
|
||
- queue_remaining
|
||
properties:
|
||
queue_remaining:
|
||
type: integer
|
||
|
||
StatusWsMessage:
|
||
type: object
|
||
description: Initial status message sent on connect + queue status updates
|
||
properties:
|
||
status:
|
||
$ref: "#/components/schemas/StatusWsMessageStatus"
|
||
sid:
|
||
type: string
|
||
description: Session ID assigned by the server
|
||
|
||
ProgressWsMessage:
|
||
type: object
|
||
description: Node execution progress (step N of M)
|
||
required:
|
||
- value
|
||
- max
|
||
- prompt_id
|
||
- node
|
||
properties:
|
||
value:
|
||
type: integer
|
||
description: Current step
|
||
max:
|
||
type: integer
|
||
description: Total steps
|
||
prompt_id:
|
||
type: string
|
||
node:
|
||
type: string
|
||
description: Node ID currently executing
|
||
|
||
ProgressTextWsMessage:
|
||
type: object
|
||
description: Text-based progress update from a node
|
||
properties:
|
||
nodeId:
|
||
type: string
|
||
text:
|
||
type: string
|
||
prompt_id:
|
||
type: string
|
||
|
||
NodeProgressState:
|
||
type: object
|
||
description: Progress state for a single node
|
||
properties:
|
||
value:
|
||
type: number
|
||
max:
|
||
type: number
|
||
state:
|
||
type: string
|
||
enum: [pending, running, finished, error]
|
||
node_id:
|
||
type: string
|
||
prompt_id:
|
||
type: string
|
||
display_node_id:
|
||
type: string
|
||
parent_node_id:
|
||
type: string
|
||
real_node_id:
|
||
type: string
|
||
|
||
ProgressStateWsMessage:
|
||
type: object
|
||
description: Bulk progress state for all nodes in a prompt
|
||
required:
|
||
- prompt_id
|
||
- nodes
|
||
properties:
|
||
prompt_id:
|
||
type: string
|
||
nodes:
|
||
type: object
|
||
description: Map of node ID to progress state
|
||
additionalProperties:
|
||
$ref: "#/components/schemas/NodeProgressState"
|
||
|
||
ExecutingWsMessage:
|
||
type: object
|
||
description: Fired when a node begins execution
|
||
required:
|
||
- node
|
||
- display_node
|
||
- prompt_id
|
||
properties:
|
||
node:
|
||
type: string
|
||
description: Node ID
|
||
display_node:
|
||
type: string
|
||
description: Display node ID (may differ for subgraphs)
|
||
prompt_id:
|
||
type: string
|
||
|
||
ExecutedWsMessage:
|
||
type: object
|
||
description: Fired when a node completes execution with output
|
||
required:
|
||
- node
|
||
- display_node
|
||
- prompt_id
|
||
- output
|
||
properties:
|
||
node:
|
||
type: string
|
||
display_node:
|
||
type: string
|
||
prompt_id:
|
||
type: string
|
||
output:
|
||
$ref: "#/components/schemas/NodeOutputs"
|
||
merge:
|
||
type: boolean
|
||
description: Whether to merge with existing output
|
||
|
||
ExecutionWsMessageBase:
|
||
type: object
|
||
description: Base fields for execution lifecycle messages
|
||
required:
|
||
- prompt_id
|
||
- timestamp
|
||
properties:
|
||
prompt_id:
|
||
type: string
|
||
timestamp:
|
||
type: integer
|
||
description: Unix timestamp in milliseconds
|
||
|
||
ExecutionStartWsMessage:
|
||
allOf:
|
||
- $ref: "#/components/schemas/ExecutionWsMessageBase"
|
||
description: Fired when prompt execution begins
|
||
|
||
ExecutionSuccessWsMessage:
|
||
allOf:
|
||
- $ref: "#/components/schemas/ExecutionWsMessageBase"
|
||
description: Fired when prompt execution completes successfully
|
||
|
||
ExecutionCachedWsMessage:
|
||
allOf:
|
||
- $ref: "#/components/schemas/ExecutionWsMessageBase"
|
||
- type: object
|
||
properties:
|
||
nodes:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: List of node IDs that were cached
|
||
description: Fired when nodes are served from cache
|
||
|
||
ExecutionInterruptedWsMessage:
|
||
allOf:
|
||
- $ref: "#/components/schemas/ExecutionWsMessageBase"
|
||
- type: object
|
||
properties:
|
||
node_id:
|
||
type: string
|
||
node_type:
|
||
type: string
|
||
executed:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: Node IDs that completed before interruption
|
||
description: Fired when execution is interrupted by user
|
||
|
||
ExecutionErrorWsMessage:
|
||
allOf:
|
||
- $ref: "#/components/schemas/ExecutionWsMessageBase"
|
||
- type: object
|
||
properties:
|
||
node_id:
|
||
type: string
|
||
node_type:
|
||
type: string
|
||
executed:
|
||
type: array
|
||
items:
|
||
type: string
|
||
exception_message:
|
||
type: string
|
||
exception_type:
|
||
type: string
|
||
traceback:
|
||
type: array
|
||
items:
|
||
type: string
|
||
current_inputs: {}
|
||
current_outputs: {}
|
||
description: Fired when a node throws an exception during execution
|
||
|
||
LogsWsMessage:
|
||
type: object
|
||
description: Streaming log entries from the server
|
||
properties:
|
||
size:
|
||
$ref: "#/components/schemas/TerminalSize"
|
||
entries:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/LogEntry"
|
||
|
||
NotificationWsMessage:
|
||
type: object
|
||
description: Server notification (e.g. model download complete)
|
||
properties:
|
||
value:
|
||
type: string
|
||
id:
|
||
type: string
|
||
|
||
FeatureFlagsWsMessage:
|
||
type: object
|
||
description: Feature flags sent on connect
|
||
additionalProperties: true
|
||
|
||
AssetDownloadWsMessage:
|
||
type: object
|
||
description: Asset download progress
|
||
required:
|
||
- task_id
|
||
- asset_name
|
||
- bytes_total
|
||
- bytes_downloaded
|
||
- progress
|
||
- status
|
||
properties:
|
||
task_id:
|
||
type: string
|
||
asset_name:
|
||
type: string
|
||
bytes_total:
|
||
type: number
|
||
bytes_downloaded:
|
||
type: number
|
||
progress:
|
||
type: number
|
||
description: 0.0 to 1.0
|
||
status:
|
||
type: string
|
||
enum: [created, running, completed, failed]
|
||
asset_id:
|
||
type: string
|
||
error:
|
||
type: string
|
||
|
||
AssetExportWsMessage:
|
||
type: object
|
||
description: Bulk asset export progress
|
||
required:
|
||
- task_id
|
||
- assets_total
|
||
- assets_attempted
|
||
- assets_failed
|
||
- bytes_total
|
||
- bytes_processed
|
||
- progress
|
||
- status
|
||
properties:
|
||
task_id:
|
||
type: string
|
||
export_name:
|
||
type: string
|
||
assets_total:
|
||
type: number
|
||
assets_attempted:
|
||
type: number
|
||
assets_failed:
|
||
type: number
|
||
bytes_total:
|
||
type: number
|
||
bytes_processed:
|
||
type: number
|
||
progress:
|
||
type: number
|
||
description: 0.0 to 1.0
|
||
status:
|
||
type: string
|
||
enum: [created, running, completed, failed]
|
||
error:
|
||
type: string
|
||
|
||
# -------------------------------------------------------------------
|
||
# Cloud-runtime schemas
|
||
#
|
||
# These schemas are exclusively referenced by cloud-runtime operations.
|
||
# Tagged x-runtime: [cloud].
|
||
# -------------------------------------------------------------------
|
||
CloudError:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Standard error response from cloud endpoints."
|
||
required:
|
||
- error
|
||
properties:
|
||
error:
|
||
type: string
|
||
description: Error message
|
||
code:
|
||
type: string
|
||
description: Machine-readable error code
|
||
details:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Additional error context
|
||
|
||
CloudJobStatus:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Status of a cloud job."
|
||
required:
|
||
- id
|
||
- status
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
status:
|
||
type: string
|
||
enum: [pending, running, completed, failed, cancelled]
|
||
progress:
|
||
type: number
|
||
minimum: 0
|
||
maximum: 1
|
||
description: "Execution progress (0.0 to 1.0)"
|
||
started_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
completed_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
|
||
CloudPrompt:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A cloud-executed prompt record."
|
||
required:
|
||
- id
|
||
- status
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
status:
|
||
type: string
|
||
workflow:
|
||
type: object
|
||
additionalProperties: true
|
||
outputs:
|
||
type: object
|
||
additionalProperties: true
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
completed_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
|
||
HistoryV2Response:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Paginated execution history in v2 format."
|
||
required:
|
||
- items
|
||
- total
|
||
- has_more
|
||
properties:
|
||
items:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/HistoryV2Entry"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
HistoryV2Entry:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A single execution history entry in v2 format."
|
||
required:
|
||
- id
|
||
- status
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
status:
|
||
type: string
|
||
workflow:
|
||
type: object
|
||
additionalProperties: true
|
||
outputs:
|
||
type: object
|
||
additionalProperties: true
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
started_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
completed_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
preview_output:
|
||
type: object
|
||
additionalProperties: true
|
||
|
||
CloudLogsResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Paginated cloud execution logs."
|
||
required:
|
||
- entries
|
||
properties:
|
||
entries:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
timestamp:
|
||
type: string
|
||
format: date-time
|
||
level:
|
||
type: string
|
||
enum: [debug, info, warn, error]
|
||
message:
|
||
type: string
|
||
job_id:
|
||
type: string
|
||
format: uuid
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
AssetDownloadRequest:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A single asset to download to the cloud runtime."
|
||
required:
|
||
- asset_id
|
||
properties:
|
||
asset_id:
|
||
type: string
|
||
format: uuid
|
||
description: ID of the asset to download
|
||
target_path:
|
||
type: string
|
||
description: Target path on the runtime filesystem
|
||
|
||
ImportPublishedAssetsRequest:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Request body for importing published assets into the caller's library."
|
||
required:
|
||
- published_asset_ids
|
||
properties:
|
||
published_asset_ids:
|
||
type: array
|
||
description: IDs of published assets (inputs and models) to import.
|
||
items:
|
||
type: string
|
||
share_id:
|
||
type: string
|
||
nullable: true
|
||
description: |
|
||
Optional. Share ID of the published workflow these assets belong to. When provided (non-null, non-empty): all `published_asset_ids` must belong to this share's workflow version; returns 400 if the share is not found or any asset does not belong to it. When omitted, null, or empty string: no share-scoped validation is performed and the assets are validated only against global rules (preserved for clients that have not yet adopted `share_id`).
|
||
|
||
ImportPublishedAssetsResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Response after importing published assets. Each returned `AssetInfo.id` is the caller's newly-created private asset ID, not the published asset ID supplied in the request."
|
||
required:
|
||
- assets
|
||
properties:
|
||
assets:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AssetInfo"
|
||
|
||
RemoteAssetMetadata:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Metadata fetched from a remote asset URL."
|
||
properties:
|
||
content_type:
|
||
type: string
|
||
description: MIME type of the remote file
|
||
content_length:
|
||
type: integer
|
||
format: int64
|
||
description: Size in bytes
|
||
filename:
|
||
type: string
|
||
description: Suggested filename from Content-Disposition or URL
|
||
|
||
CloudNode:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] An installed custom node package in the cloud runtime."
|
||
required:
|
||
- id
|
||
- name
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
version:
|
||
type: string
|
||
description:
|
||
type: string
|
||
author:
|
||
type: string
|
||
repository:
|
||
type: string
|
||
format: uri
|
||
installed_at:
|
||
type: string
|
||
format: date-time
|
||
enabled:
|
||
type: boolean
|
||
|
||
HubLabel:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A label/category used for tagging hub content."
|
||
required:
|
||
- id
|
||
- name
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
color:
|
||
type: string
|
||
description: Hex color code for the label
|
||
|
||
HubProfile:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A public user profile on the ComfyUI Hub."
|
||
required:
|
||
- username
|
||
properties:
|
||
username:
|
||
type: string
|
||
display_name:
|
||
type: string
|
||
bio:
|
||
type: string
|
||
avatar_url:
|
||
type: string
|
||
format: uri
|
||
links:
|
||
type: array
|
||
items:
|
||
type: string
|
||
format: uri
|
||
workflow_count:
|
||
type: integer
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
HubWorkflow:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A published workflow on the ComfyUI Hub."
|
||
required:
|
||
- share_id
|
||
- name
|
||
properties:
|
||
share_id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
author:
|
||
$ref: "#/components/schemas/HubProfile"
|
||
labels:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/HubLabel"
|
||
thumbnail_url:
|
||
type: string
|
||
format: uri
|
||
content:
|
||
type: object
|
||
additionalProperties: true
|
||
description: Workflow graph JSON
|
||
likes:
|
||
type: integer
|
||
views:
|
||
type: integer
|
||
forks:
|
||
type: integer
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
HubWorkflowList:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Paginated list of hub workflows."
|
||
required:
|
||
- workflows
|
||
- total
|
||
- has_more
|
||
properties:
|
||
workflows:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/HubWorkflow"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
HubWorkflowIndexEntry:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Lightweight entry in the hub workflow index for client-side search."
|
||
required:
|
||
- share_id
|
||
- name
|
||
properties:
|
||
share_id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
author_username:
|
||
type: string
|
||
labels:
|
||
type: array
|
||
items:
|
||
type: string
|
||
likes:
|
||
type: integer
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
CloudWorkflow:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A cloud-managed workflow with version history."
|
||
required:
|
||
- id
|
||
- name
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
share_id:
|
||
type: string
|
||
nullable: true
|
||
description: Public share identifier if published
|
||
latest_version_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
thumbnail_url:
|
||
type: string
|
||
format: uri
|
||
nullable: true
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
CloudWorkflowList:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Paginated list of cloud workflows."
|
||
required:
|
||
- workflows
|
||
- total
|
||
- has_more
|
||
properties:
|
||
workflows:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/CloudWorkflow"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
CloudWorkflowVersion:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A version of a cloud workflow."
|
||
required:
|
||
- id
|
||
- workflow_id
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
workflow_id:
|
||
type: string
|
||
format: uuid
|
||
version_number:
|
||
type: integer
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
AuthSession:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Current authentication session state."
|
||
required:
|
||
- user
|
||
properties:
|
||
user:
|
||
$ref: "#/components/schemas/CloudUser"
|
||
workspace:
|
||
$ref: "#/components/schemas/Workspace"
|
||
expires_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
AuthTokenResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] OAuth2 token response."
|
||
required:
|
||
- access_token
|
||
- token_type
|
||
properties:
|
||
access_token:
|
||
type: string
|
||
token_type:
|
||
type: string
|
||
description: Always "Bearer"
|
||
expires_in:
|
||
type: integer
|
||
description: Token lifetime in seconds
|
||
refresh_token:
|
||
type: string
|
||
nullable: true
|
||
scope:
|
||
type: string
|
||
|
||
JwksResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] JSON Web Key Set for JWT verification."
|
||
required:
|
||
- keys
|
||
properties:
|
||
keys:
|
||
type: array
|
||
items:
|
||
type: object
|
||
required:
|
||
- kty
|
||
- kid
|
||
- use
|
||
properties:
|
||
kty:
|
||
type: string
|
||
description: Key type (e.g. RSA)
|
||
kid:
|
||
type: string
|
||
description: Key ID
|
||
use:
|
||
type: string
|
||
description: Key use (e.g. sig)
|
||
alg:
|
||
type: string
|
||
description: Algorithm (e.g. RS256)
|
||
n:
|
||
type: string
|
||
description: RSA modulus (base64url)
|
||
e:
|
||
type: string
|
||
description: RSA exponent (base64url)
|
||
additionalProperties: true
|
||
|
||
OAuthAuthorizationServerMetadata:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] OAuth 2.1 authorization-server metadata (RFC 8414)."
|
||
required:
|
||
- issuer
|
||
- authorization_endpoint
|
||
- token_endpoint
|
||
- jwks_uri
|
||
- response_types_supported
|
||
- grant_types_supported
|
||
- code_challenge_methods_supported
|
||
- token_endpoint_auth_methods_supported
|
||
properties:
|
||
issuer:
|
||
type: string
|
||
format: uri
|
||
authorization_endpoint:
|
||
type: string
|
||
format: uri
|
||
token_endpoint:
|
||
type: string
|
||
format: uri
|
||
jwks_uri:
|
||
type: string
|
||
format: uri
|
||
registration_endpoint:
|
||
type: string
|
||
format: uri
|
||
description: "[cloud-only] RFC 7591 §3.1 Dynamic Client Registration endpoint. Advertised so MCP-spec-compliant clients can auto-discover and self-register without operator involvement. Present only when DCR is enabled."
|
||
response_types_supported:
|
||
type: array
|
||
items:
|
||
type: string
|
||
grant_types_supported:
|
||
type: array
|
||
items:
|
||
type: string
|
||
code_challenge_methods_supported:
|
||
type: array
|
||
items:
|
||
type: string
|
||
token_endpoint_auth_methods_supported:
|
||
type: array
|
||
items:
|
||
type: string
|
||
scopes_supported:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
OAuthProtectedResourceMetadata:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] OAuth 2.1 protected-resource metadata (RFC 9728)."
|
||
required:
|
||
- resource
|
||
- authorization_servers
|
||
- scopes_supported
|
||
properties:
|
||
resource:
|
||
type: string
|
||
format: uri
|
||
authorization_servers:
|
||
type: array
|
||
items:
|
||
type: string
|
||
format: uri
|
||
scopes_supported:
|
||
type: array
|
||
items:
|
||
type: string
|
||
bearer_methods_supported:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
OAuthConsentChallenge:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Server-side state describing the OAuth consent decision the user is being asked to make. Returned by GET /oauth/authorize when a valid session exists; the frontend renders the consent UI from this payload and POSTs the decision back. Browser never sees the original OAuth params on resume."
|
||
required:
|
||
- oauth_request_id
|
||
- csrf_token
|
||
- client_display_name
|
||
- resource_display_name
|
||
- scopes
|
||
- workspaces
|
||
properties:
|
||
oauth_request_id:
|
||
type: string
|
||
format: uuid
|
||
description: Opaque server-side identifier for the authorization-request row. Carried back unchanged in the consent submission.
|
||
csrf_token:
|
||
type: string
|
||
description: Per-row CSRF token bound to this authorization request (not to the session). Must be echoed back on POST.
|
||
client_display_name:
|
||
type: string
|
||
description: Human-readable name of the OAuth client requesting authorization.
|
||
resource_display_name:
|
||
type: string
|
||
description: Human-readable name of the protected resource.
|
||
scopes:
|
||
type: array
|
||
description: Scopes the client is requesting for this resource. The frontend should present these for the user to approve.
|
||
items:
|
||
type: string
|
||
workspaces:
|
||
type: array
|
||
description: Workspaces the user can select from. Membership is re-checked on POST.
|
||
items:
|
||
$ref: "#/components/schemas/OAuthConsentChallengeWorkspace"
|
||
|
||
OAuthConsentChallengeWorkspace:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] One workspace option presented in the OAuth consent challenge."
|
||
required: [id, name, type, role]
|
||
properties:
|
||
id: { type: string }
|
||
name: { type: string }
|
||
type: { type: string, enum: [personal, team] }
|
||
role: { type: string, enum: [owner, member] }
|
||
|
||
OAuthAuthorizeRedirectResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Redirect target produced after a JSON consent submission. The frontend must navigate the browser to this URL so custom-scheme client callbacks work without relying on fetch-visible 302 headers."
|
||
required:
|
||
- redirect_url
|
||
properties:
|
||
redirect_url:
|
||
type: string
|
||
format: uri
|
||
description: OAuth client redirect URI with either code+state for allow, or error+state for deny.
|
||
|
||
OAuthTokenResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] RFC 6749 §5.1 successful token response."
|
||
required: [access_token, token_type, expires_in, refresh_token, scope]
|
||
properties:
|
||
access_token:
|
||
type: string
|
||
description: Resource-bound access token (audience matches the protected resource).
|
||
token_type:
|
||
type: string
|
||
enum: [Bearer]
|
||
expires_in:
|
||
type: integer
|
||
description: Access token lifetime in seconds.
|
||
refresh_token:
|
||
type: string
|
||
description: Opaque refresh token. Rotates on every successful refresh; presenting an already-rotated token revokes the entire family.
|
||
scope:
|
||
type: string
|
||
description: Space-delimited scopes granted with this token.
|
||
|
||
OAuthTokenError:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] RFC 6749 §5.2 error response."
|
||
required: [error]
|
||
properties:
|
||
error:
|
||
type: string
|
||
description: 'RFC 6749 §5.2 error code: invalid_request, invalid_client, invalid_grant, unauthorized_client, unsupported_grant_type, invalid_scope.'
|
||
error_description:
|
||
type: string
|
||
description: Human-readable, no leak of internal storage state.
|
||
|
||
OAuthRegisterRequest:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
additionalProperties: false
|
||
description: "[cloud-only] RFC 7591 §2 client metadata document. Only the fields the server honors are listed; presence of `scope` or `resource_grants` in the request is rejected (`invalid_client_metadata`) because those are server-owned for dynamic clients."
|
||
required:
|
||
- redirect_uris
|
||
- application_type
|
||
properties:
|
||
redirect_uris:
|
||
type: array
|
||
items:
|
||
type: string
|
||
minItems: 1
|
||
maxItems: 5
|
||
description: 1–5 redirect URIs. Validated against `application_type` policy.
|
||
client_name:
|
||
type: string
|
||
maxLength: 100
|
||
description: Human-readable name shown in the consent UI. Reserved-name list rejects impersonation of major clients.
|
||
application_type:
|
||
type: string
|
||
enum: [native, web]
|
||
description: |
|
||
RFC 7591 §2 application_type. **REQUIRED** — clients MUST declare intent; the server does not default this field. `native` for desktop / CLI / MCP-spec-strict clients (loopback redirects); `web` for hosted clients (HTTPS only, host must be allowlisted). A missing or explicitly empty `application_type` rejects with `invalid_client_metadata`.
|
||
token_endpoint_auth_method:
|
||
type: string
|
||
enum: [none]
|
||
description: 'Public clients only this phase — must be `none` if present. The server forces `none` regardless.'
|
||
grant_types:
|
||
type: array
|
||
items:
|
||
type: string
|
||
enum: [authorization_code, refresh_token]
|
||
description: Optional. Defaults to `["authorization_code","refresh_token"]`.
|
||
response_types:
|
||
type: array
|
||
items:
|
||
type: string
|
||
enum: [code]
|
||
description: Optional. Defaults to `["code"]`.
|
||
scope:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Dynamic clients do not pick scopes — the server assigns scopes from the active resource's published list. Sending `scope` in the registration body is treated as a privilege-escalation attempt and returns `invalid_client_metadata`."
|
||
resource_grants:
|
||
type: object
|
||
nullable: true
|
||
additionalProperties:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: "**REJECTED IF PRESENT.** Same reason as `scope`. The set of resources and scopes a dynamic client may request is server-policy, not request-driven."
|
||
client_uri:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
logo_uri:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
tos_uri:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
policy_uri:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
software_id:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
software_version:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
contacts:
|
||
type: array
|
||
nullable: true
|
||
items:
|
||
type: string
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
jwks:
|
||
type: object
|
||
nullable: true
|
||
additionalProperties: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
jwks_uri:
|
||
type: string
|
||
nullable: true
|
||
description: "**REJECTED IF PRESENT.** Unsupported RFC 7591 metadata for this public-client phase."
|
||
|
||
OAuthRegisterResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] RFC 7591 §3.2.1 successful registration response."
|
||
required:
|
||
- client_id
|
||
- client_id_issued_at
|
||
- redirect_uris
|
||
- grant_types
|
||
- response_types
|
||
- token_endpoint_auth_method
|
||
- application_type
|
||
properties:
|
||
client_id:
|
||
type: string
|
||
description: Server-generated client_id.
|
||
client_id_issued_at:
|
||
type: integer
|
||
format: int64
|
||
description: Unix timestamp (seconds) when the client was registered.
|
||
client_name:
|
||
type: string
|
||
redirect_uris:
|
||
type: array
|
||
items:
|
||
type: string
|
||
grant_types:
|
||
type: array
|
||
items:
|
||
type: string
|
||
response_types:
|
||
type: array
|
||
items:
|
||
type: string
|
||
token_endpoint_auth_method:
|
||
type: string
|
||
enum: [none]
|
||
application_type:
|
||
type: string
|
||
enum: [native, web]
|
||
|
||
OAuthRegisterError:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] RFC 7591 §3.2.2 error response."
|
||
required:
|
||
- error
|
||
properties:
|
||
error:
|
||
type: string
|
||
enum: [invalid_redirect_uri, invalid_client_metadata]
|
||
error_description:
|
||
type: string
|
||
nullable: true
|
||
|
||
BillingBalance:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Current credit balance and usage summary."
|
||
required:
|
||
- credits_remaining
|
||
properties:
|
||
credits_remaining:
|
||
type: integer
|
||
description: Available credits
|
||
credits_used:
|
||
type: integer
|
||
description: Credits used in current billing period
|
||
credits_total:
|
||
type: integer
|
||
description: Total credits allocated in current period
|
||
|
||
BillingEvent:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A billing event (charge, credit, refund)."
|
||
required:
|
||
- id
|
||
- type
|
||
- amount
|
||
- created_at
|
||
properties:
|
||
id:
|
||
type: string
|
||
type:
|
||
type: string
|
||
enum: [charge, credit, refund, topup, subscription]
|
||
amount:
|
||
type: integer
|
||
description: Amount in credits
|
||
description:
|
||
type: string
|
||
job_id:
|
||
type: string
|
||
format: uuid
|
||
nullable: true
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
BillingEventList:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Paginated list of billing events."
|
||
required:
|
||
- events
|
||
- total
|
||
- has_more
|
||
properties:
|
||
events:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/BillingEvent"
|
||
total:
|
||
type: integer
|
||
has_more:
|
||
type: boolean
|
||
|
||
BillingOp:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A billing operation record."
|
||
required:
|
||
- id
|
||
- status
|
||
properties:
|
||
id:
|
||
type: string
|
||
status:
|
||
type: string
|
||
enum: [pending, completed, failed]
|
||
type:
|
||
type: string
|
||
amount:
|
||
type: integer
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
completed_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
|
||
BillingPlan:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A subscription plan with pricing details."
|
||
required:
|
||
- id
|
||
- name
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
credits_per_month:
|
||
type: integer
|
||
price_cents:
|
||
type: integer
|
||
description: Monthly price in cents (USD)
|
||
currency:
|
||
type: string
|
||
default: usd
|
||
features:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description: List of plan features
|
||
|
||
BillingStatus:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Overall billing and subscription status."
|
||
properties:
|
||
subscription:
|
||
$ref: "#/components/schemas/BillingSubscription"
|
||
balance:
|
||
$ref: "#/components/schemas/BillingBalance"
|
||
has_payment_method:
|
||
type: boolean
|
||
|
||
BillingSubscription:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Active subscription details."
|
||
required:
|
||
- id
|
||
- status
|
||
- plan_id
|
||
properties:
|
||
id:
|
||
type: string
|
||
status:
|
||
type: string
|
||
enum: [active, cancelled, past_due, trialing]
|
||
plan_id:
|
||
type: string
|
||
plan_name:
|
||
type: string
|
||
current_period_start:
|
||
type: string
|
||
format: date-time
|
||
current_period_end:
|
||
type: string
|
||
format: date-time
|
||
cancel_at_period_end:
|
||
type: boolean
|
||
|
||
SubscriptionPreview:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Preview of a subscription change including prorations."
|
||
properties:
|
||
plan_id:
|
||
type: string
|
||
plan_name:
|
||
type: string
|
||
amount_due:
|
||
type: integer
|
||
description: Amount due in cents
|
||
proration_amount:
|
||
type: integer
|
||
description: Proration adjustment in cents
|
||
currency:
|
||
type: string
|
||
next_billing_date:
|
||
type: string
|
||
format: date-time
|
||
|
||
Workspace:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A cloud workspace for team collaboration."
|
||
required:
|
||
- id
|
||
- name
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
owner_id:
|
||
type: string
|
||
member_count:
|
||
type: integer
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
WorkspaceMember:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A member of a cloud workspace."
|
||
required:
|
||
- user_id
|
||
- role
|
||
properties:
|
||
user_id:
|
||
type: string
|
||
email:
|
||
type: string
|
||
format: email
|
||
display_name:
|
||
type: string
|
||
avatar_url:
|
||
type: string
|
||
format: uri
|
||
role:
|
||
type: string
|
||
enum: [owner, admin, member]
|
||
joined_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
WorkspaceInvite:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A pending workspace invitation."
|
||
required:
|
||
- id
|
||
- email
|
||
- role
|
||
properties:
|
||
id:
|
||
type: string
|
||
email:
|
||
type: string
|
||
format: email
|
||
role:
|
||
type: string
|
||
enum: [admin, member]
|
||
invited_by:
|
||
type: string
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
expires_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
WorkspaceApiKey:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A workspace API key (secret value redacted)."
|
||
required:
|
||
- id
|
||
- name
|
||
- description
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
maxLength: 5000
|
||
description: User-provided description of the key's purpose. Always present in responses; empty string when no description was supplied on create.
|
||
prefix:
|
||
type: string
|
||
description: First few characters of the key for identification
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
last_used_at:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
created_by:
|
||
type: string
|
||
|
||
WorkspaceApiKeyCreated:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A newly created workspace API key, including the full secret value (shown only once)."
|
||
required:
|
||
- id
|
||
- name
|
||
- description
|
||
- key
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
maxLength: 5000
|
||
description: User-provided description of the key's purpose. Always present in responses; empty string when no description was supplied on create.
|
||
key:
|
||
type: string
|
||
description: Full API key value (only returned on creation)
|
||
prefix:
|
||
type: string
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
CloudUser:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] A cloud-authenticated user profile."
|
||
required:
|
||
- id
|
||
- email
|
||
properties:
|
||
id:
|
||
type: string
|
||
email:
|
||
type: string
|
||
format: email
|
||
display_name:
|
||
type: string
|
||
avatar_url:
|
||
type: string
|
||
format: uri
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
SecretMeta:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Metadata for a stored secret (value is never returned)."
|
||
required:
|
||
- id
|
||
- name
|
||
properties:
|
||
id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
provider:
|
||
type: string
|
||
description: "[cloud-only] Provider identifier (e.g., huggingface, civitai)."
|
||
x-runtime: [cloud]
|
||
last_used_at:
|
||
type: string
|
||
format: date-time
|
||
description: "[cloud-only] When the secret was last used for decryption."
|
||
x-runtime: [cloud]
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
updated_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
UpdateSecretRequest:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Request body for updating an existing user secret."
|
||
properties:
|
||
name:
|
||
type: string
|
||
description: New name for the secret
|
||
secret_value:
|
||
type: string
|
||
description: New secret value (API key, token, etc.)
|
||
|
||
CreateSessionResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Response after creating a session cookie."
|
||
required:
|
||
- success
|
||
properties:
|
||
success:
|
||
type: boolean
|
||
expiresIn:
|
||
type: integer
|
||
description: Session expiration time in seconds.
|
||
|
||
DeleteSessionResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Response after deleting a session cookie."
|
||
required:
|
||
- success
|
||
properties:
|
||
success:
|
||
type: boolean
|
||
|
||
CreateHubProfileRequest:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Request body for creating a new Hub profile."
|
||
required:
|
||
- workspace_id
|
||
- username
|
||
properties:
|
||
workspace_id:
|
||
type: string
|
||
username:
|
||
type: string
|
||
description: Unique URL-safe slug. Immutable after creation.
|
||
display_name:
|
||
type: string
|
||
description:
|
||
type: string
|
||
avatar_token:
|
||
type: string
|
||
website_urls:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
PublishHubWorkflowRequest:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Request body for publishing or updating a workflow on the Hub."
|
||
required:
|
||
- username
|
||
- name
|
||
- workflow_filename
|
||
- asset_ids
|
||
properties:
|
||
username:
|
||
type: string
|
||
name:
|
||
type: string
|
||
workflow_filename:
|
||
type: string
|
||
asset_ids:
|
||
type: array
|
||
items:
|
||
type: string
|
||
description:
|
||
type: string
|
||
tags:
|
||
type: array
|
||
items:
|
||
type: string
|
||
models:
|
||
type: array
|
||
items:
|
||
type: string
|
||
custom_nodes:
|
||
type: array
|
||
items:
|
||
type: string
|
||
tutorial_url:
|
||
type: string
|
||
metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
thumbnail_type:
|
||
type: string
|
||
enum: [image, video, image_comparison]
|
||
thumbnail_token_or_url:
|
||
type: string
|
||
thumbnail_comparison_token_or_url:
|
||
type: string
|
||
sample_image_tokens_or_urls:
|
||
type: array
|
||
items:
|
||
type: string
|
||
|
||
HubWorkflowDetail:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Full Hub workflow detail including versions, assets, and statistics."
|
||
required:
|
||
- share_id
|
||
- workflow_id
|
||
- name
|
||
- workflow_json
|
||
- assets
|
||
- profile
|
||
- status
|
||
properties:
|
||
share_id:
|
||
type: string
|
||
workflow_id:
|
||
type: string
|
||
name:
|
||
type: string
|
||
status:
|
||
type: string
|
||
enum: [pending, approved, rejected, deprecated]
|
||
description:
|
||
type: string
|
||
thumbnail_type:
|
||
type: string
|
||
enum: [image, video, image_comparison]
|
||
thumbnail_url:
|
||
type: string
|
||
thumbnail_comparison_url:
|
||
type: string
|
||
tutorial_url:
|
||
type: string
|
||
metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
sample_image_urls:
|
||
type: array
|
||
items:
|
||
type: string
|
||
publish_time:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
workflow_json:
|
||
type: object
|
||
additionalProperties: true
|
||
assets:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AssetInfo"
|
||
profile:
|
||
$ref: "#/components/schemas/HubProfile"
|
||
|
||
AssetInfo:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Lightweight asset reference used in workflow publishing payloads."
|
||
required:
|
||
- id
|
||
- filename
|
||
properties:
|
||
id:
|
||
type: string
|
||
filename:
|
||
type: string
|
||
mime_type:
|
||
type: string
|
||
size_bytes:
|
||
type: integer
|
||
format: int64
|
||
|
||
BulkRevokeAPIKeysResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Response after bulk-revoking API keys for a workspace member."
|
||
required:
|
||
- revoked_count
|
||
properties:
|
||
revoked_count:
|
||
type: integer
|
||
minimum: 0
|
||
|
||
CreateWorkflowVersionRequest:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Request body for creating a new version of a saved workflow."
|
||
required:
|
||
- base_version
|
||
- workflow_json
|
||
properties:
|
||
base_version:
|
||
type: integer
|
||
description: Version number this change is based on (for optimistic concurrency).
|
||
workflow_json:
|
||
type: object
|
||
additionalProperties: true
|
||
|
||
WorkflowVersionResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Metadata for a single workflow version."
|
||
required:
|
||
- id
|
||
- version
|
||
- latest_version
|
||
- created_by
|
||
- created_at
|
||
properties:
|
||
id:
|
||
type: string
|
||
version:
|
||
type: integer
|
||
latest_version:
|
||
type: integer
|
||
created_by:
|
||
type: string
|
||
created_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
WorkflowPublishInfo:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Publishing metadata for a workflow shared to the Hub."
|
||
required:
|
||
- workflow_id
|
||
- share_id
|
||
- listed
|
||
- assets
|
||
properties:
|
||
workflow_id:
|
||
type: string
|
||
share_id:
|
||
type: string
|
||
publish_time:
|
||
type: string
|
||
format: date-time
|
||
nullable: true
|
||
listed:
|
||
type: boolean
|
||
assets:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/AssetInfo"
|
||
|
||
TaskEntry:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Task data for list views."
|
||
required:
|
||
- id
|
||
- task_name
|
||
- status
|
||
- create_time
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
task_name:
|
||
type: string
|
||
status:
|
||
type: string
|
||
enum: [created, running, completed, failed]
|
||
create_time:
|
||
type: string
|
||
format: date-time
|
||
started_at:
|
||
type: string
|
||
format: date-time
|
||
completed_at:
|
||
type: string
|
||
format: date-time
|
||
|
||
TaskResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Full task details including payload and result."
|
||
required:
|
||
- id
|
||
- idempotency_key
|
||
- task_name
|
||
- payload
|
||
- status
|
||
- create_time
|
||
- update_time
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
idempotency_key:
|
||
type: string
|
||
task_name:
|
||
type: string
|
||
payload:
|
||
type: object
|
||
additionalProperties: true
|
||
status:
|
||
type: string
|
||
enum: [created, running, completed, failed]
|
||
result:
|
||
type: object
|
||
additionalProperties: true
|
||
create_time:
|
||
type: string
|
||
format: date-time
|
||
update_time:
|
||
type: string
|
||
format: date-time
|
||
started_at:
|
||
type: string
|
||
format: date-time
|
||
completed_at:
|
||
type: string
|
||
format: date-time
|
||
error:
|
||
type: string
|
||
|
||
TasksListResponse:
|
||
type: object
|
||
x-runtime: [cloud]
|
||
description: "[cloud-only] Paginated list of background tasks for the authenticated user."
|
||
required:
|
||
- tasks
|
||
- pagination
|
||
properties:
|
||
tasks:
|
||
type: array
|
||
items:
|
||
$ref: "#/components/schemas/TaskEntry"
|
||
pagination:
|
||
$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
|