Instructions to use saik0s/comfy_backup with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use saik0s/comfy_backup with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="saik0s/comfy_backup", filename="ComfyUI/models/text_encoders/gemma-3-12b-it-q2_k.gguf", )
llm.create_chat_completion( messages = "No input example has been defined for this model task." )
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use saik0s/comfy_backup with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: llama cli -hf saik0s/comfy_backup:Q4_K_S
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: llama cli -hf saik0s/comfy_backup:Q4_K_S
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: ./llama-cli -hf saik0s/comfy_backup:Q4_K_S
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf saik0s/comfy_backup:Q4_K_S # Run inference directly in the terminal: ./build/bin/llama-cli -hf saik0s/comfy_backup:Q4_K_S
Use Docker
docker model run hf.co/saik0s/comfy_backup:Q4_K_S
- LM Studio
- Jan
- Ollama
How to use saik0s/comfy_backup with Ollama:
ollama run hf.co/saik0s/comfy_backup:Q4_K_S
- Unsloth Studio
How to use saik0s/comfy_backup with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for saik0s/comfy_backup to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for saik0s/comfy_backup to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for saik0s/comfy_backup to start chatting
- Pi
How to use saik0s/comfy_backup with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf saik0s/comfy_backup:Q4_K_S
Configure the model in Pi
# Install Pi: npm install -g @mariozechner/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "saik0s/comfy_backup:Q4_K_S" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Hermes Agent new
How to use saik0s/comfy_backup with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf saik0s/comfy_backup:Q4_K_S
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default saik0s/comfy_backup:Q4_K_S
Run Hermes
hermes
- Atomic Chat new
- Docker Model Runner
How to use saik0s/comfy_backup with Docker Model Runner:
docker model run hf.co/saik0s/comfy_backup:Q4_K_S
- Lemonade
How to use saik0s/comfy_backup with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull saik0s/comfy_backup:Q4_K_S
Run and chat with the model
lemonade run user.comfy_backup-Q4_K_S
List all available models
lemonade list
| 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 | |
| content: | |
| application/json: | |
| schema: | |
| $ref: "#/components/schemas/QueueManageResponse" | |
| '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/GetUserDataResponseFull" | |
| "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/UserDataResponseFull" | |
| "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/UserDataResponseFull" | |
| "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/JobCancelResponse" | |
| "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/JobStatusResponse" | |
| "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/HistoryResponse" | |
| "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/HistoryDetailResponse" | |
| "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/LogsResponse" | |
| "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 | |
| properties: | |
| job_ids: | |
| type: array | |
| items: | |
| type: string | |
| description: Job IDs whose associated assets should all be included in the ZIP bundle. | |
| asset_ids: | |
| type: array | |
| items: | |
| type: string | |
| format: uuid | |
| description: Asset IDs to include in the ZIP bundle. Additive to assets associated with provided job IDs. | |
| export_name: | |
| type: string | |
| description: Name for the export archive | |
| naming_strategy: | |
| type: string | |
| enum: [group_by_job_id, preserve, asset_id, group_by_job_time] | |
| default: group_by_job_time | |
| description: "Strategy for naming files in the ZIP: group by job ID, preserve original names, use the asset ID, or group by job creation time." | |
| job_asset_name_filters: | |
| type: object | |
| additionalProperties: | |
| type: array | |
| minItems: 1 | |
| items: | |
| type: string | |
| description: Optional per-job asset name filters. When provided for a job ID, only assets whose name matches one of the listed names are included. | |
| 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/AssetMetadataResponse" | |
| "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: | |
| $ref: "#/components/schemas/HubLabelListResponse" | |
| '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/HubWorkflowListResponse" | |
| '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/HubWorkflowDetail" | |
| "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/WorkflowListResponse" | |
| "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/WorkflowResponse" | |
| "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/WorkflowResponse" | |
| "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/WorkflowResponse" | |
| "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/WorkflowResponse" | |
| "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/PublishedWorkflowDetail" | |
| "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/ExchangeTokenResponse" | |
| "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/BillingBalanceResponse" | |
| "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/BillingEventsResponse" | |
| "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/BillingOpStatusResponse" | |
| "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/PreviewSubscribeResponse" | |
| "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/BillingStatusResponse" | |
| "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/SubscribeResponse" | |
| "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/CancelSubscriptionResponse" | |
| "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/ResubscribeResponse" | |
| "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/CreateTopupResponse" | |
| "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/CreateWorkspaceAPIKeyResponse" | |
| "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: | |
| 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/PendingInvite" | |
| "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: | |
| $ref: "#/components/schemas/FeedbackRequest" | |
| 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/AcceptInviteResponse" | |
| "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/SecretResponse" | |
| "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/SecretResponse" | |
| "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/SecretResponse" | |
| "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/UserResponse" | |
| "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 | |
| QueueManageResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: >- | |
| [cloud-only] Result of a queue mutation. The Cloud runtime returns which | |
| items were deleted and whether the queue was cleared; local ComfyUI | |
| returns an empty 200 body. | |
| properties: | |
| deleted: | |
| type: array | |
| nullable: true | |
| items: | |
| type: string | |
| description: Prompt IDs that were deleted from the queue. | |
| cleared: | |
| type: boolean | |
| nullable: true | |
| description: Whether the queue was cleared. | |
| # ------------------------------------------------------------------- | |
| # 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 | |
| enum: | |
| - pending | |
| - in_progress | |
| - completed | |
| - failed | |
| - cancelled | |
| 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 | |
| workflow_id: | |
| type: string | |
| nullable: true | |
| x-runtime: [cloud] | |
| description: "[cloud-only] UUID of the Cloud workflow entity this job is associated with. Local ComfyUI returns null." | |
| execution_error: | |
| x-runtime: [cloud] | |
| description: "[cloud-only] Detailed execution error from ComfyUI for failed jobs. Absent on local ComfyUI." | |
| allOf: | |
| - $ref: "#/components/schemas/ExecutionError" | |
| JobDetailResponse: | |
| type: object | |
| description: Full job details including workflow and outputs | |
| required: | |
| - id | |
| - status | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| status: | |
| type: string | |
| enum: | |
| - pending | |
| - in_progress | |
| - completed | |
| - failed | |
| - cancelled | |
| 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: string | |
| x-runtime: [cloud] | |
| description: "[cloud-only] Overall billing/payment lifecycle status." | |
| enum: | |
| - awaiting_payment_method | |
| - pending_payment | |
| - paid | |
| - payment_failed | |
| - inactive | |
| 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 | |
| type: | |
| type: string | |
| enum: | |
| - personal | |
| - team | |
| description: Workspace type (personal vs. team). | |
| 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 | |
| - 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 | |
| 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. | |
| HubLabelListResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response wrapper for the available Hub label catalog.' | |
| required: | |
| - labels | |
| properties: | |
| labels: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/HubLabelInfo' | |
| description: Available labels, optionally filtered by type. | |
| 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 | |
| - 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 | |
| - 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 | |
| AcceptInviteResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response returned after successfully accepting a workspace invitation.' | |
| required: | |
| - workspace_id | |
| - workspace_name | |
| properties: | |
| workspace_id: | |
| type: string | |
| description: ID of the workspace joined | |
| workspace_name: | |
| type: string | |
| description: Name of the workspace joined | |
| BillingEventsResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Paginated list of billing events for a workspace.' | |
| required: | |
| - total | |
| - events | |
| - page | |
| - limit | |
| - totalPages | |
| properties: | |
| total: | |
| type: integer | |
| description: Total number of events | |
| events: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/BillingEvent' | |
| page: | |
| type: integer | |
| description: Current page number (1-indexed) | |
| limit: | |
| type: integer | |
| description: Items per page | |
| totalPages: | |
| type: integer | |
| description: Total number of pages | |
| BillingOpStatusResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Status of an asynchronous billing operation.' | |
| required: | |
| - id | |
| - status | |
| - started_at | |
| properties: | |
| id: | |
| type: string | |
| description: Unique identifier for the billing operation | |
| status: | |
| type: string | |
| enum: | |
| - pending | |
| - succeeded | |
| - failed | |
| description: Current status of the operation | |
| error_message: | |
| type: string | |
| description: Error message if status is failed | |
| started_at: | |
| type: string | |
| format: date-time | |
| description: When the operation was initiated | |
| completed_at: | |
| type: string | |
| format: date-time | |
| description: When the operation completed (success or failure) | |
| CancelSubscriptionResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response after successfully cancelling a subscription.' | |
| required: | |
| - cancel_at | |
| - billing_op_id | |
| properties: | |
| billing_op_id: | |
| type: string | |
| description: Billing operation ID to poll for status via GET /api/billing/ops/{id} | |
| cancel_at: | |
| type: string | |
| format: date-time | |
| description: The date when the subscription will end (end of current billing period) | |
| CreateTopupResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response after successfully purchasing a credit top-up.' | |
| required: | |
| - topup_id | |
| - status | |
| - amount_cents | |
| - billing_op_id | |
| properties: | |
| billing_op_id: | |
| type: string | |
| description: Billing operation ID to poll for status via GET /api/billing/ops/{id} | |
| topup_id: | |
| type: string | |
| description: Unique identifier for the top-up request (same as billing_op_id, deprecated) | |
| status: | |
| type: string | |
| enum: | |
| - pending | |
| - completed | |
| - failed | |
| description: Current status of the top-up | |
| amount_cents: | |
| type: integer | |
| format: int64 | |
| description: Amount being charged in cents | |
| CreateWorkspaceAPIKeyResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response containing the newly created workspace API key.' | |
| required: | |
| - id | |
| - name | |
| - description | |
| - key | |
| - key_prefix | |
| - created_at | |
| properties: | |
| id: | |
| type: string | |
| format: uuid | |
| description: API key ID | |
| 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: | |
| type: string | |
| description: The full plaintext API key (only shown once) | |
| 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) | |
| created_at: | |
| type: string | |
| format: date-time | |
| description: When the key was created | |
| ExchangeTokenResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response containing the issued Cloud JWT and its expiry.' | |
| required: | |
| - token | |
| - expires_at | |
| - workspace | |
| - role | |
| - permissions | |
| properties: | |
| token: | |
| type: string | |
| description: Cloud JWT token | |
| expires_at: | |
| type: string | |
| format: date-time | |
| description: Token expiration time (RFC 3339) | |
| workspace: | |
| $ref: '#/components/schemas/WorkspaceSummary' | |
| role: | |
| type: string | |
| enum: | |
| - owner | |
| - member | |
| description: User's role in the workspace | |
| permissions: | |
| type: array | |
| items: | |
| type: string | |
| description: Permission strings for the role | |
| example: | |
| - owner:* | |
| JobCancelResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response for POST /api/jobs/{job_id}/cancel. Returned on both fresh cancels and idempotent no-ops.' | |
| required: | |
| - cancelled | |
| properties: | |
| cancelled: | |
| type: boolean | |
| description: "True when a cancel event was successfully dispatched by this call.\nFalse when the job was already in\ | |
| \ a terminal or cancelling state,\nin which case the call is a no-op (still 200 \u2014 idempotent).\n" | |
| ResubscribeResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response after successfully resubscribing to a billing plan.' | |
| required: | |
| - status | |
| - billing_op_id | |
| properties: | |
| billing_op_id: | |
| type: string | |
| description: Billing operation ID to poll for status via GET /api/billing/ops/{id} | |
| status: | |
| type: string | |
| enum: | |
| - active | |
| description: The subscription status after resubscribing | |
| message: | |
| type: string | |
| description: Human-readable confirmation message | |
| SubscribeResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Response after successfully subscribing to a billing plan.' | |
| required: | |
| - status | |
| - billing_op_id | |
| properties: | |
| billing_op_id: | |
| type: string | |
| description: Billing operation ID to poll for status via GET /api/billing/ops/{id} | |
| status: | |
| type: string | |
| enum: | |
| - subscribed | |
| - needs_payment_method | |
| - pending_payment | |
| description: 'Status of the subscription operation: | |
| - subscribed: Subscription is active immediately | |
| - needs_payment_method: User must add payment method via payment_method_url | |
| - pending_payment: Upgrade initiated, waiting for payment to complete | |
| ' | |
| effective_at: | |
| type: string | |
| format: date-time | |
| description: When the subscription became/becomes active (present when status=subscribed or pending_payment) | |
| payment_method_url: | |
| type: string | |
| description: URL to redirect user to add payment method (present when status=needs_payment_method) | |
| UserResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] User information response' | |
| required: | |
| - id | |
| - status | |
| properties: | |
| id: | |
| type: string | |
| description: Firebase UID of the authenticated user | |
| status: | |
| type: string | |
| description: User status (always "active" for authenticated users) | |
| WorkflowListResponse: | |
| type: object | |
| x-runtime: [cloud] | |
| description: '[cloud-only] Paginated list of saved workflows.' | |
| required: | |
| - data | |
| - pagination | |
| properties: | |
| data: | |
| type: array | |
| items: | |
| $ref: '#/components/schemas/WorkflowResponse' | |
| pagination: | |
| $ref: '#/components/schemas/PaginationInfo' | |
| FeedbackRequest: | |
| type: object | |
| x-runtime: [cloud] | |
| description: "[cloud-only] User feedback submission body." | |
| required: | |
| - message | |
| properties: | |
| type: | |
| type: string | |
| enum: | |
| - missing_nodes | |
| - general | |
| - missing_models | |
| description: Feedback category | |
| category: | |
| type: string | |
| description: Additional category metadata | |
| message: | |
| type: string | |
| description: User-provided feedback message | |