openapi: "3.0.3"

info:
  version: 1.766.2
  title: Windmill API

  contact:
    name: Windmill Team
    email: contact@windmill.dev
    url: https://windmill.dev

  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html

  x-logo:
    url: https://windmill.dev/img/windmill.svg
externalDocs:
  description: documentation portal
  url: https://windmill.dev

servers:
  - url: /api

security:
  - bearerAuth: []
  - cookieAuth: []

paths:
  /version:
    get:
      summary: get backend version
      operationId: backendVersion
      tags:
        - settings
      responses:
        "200":
          description: git version of backend
          content:
            text/plain:
              schema:
                type: string

  /health/status:
    get:
      summary: health status
      description: |
        Health status endpoint. Returns cached health status (database connectivity, worker count).
        Cache TTL is fixed at 5 seconds. Use force=true query parameter to bypass cache.
        Note: This endpoint is intentionally different from Kubernetes probes to avoid confusion.
        For k8s liveness/readiness probes, use /version endpoint.
      operationId: getHealthStatus
      tags:
        - health
      security: []
      parameters:
        - name: force
          in: query
          description: Force a fresh check, bypassing the cache
          required: false
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: server is healthy or degraded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthStatusResponse"
        "503":
          description: server is unhealthy (database unreachable)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthStatusResponse"

  /health/detailed:
    get:
      summary: detailed health status
      description: |
        Returns detailed health information including database pool stats, worker details, and queue status.
        Requires authentication. Use for monitoring dashboards and debugging.
        This endpoint always returns fresh data (no caching).
      operationId: getHealthDetailed
      tags:
        - health
      responses:
        "200":
          description: server is healthy or degraded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DetailedHealthResponse"
        "503":
          description: server is unhealthy (database unreachable)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DetailedHealthResponse"

  /uptodate:
    get:
      summary: is backend up to date
      operationId: backendUptodate
      tags:
        - settings
      responses:
        "200":
          description: is backend up to date
          content:
            text/plain:
              schema:
                type: string

  /ee_license:
    get:
      summary: get license id
      operationId: getLicenseId
      tags:
        - settings
      responses:
        "200":
          description: get license id (empty if not ee)
          content:
            text/plain:
              schema:
                type: string

  /docs/search:
    get:
      summary: "Full-text search across the entire Windmill documentation. Provide one or more keywords; returns the most relevant docs pages, each with its Source URL and short matching snippets. Use this FIRST to find relevant pages by their content (a flag, function, error message, config key or concept). If the snippets answer the question, answer directly; otherwise call readDocsPage with a returned Source URL to read more."
      operationId: searchDocs
      x-mcp-tool: true
      tags:
        - documentation
      parameters:
        - name: query
          description: 'Keywords to search for in the documentation body, e.g. "chromium worker tag" or "retry exponential backoff". Fewer, more distinctive words match better.'
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: matching documentation pages
          content:
            application/json:
              schema:
                type: object
                properties:
                  text:
                    type: string
                    description: Model-ready rendering of the results
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        url:
                          type: string
                        title:
                          type: string
                        score:
                          type: integer
                        snippets:
                          type: array
                          items:
                            type: string
                      required:
                        - url
                        - title
                        - score
                        - snippets
                required:
                  - text
                  - results

  /docs/page:
    get:
      summary: "Fetch the markdown of a single Windmill documentation page. Provide the `url` of a page found via searchDocs (its Source URL). If the page is large, this returns its list of section headings instead of the full content; call again with the `section` argument set to one of those headings to read that section."
      operationId: readDocsPage
      x-mcp-tool: true
      tags:
        - documentation
      parameters:
        - name: url
          description: "The docs page to read, as a Source URL returned by searchDocs (e.g. https://www.windmill.dev/docs/core_concepts/jobs). A bare path (e.g. /docs/core_concepts/jobs) is also accepted."
          in: query
          required: true
          schema:
            type: string
        - name: section
          description: "Optional. A heading title from the page outline to read just that section instead of the full page."
          in: query
          schema:
            type: string
      responses:
        "200":
          description: documentation page content
          content:
            application/json:
              schema:
                type: object
                properties:
                  text:
                    type: string
                  source_url:
                    type: string
                required:
                  - text
                  - source_url

  /openapi.yaml:
    get:
      summary: get openapi yaml spec
      operationId: getOpenApiYaml
      tags:
        - settings
      responses:
        "200":
          description: openapi yaml file content
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/audit/get/{id}:
    get:
      summary: get audit log (requires admin privilege)
      operationId: getAuditLog
      tags:
        - audit
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/PathId"
      responses:
        "200":
          description: an audit log
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuditLog"

  /w/{workspace}/audit/list:
    get:
      summary: list audit logs (requires admin privilege)
      operationId: listAuditLogs
      tags:
        - audit
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/Before"
        - $ref: "#/components/parameters/After"
        - $ref: "#/components/parameters/Username"
        - $ref: "#/components/parameters/Operation"
        - name: operations
          in: query
          description: comma separated list of exact operations to include
          schema:
            type: string
        - name: exclude_operations
          in: query
          description: comma separated list of operations to exclude
          schema:
            type: string
        - $ref: "#/components/parameters/ResourceName"
        - $ref: "#/components/parameters/ActionKind"
        - name: all_workspaces
          in: query
          description: get audit logs for all workspaces
          schema:
            type: boolean

      responses:
        "200":
          description: a list of audit logs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AuditLog"

  /auth/login:
    post:
      security: []
      summary: login with password
      operationId: login
      tags:
        - user
      requestBody:
        description: credentials
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Login"

      responses:
        "200":
          description: >
            Successfully authenticated. The session ID is returned in a cookie
            named `token` and as plaintext response. Preferred method of
            authorization is through the bearer token. The cookie is only for
            browser convenience.

          headers:
            Set-Cookie:
              schema:
                type: string
                example: token=abcde12345; Path=/; HttpOnly
          content:
            text/plain:
              schema:
                type: string

  /auth/logout:
    post:
      security: []
      summary: logout
      operationId: logout
      tags:
        - user

      responses:
        "200":
          description: clear cookies and clear token (if applicable)
          headers:
            Set-Cookie:
              schema:
                type: string
          content:
            text/plain:
              schema:
                type: string

  /auth/is_smtp_configured:
    get:
      security: []
      summary: check if SMTP is configured for password reset
      operationId: isSmtpConfigured
      tags:
        - user
      responses:
        "200":
          description: returns true if SMTP is configured
          content:
            application/json:
              schema:
                type: boolean

  /auth/is_password_login_disabled:
    get:
      security: []
      summary: check if password login is disabled instance-wide
      operationId: isPasswordLoginDisabled
      tags:
        - user
      responses:
        "200":
          description: returns true if password login is disabled
          content:
            application/json:
              schema:
                type: boolean

  /auth/request_password_reset:
    post:
      security: []
      summary: request password reset email
      operationId: requestPasswordReset
      tags:
        - user
      requestBody:
        description: email to send password reset link to
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - email
              properties:
                email:
                  type: string
                  format: email
      responses:
        "200":
          description: password reset email sent (if user exists)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PasswordResetResponse"
        "400":
          description: SMTP not configured

  /auth/reset_password:
    post:
      security: []
      summary: reset password using token
      operationId: resetPassword
      tags:
        - user
      requestBody:
        description: token and new password
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - token
                - new_password
              properties:
                token:
                  type: string
                new_password:
                  type: string
      responses:
        "200":
          description: password reset successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PasswordResetResponse"
        "400":
          description: invalid or expired token

  /w/{workspace}/users/get/{username}:
    get:
      summary: get user (require admin privilege)
      operationId: getUser
      tags:
        - user
        - admin
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: user created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /w/{workspace}/users/update/{username}:
    post:
      summary: update user (require admin privilege)
      operationId: updateUser
      tags:
        - user
        - admin
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: new user
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditWorkspaceUser"
      responses:
        "200":
          description: edited user
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/users/is_owner/{path}:
    get:
      summary: is owner of path
      operationId: isOwnerOfPath
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: is owner
          content:
            application/json:
              schema:
                type: boolean

  /users/setpassword:
    post:
      summary: set password
      operationId: setPassword
      tags:
        - user
      requestBody:
        description: set password
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                password:
                  type: string
              required:
                - password
      responses:
        "200":
          description: password set
          content:
            text/plain:
              schema:
                type: string

  /users/set_password_of/{user}:
    post:
      summary: set password for a specific user (require super admin)
      operationId: setPasswordForUser
      tags:
        - user
      parameters:
        - name: user
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: set password
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                password:
                  type: string
              required:
                - password
      responses:
        "200":
          description: password set
          content:
            text/plain:
              schema:
                type: string

  /users/set_login_type/{user}:
    post:
      summary: set login type for a specific user (require super admin)
      operationId: setLoginTypeForUser
      tags:
        - user
      parameters:
        - name: user
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: set login type
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                login_type:
                  type: string
              required:
                - login_type
      responses:
        "200":
          description: login type set
          content:
            text/plain:
              schema:
                type: string

  /users/create:
    post:
      summary: create user
      operationId: createUserGlobally
      tags:
        - user
      requestBody:
        description: user info
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                password:
                  type: string
                super_admin:
                  type: boolean
                name:
                  type: string
                company:
                  type: string
                skip_email:
                  type: boolean
                  description: Skip sending email notifications to the user
              required:
                - email
                - password
                - super_admin
      responses:
        "201":
          description: user created
          content:
            text/plain:
              schema:
                type: string

  /users/update/{email}:
    post:
      summary: global update user (require super admin)
      operationId: globalUserUpdate
      tags:
        - user
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: new user info
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                is_super_admin:
                  type: boolean
                is_devops:
                  type: boolean
                name:
                  type: string
                disabled:
                  type: boolean
      responses:
        "200":
          description: user updated
          content:
            text/plain:
              schema:
                type: string

  /users/username_info/{email}:
    get:
      summary: global username info (require super admin)
      operationId: globalUsernameInfo
      tags:
        - user
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: user renamed
          content:
            application/json:
              schema:
                type: object
                properties:
                  username:
                    type: string
                  workspace_usernames:
                    type: array
                    items:
                      type: object
                      properties:
                        workspace_id:
                          type: string
                        username:
                          type: string
                      required:
                        - workspace_id
                        - username
                required:
                  - username
                  - workspace_usernames

  /users/rename/{email}:
    post:
      summary: global rename user (require super admin)
      operationId: globalUserRename
      tags:
        - user
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: new username
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                new_username:
                  type: string
              required:
                - new_username
      responses:
        "200":
          description: user renamed
          content:
            text/plain:
              schema:
                type: string

  /users/delete/{email}:
    delete:
      summary: global delete user (require super admin)
      operationId: globalUserDelete
      tags:
        - user
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: user deleted
          content:
            text/plain:
              schema:
                type: string
  /users/overwrite:
    post:
      summary: global overwrite users (require super admin and EE)
      operationId: globalUsersOverwrite
      tags:
        - user
      requestBody:
        description: List of users
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/ExportedUser"
      responses:
        "200":
          description: Success message
          content:
            text/plain:
              schema:
                type: string

  /users/export:
    get:
      summary: global export users (require super admin and EE)
      operationId: globalUsersExport
      tags:
        - user
      responses:
        "200":
          description: exported users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ExportedUser"

  /users/ext_jwt_tokens:
    get:
      summary: list external JWT tokens (ee only)
      operationId: listExtJwtTokens
      tags:
        - user
      parameters:
        - name: page
          in: query
          schema:
            type: integer
        - name: per_page
          in: query
          schema:
            type: integer
        - name: active_only
          in: query
          description: only tokens used in the last 30 days
          schema:
            type: boolean
      responses:
        "200":
          description: list of external JWT tokens
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ExternalJwtToken"

  /users/onboarding:
    post:
      summary: Submit user onboarding data
      operationId: submitOnboardingData
      tags:
        - user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                touch_point:
                  type: string
                use_case:
                  type: string
      responses:
        "200":
          description: Onboarding data submitted successfully
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/users/delete/{username}:
    delete:
      summary: delete user (require admin privilege, except for the creator of a fork removing a non-admin member of the fork)
      operationId: deleteUser
      tags:
        - user
        - admin
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: delete user
          content:
            text/plain:
              schema:
                type: string
  /w/{workspace}/users/offboard_preview/{username}:
    get:
      summary: preview offboarding for a workspace user (require admin privilege)
      operationId: offboardPreview
      tags:
        - user
        - admin
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: offboard preview with object counts
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OffboardPreview"
  /w/{workspace}/users/offboard/{username}:
    post:
      summary: offboard a workspace user (reassign objects, optionally delete user)
      operationId: offboardWorkspaceUser
      tags:
        - user
        - admin
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OffboardRequest"
      responses:
        "200":
          description: offboard response with conflicts or summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OffboardResponse"
  /users/offboard_preview/{email}:
    get:
      summary: preview global offboarding for a user across all workspaces (require super admin)
      operationId: globalOffboardPreview
      tags:
        - user
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: per-workspace offboard previews
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GlobalOffboardPreview"
  /users/offboard/{email}:
    post:
      summary: offboard a user globally (reassign objects across workspaces, optionally delete)
      operationId: offboardGlobalUser
      tags:
        - user
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GlobalOffboardRequest"
      responses:
        "200":
          description: offboard result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OffboardResponse"
  /w/{workspace}/users/convert_to_group/{username}:
    post:
      summary: convert manual user to group user (require admin privilege)
      operationId: convertUserToGroup
      tags:
        - user
        - admin
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: convert user to group user
          content:
            text/plain:
              schema:
                type: string

  /github_app/connected_repositories:
    get:
      summary: get connected repositories
      operationId: getGlobalConnectedRepositories
      tags:
        - Git Sync
      parameters:
        - name: page
          in: query
          description: Page number for pagination (default 1)
          required: false
          schema:
            type: integer
            default: 1
      responses:
        "200":
          description: connected repositories
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GithubInstallations"

  /workspaces/list:
    get:
      summary: list all workspaces visible to me
      operationId: listWorkspaces
      tags:
        - workspace
      responses:
        "200":
          description: all workspaces
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Workspace"

  /workspaces/allowed_domain_auto_invite:
    get:
      summary: is domain allowed for auto invi
      operationId: isDomainAllowed
      tags:
        - workspace
      responses:
        "200":
          description: domain allowed or not
          content:
            application/json:
              schema:
                type: boolean

  /workspaces/users:
    get:
      summary: list all workspaces visible to me with user info
      operationId: listUserWorkspaces
      tags:
        - workspace
      responses:
        "200":
          description: workspace with associated username
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserWorkspaceList"

  /workspaces/session_workspace_status:
    post:
      summary: get the lifecycle status of workspaces referenced by client-side sessions
      operationId: getSessionWorkspaceStatus
      tags:
        - workspace
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                workspace_ids:
                  type: array
                  items:
                    type: string
              required:
                - workspace_ids
      responses:
        "200":
          description: map of workspace id to status (active, archived, or deleted)
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                  enum:
                    - active
                    - archived
                    - deleted

  /w/{workspace}/workspaces/get_as_superadmin:
    get:
      summary: get workspace as super admin (require to be super admin)
      operationId: getWorkspaceAsSuperAdmin
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: workspace
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Workspace"

  /workspaces/list_as_superadmin:
    get:
      summary: list all workspaces as super admin (require to be super admin)
      operationId: listWorkspacesAsSuperAdmin
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: workspaces
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Workspace"

  /workspaces/create:
    post:
      summary: create workspace
      operationId: createWorkspace
      tags:
        - workspace
      requestBody:
        description: new token
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateWorkspace"
      responses:
        "201":
          description: token created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/create_workspace_fork_branch:
    post:
      summary: create forked workspace branch with git sync
      operationId: createWorkspaceForkGitBranch
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new forked workspace
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateWorkspaceFork"
      responses:
        "201":
          description: forked workspace branch created
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                  format: uuid

  /w/{workspace}/workspaces/create_fork:
    post:
      summary: create forked workspace
      operationId: createWorkspaceFork
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new forked workspace
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateWorkspaceFork"
      responses:
        "201":
          description: forked workspace created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/attach_dev_workspace:
    post:
      summary: attach an existing workspace as the dev workspace of this (prod) workspace
      operationId: attachDevWorkspace
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                dev_workspace_id:
                  type: string
                lock_prod_deploy:
                  type: boolean
                lock_prod_forking:
                  type: boolean
                dev_workspace_label:
                  type: string
                  enum: [dev, staging]
              required:
                - dev_workspace_id
      responses:
        "200":
          description: dev workspace attached
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/detach_dev_workspace:
    post:
      summary: detach the dev workspace from this (prod) workspace
      operationId: detachDevWorkspace
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                dev_workspace_id:
                  type: string
              required:
                - dev_workspace_id
      responses:
        "200":
          description: dev workspace detached
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/get_dev_workspace:
    get:
      summary: this workspace's active canonical dev workspace, if any
      operationId: getDevWorkspace
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: the dev workspace, or null if none
          content:
            application/json:
              schema:
                nullable: true
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  dev_workspace_label:
                    type: string
                    nullable: true
                    description: "Cosmetic display label ('dev' | 'staging'); null defaults to 'dev'"
                required:
                  - id
                  - name

  /workspaces/exists:
    post:
      summary: exists workspace
      operationId: existsWorkspace
      tags:
        - workspace
      requestBody:
        description: id of workspace
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
              required:
                - id
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: boolean

  /workspaces/exists_username:
    post:
      summary: exists username
      operationId: existsUsername
      tags:
        - workspace
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                username:
                  type: string
              required:
                - id
                - username
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: boolean

  /settings/refresh_custom_instance_user_pwd:
    post:
      summary: Refreshes the password for the custom_instance_user
      operationId: refreshCustomInstanceUserPwd
      tags:
        - setting
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                type: object

  /settings/list_custom_instance_pg_databases:
    post:
      summary: Returns the set-up statuses of custom instance pg databases
      operationId: listCustomInstanceDbs
      tags:
        - setting
      responses:
        "200":
          description: Statuses of all custom instance dbs
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  $ref: "#/components/schemas/CustomInstanceDb"

  /settings/setup_custom_instance_pg_database/{name}:
    post:
      summary: Runs CREATE DATABASE on the Windmill Postgres and grants access to the custom_instance_user
      operationId: setupCustomInstanceDb
      tags:
        - setting
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                tag:
                  $ref: "#/components/schemas/CustomInstanceDbTag"
      parameters:
        - in: path
          name: name
          required: true
          schema:
            type: string
          description: The name of the database to create
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CustomInstanceDb"

  /settings/drop_custom_instance_pg_database/{name}:
    post:
      summary: Drops a custom instance database (superadmin only, irreversible)
      operationId: dropCustomInstanceDb
      tags:
        - setting
      parameters:
        - in: path
          name: name
          required: true
          schema:
            type: string
          description: The name of the database to drop
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings/global/{key}:
    get:
      summary: get global settings
      operationId: getGlobal
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/Key"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

    post:
      summary: post global settings
      operationId: setGlobal
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/Key"
      requestBody:
        description: value set
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                value: {}

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings_u/ruff_config:
    get:
      summary: get instance ruff config (unauthenticated)
      description: |
        Returns the instance-level ruff.toml content as plain text.
        Intentionally unauthenticated so the LSP extra container can poll it
        across any deployment topology. Responds with an empty body when the
        instance config is unset. Ruff configuration is lint/format policy,
        not a credential.
      operationId: getRuffConfig
      tags:
        - setting
      responses:
        "200":
          description: ruff.toml content (may be empty)
          content:
            text/plain:
              schema:
                type: string

  /settings/local:
    get:
      summary: get local settings
      operationId: getLocal
      tags:
        - setting
      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /settings/test_smtp:
    post:
      summary: test smtp
      operationId: testSmtp
      tags:
        - setting
      requestBody:
        description: test smtp payload
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                to:
                  type: string
                smtp:
                  type: object
                  properties:
                    host:
                      type: string
                    username:
                      type: string
                    password:
                      type: string
                    port:
                      type: integer
                    from:
                      type: string
                    tls_implicit:
                      type: boolean
                    disable_tls:
                      type: boolean
                  required:
                    - host
                    - username
                    - password
                    - port
                    - from
                    - tls_implicit
                    - disable_tls
              required:
                - to
                - smtp
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings/test_critical_channels:
    post:
      summary: test critical channels
      operationId: testCriticalChannels
      tags:
        - setting
      requestBody:
        description: test critical channel payload
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                properties:
                  email:
                    type: string
                  slack_channel:
                    type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings/critical_alerts:
    get:
      summary: Get all critical alerts
      operationId: getCriticalAlerts
      tags:
        - setting
      parameters:
        - in: query
          name: page
          schema:
            type: integer
            default: 1
            description: The page number to retrieve (minimum value is 1)
        - in: query
          name: page_size
          schema:
            type: integer
            default: 10
            maximum: 100
            description: Number of alerts per page (maximum is 100)
        - in: query
          name: acknowledged
          schema:
            type: boolean
            nullable: true
            description: Filter by acknowledgment status; true for acknowledged, false for unacknowledged, and omit for all alerts
      responses:
        "200":
          description: Successfully retrieved all critical alerts
          content:
            application/json:
              schema:
                type: object
                properties:
                  alerts:
                    type: array
                    items:
                      $ref: "#/components/schemas/CriticalAlert"
                  total_rows:
                    type: integer
                    description: Total number of rows matching the query.
                    example: 100
                  total_pages:
                    type: integer
                    description: Total number of pages based on the page size.
                    example: 10

  /settings/critical_alerts/{id}/acknowledge:
    post:
      summary: Acknowledge a critical alert
      operationId: acknowledgeCriticalAlert
      tags:
        - setting
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: The ID of the critical alert to acknowledge
      responses:
        "200":
          description: Successfully acknowledged the critical alert
          content:
            application/json:
              schema:
                type: string
                example: "Critical alert acknowledged"

  /settings/critical_alerts/acknowledge_all:
    post:
      summary: Acknowledge all unacknowledged critical alerts
      operationId: acknowledgeAllCriticalAlerts
      tags:
        - setting
      responses:
        "200":
          description: Successfully acknowledged all unacknowledged critical alerts.
          content:
            application/json:
              schema:
                type: string
                example: "All unacknowledged critical alerts acknowledged"

  /settings/test_license_key:
    post:
      summary: test license key
      operationId: testLicenseKey
      tags:
        - setting
      requestBody:
        description: test license key
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                license_key:
                  type: string
              required:
                - license_key
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

    # pub use_ssl: Option<bool>,
    # #[serde(rename = "accountName")]
    # pub account_name: String,
    # #[serde(rename = "tenantId")]
    # pub tenant_id: Option<String>,
    # #[serde(rename = "clientId")]
    # pub client_id: Option<String>,
    # #[serde(rename = "containerName")]
    # pub container_name: String,
    # #[serde(rename = "accessKey")]
    # pub access_key: Option<String>,

  /settings/test_object_storage_config:
    post:
      summary: test object storage config
      operationId: testObjectStorageConfig
      tags:
        - setting
      requestBody:
        description: test object storage config
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings/object_storage_usage:
    get:
      summary: get current or last object storage usage computation (null if never run)
      operationId: getObjectStorageUsage
      tags:
        - setting
      responses:
        "200":
          description: current or last storage-usage computation state
          content:
            application/json:
              schema:
                nullable: true
                type: object
                properties:
                  running:
                    type: boolean
                  started_at:
                    type: string
                    format: date-time
                  finished_at:
                    type: string
                    format: date-time
                    nullable: true
                  current_prefix:
                    type: string
                    nullable: true
                  scanned_objects:
                    type: integer
                    format: int64
                  folders:
                    type: array
                    items:
                      type: object
                      properties:
                        prefix:
                          type: string
                        size:
                          type: integer
                          format: int64
                        partial:
                          type: boolean
                      required:
                        - prefix
                        - size
                  error:
                    type: string
                    nullable: true
                required:
                  - running
                  - started_at
                  - scanned_objects
                  - folders
    post:
      summary: start a background computation of object storage usage by top-level folder
      operationId: computeObjectStorageUsage
      tags:
        - setting
      responses:
        "202":
          description: computation started
          content:
            text/plain:
              schema:
                type: string

  /settings/run_log_cleanup:
    post:
      summary: start a manual cleanup of expired logs from object storage
      operationId: runLogCleanup
      tags:
        - setting
      responses:
        "202":
          description: cleanup started
          content:
            text/plain:
              schema:
                type: string

  /settings/log_cleanup_status:
    get:
      summary: get status of the manual log cleanup task
      operationId: getLogCleanupStatus
      tags:
        - setting
      responses:
        "200":
          description: current or last log cleanup status (null if never run)
          content:
            application/json:
              schema:
                nullable: true
                type: object
                properties:
                  running:
                    type: boolean
                  started_at:
                    type: string
                    format: date-time
                  finished_at:
                    type: string
                    format: date-time
                    nullable: true
                  phase:
                    type: string
                  total_service:
                    type: integer
                    format: int64
                  processed_service:
                    type: integer
                    format: int64
                  total_jobs:
                    type: integer
                    format: int64
                  processed_jobs:
                    type: integer
                    format: int64
                  s3_deleted:
                    type: integer
                    format: int64
                  s3_not_found:
                    type: integer
                    format: int64
                  orphans_scanned:
                    type: integer
                    format: int64
                  orphans_deleted:
                    type: integer
                    format: int64
                  errors:
                    type: integer
                    format: int64
                  last_error:
                    type: string
                    nullable: true
                required:
                  - running
                  - started_at
                  - phase
                  - total_service
                  - processed_service
                  - total_jobs
                  - processed_jobs
                  - s3_deleted
                  - orphans_scanned
                  - orphans_deleted
                  - errors

  /settings/audit_logs_s3_status:
    get:
      summary: get status of the audit-log object-store export cursor
      operationId: getAuditLogsS3Status
      tags:
        - setting
      responses:
        "200":
          description: current export status (null if the feature was never enabled)
          content:
            application/json:
              schema:
                nullable: true
                type: object
                properties:
                  last_xmin:
                    type: integer
                    format: int64
                  last_ts:
                    type: string
                    format: date-time
                    nullable: true
                  bootstrapping:
                    type: boolean
                  last_exported_audit_ts:
                    type: string
                    format: date-time
                    nullable: true
                  last_run_at:
                    type: string
                    format: date-time
                    nullable: true
                  last_run_exported:
                    type: integer
                    format: int64
                  updated_at:
                    type: string
                    format: date-time
                  owner:
                    type: string
                    nullable: true
                required:
                  - last_xmin
                  - bootstrapping
                  - last_run_exported
                  - updated_at

  /settings/audit_logs_s3_backfill:
    post:
      summary: start an opt-in historical backfill of audit logs to object storage
      operationId: runAuditLogsS3Backfill
      tags:
        - setting
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                from:
                  type: string
                  format: date-time
                  description: inclusive lower bound of the window to export
                to:
                  type: string
                  format: date-time
                  description: exclusive upper bound of the window to export
              required:
                - from
                - to
      responses:
        "202":
          description: backfill started

  /settings/audit_logs_s3_backfill_status:
    get:
      summary: get status of the audit-log object-store historical backfill
      operationId: getAuditLogsS3BackfillStatus
      tags:
        - setting
      responses:
        "200":
          description: current backfill status (null if never run)
          content:
            application/json:
              schema:
                nullable: true
                type: object
                properties:
                  running:
                    type: boolean
                  started_at:
                    type: string
                    format: date-time
                  finished_at:
                    type: string
                    format: date-time
                    nullable: true
                  phase:
                    type: string
                  from:
                    type: string
                    format: date-time
                  to:
                    type: string
                    format: date-time
                  rows_written:
                    type: integer
                    format: int64
                  objects_written:
                    type: integer
                    format: int64
                  last_ts:
                    type: string
                    format: date-time
                    nullable: true
                  errors:
                    type: integer
                    format: int64
                  last_error:
                    type: string
                    nullable: true
                required:
                  - running
                  - started_at
                  - phase
                  - from
                  - to
                  - rows_written
                  - objects_written
                  - errors

  /settings/send_stats:
    post:
      summary: send stats
      operationId: sendStats
      tags:
        - setting
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings/restart_worker_group/{worker_group}:
    post:
      summary: restart worker group
      description: Send a restart signal to all workers in the specified worker group. Workers will gracefully shut down and are expected to be restarted by their supervisor. Requires devops role.
      operationId: restartWorkerGroup
      tags:
        - setting
      parameters:
        - name: worker_group
          in: path
          required: true
          schema:
            type: string
          description: the name of the worker group to restart
      responses:
        "200":
          description: restart signal sent
          content:
            text/plain:
              schema:
                type: string

  /settings/get_stats:
    get:
      summary: get telemetry stats with HMAC signature (EE only)
      operationId: getStats
      tags:
        - setting
      responses:
        "200":
          description: telemetry stats JSON with signature
          content:
            application/json:
              schema:
                type: object
                properties:
                  signature:
                    type: string
                  data:
                    type: string

  /settings/latest_key_renewal_attempt:
    get:
      summary: get latest key renewal attempt
      operationId: getLatestKeyRenewalAttempt
      tags:
        - setting
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  result:
                    type: string
                  attempted_at:
                    type: string
                    format: date-time
                required:
                  - result
                  - attempted_at
                nullable: true

  /settings/renew_license_key:
    post:
      summary: renew license key
      operationId: renewLicenseKey
      tags:
        - setting
      parameters:
        - name: license_key
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings/offline_license_status:
    get:
      summary: get cap-usage status for the currently-loaded offline license
      description: |
        Returns the live cap status (seats used vs cap, current CU vs cap) for
        the offline license key currently in use. Returns `null` if no offline
        license is loaded. Super-admin only.
      operationId: getOfflineLicenseStatus
      tags:
        - setting
      responses:
        "200":
          description: cap status (or null when no offline license)
          content:
            application/json:
              schema:
                type: object
                nullable: true
                properties:
                  seats_used:
                    type: number
                    description: Author-equivalent seats consumed (authors + 0.5 × operators)
                  seats_cap:
                    type: integer
                  author_count:
                    type: integer
                  operator_count:
                    type: integer
                  current_cu:
                    type: number
                    description: Sum of CU rate across workers that pinged in the last 2 minutes.
                  cu_cap:
                    type: number
                  cu_over_cap:
                    type: boolean

  /settings/instance_hash:
    get:
      summary: per-instance binding hash for offline license issuance
      description: |
        Returns the hash a superadmin shares with Windmill support when
        requesting an offline license. Super-admin only.
      operationId: getInstanceHash
      tags:
        - setting
      responses:
        '200':
          description: instance hash
          content:
            application/json:
              schema:
                type: object
                properties:
                  instance_hash:
                    type: string
                    nullable: true

  /settings/customer_portal:
    post:
      summary: create customer portal session
      operationId: createCustomerPortalSession
      tags:
        - setting
      parameters:
        - name: license_key
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: url to portal
          content:
            text/plain:
              schema:
                type: string

  /saml/test_metadata:
    post:
      summary: test metadata
      operationId: testMetadata
      tags:
        - setting
      requestBody:
        description: test metadata
        required: true
        content:
          application/json:
            schema:
              type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /settings/list_global:
    get:
      summary: list global settings
      operationId: listGlobalSettings
      tags:
        - setting
      responses:
        "200":
          description: list of settings
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/GlobalSetting"

  /settings/instance_config:
    get:
      summary: get full instance config (global settings + worker configs)
      operationId: getInstanceConfig
      tags:
        - setting
      responses:
        "200":
          description: full instance configuration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InstanceConfig"
    put:
      summary: update instance config (bulk upsert, no deletes). Empty or missing global_settings/worker_configs are skipped.
      operationId: setInstanceConfig
      tags:
        - setting
      requestBody:
        description: full instance configuration to apply
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InstanceConfig"
      responses:
        "200":
          description: instance config updated
          content:
            text/plain:
              schema:
                type: string

  /min_keep_alive_version:
    get:
      summary: get minimum worker versions required to stay alive
      operationId: getMinKeepAliveVersion
      tags:
        - setting
      responses:
        "200":
          description: minimum keep-alive versions for workers and agents
          content:
            application/json:
              schema:
                type: object
                required:
                  - worker
                  - agent
                properties:
                  worker:
                    type: string
                    description: minimum version for normal workers
                  agent:
                    type: string
                    description: minimum version for agent workers

  /.well-known/jwks.json:
    get:
      summary: get JWKS for Vault JWT authentication
      operationId: getJwks
      tags:
        - setting
      responses:
        "200":
          description: JSON Web Key Set
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JwksResponse"

  /settings/test_secret_backend:
    post:
      summary: test secret backend connection (HashiCorp Vault)
      operationId: testSecretBackend
      tags:
        - setting
      requestBody:
        description: Vault settings to test
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VaultSettings"
      responses:
        "200":
          description: connection successful
          content:
            text/plain:
              schema:
                type: string

  /settings/migrate_secrets_to_vault:
    post:
      summary: migrate secrets from database to HashiCorp Vault
      operationId: migrateSecretsToVault
      tags:
        - setting
      requestBody:
        description: Vault settings for migration target
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VaultSettings"
      responses:
        "200":
          description: migration report
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SecretMigrationReport"

  /settings/migrate_secrets_to_database:
    post:
      summary: migrate secrets from HashiCorp Vault to database
      operationId: migrateSecretsToDatabase
      tags:
        - setting
      requestBody:
        description: Vault settings for migration source
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VaultSettings"
      responses:
        "200":
          description: migration report
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SecretMigrationReport"

  /settings/test_azure_kv_backend:
    post:
      summary: test Azure Key Vault connection
      operationId: testAzureKvBackend
      tags:
        - setting
      requestBody:
        description: Azure Key Vault settings to test
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureKeyVaultSettings"
      responses:
        "200":
          description: connection successful
          content:
            text/plain:
              schema:
                type: string

  /settings/migrate_secrets_to_azure_kv:
    post:
      summary: migrate secrets from database to Azure Key Vault
      operationId: migrateSecretsToAzureKv
      tags:
        - setting
      requestBody:
        description: Azure Key Vault settings for migration target
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureKeyVaultSettings"
      responses:
        "200":
          description: migration report
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SecretMigrationReport"

  /settings/migrate_secrets_from_azure_kv:
    post:
      summary: migrate secrets from Azure Key Vault to database
      operationId: migrateSecretsFromAzureKv
      tags:
        - setting
      requestBody:
        description: Azure Key Vault settings for migration source
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureKeyVaultSettings"
      responses:
        "200":
          description: migration report
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SecretMigrationReport"

  /settings/test_aws_sm_backend:
    post:
      summary: test connection to AWS Secrets Manager
      operationId: testAwsSmBackend
      tags:
        - setting
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AwsSecretsManagerSettings"
      responses:
        "200":
          description: connection test result
          content:
            text/plain:
              schema:
                type: string

  /settings/migrate_secrets_to_aws_sm:
    post:
      summary: migrate secrets from database to AWS Secrets Manager
      operationId: migrateSecretsToAwsSm
      tags:
        - setting
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AwsSecretsManagerSettings"
      responses:
        "200":
          description: migration report
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SecretMigrationReport"

  /settings/migrate_secrets_from_aws_sm:
    post:
      summary: migrate secrets from AWS Secrets Manager to database
      operationId: migrateSecretsFromAwsSm
      tags:
        - setting
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AwsSecretsManagerSettings"
      responses:
        "200":
          description: migration report
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SecretMigrationReport"

  /users/email:
    get:
      summary: get current user email (if logged in)
      operationId: getCurrentEmail
      tags:
        - user
      responses:
        "200":
          description: user email
          content:
            text/plain:
              schema:
                type: string

  /users/refresh_token:
    get:
      summary: refresh the current token
      operationId: refreshUserToken
      tags:
        - user
      parameters:
        - name: if_expiring_in_less_than_s
          in: query
          required: false
          schema:
            type: integer
      responses:
        "200":
          description: new token
          content:
            text/plain:
              schema:
                type: string

  /users/tutorial_progress:
    get:
      summary: get tutorial progress
      operationId: getTutorialProgress
      tags:
        - user
      responses:
        "200":
          description: tutorial progress
          content:
            application/json:
              schema:
                type: object
                properties:
                  progress:
                    type: integer
                  skipped_all:
                    type: boolean
    post:
      summary: update tutorial progress
      operationId: updateTutorialProgress
      tags:
        - user
      requestBody:
        description: progress update
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                progress:
                  type: integer
                skipped_all:
                  type: boolean
      responses:
        "200":
          description: tutorial progress
          content:
            text/plain:
              schema:
                type: string

  /users/leave_instance:
    post:
      summary: leave instance
      operationId: leaveInstance
      tags:
        - user
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /users/usage:
    get:
      summary: get current usage outside of premium workspaces
      operationId: getUsage
      tags:
        - user
      responses:
        "200":
          description: free usage
          content:
            text/plain:
              schema:
                type: number

  /users/all_runnables:
    get:
      summary: get all runnables in every workspace
      operationId: getRunnable
      tags:
        - user
      responses:
        "200":
          description: free all runnables
          content:
            application/json:
              schema:
                type: object
                properties:
                  workspace:
                    type: string
                  endpoint_async:
                    type: string
                  endpoint_sync:
                    type: string
                  summary:
                    type: string
                  description:
                    type: string
                  kind:
                    type: string
                required:
                  - workspace
                  - endpoint_async
                  - endpoint_sync
                  - summary
                  - kind

  /users/whoami:
    get:
      summary: get current global whoami (if logged in)
      operationId: globalWhoami
      tags:
        - user
      responses:
        "200":
          description: user email
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GlobalUserInfo"

  /users/list_invites:
    get:
      summary: list all workspace invites
      operationId: listWorkspaceInvites
      tags:
        - user
      responses:
        "200":
          description: list all workspace invites
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WorkspaceInvite"

  /w/{workspace}/users/whoami:
    get:
      summary: whoami
      operationId: whoami
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /w/{workspace}/github_app/token:
    post:
      summary: get github app token
      operationId: getGithubAppToken
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: jwt job token
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                job_token:
                  type: string
              required:
                - job_token
      responses:
        "200":
          description: github app token
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                required:
                  - token

  /w/{workspace}/github_app/install_from_workspace:
    post:
      tags:
        - Git Sync
      summary: Install a GitHub installation from another workspace
      operationId: installFromWorkspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                source_workspace_id:
                  type: string
                  description: The ID of the workspace containing the installation to copy
                installation_id:
                  type: number
                  description: The ID of the GitHub installation to copy
              required:
                - source_workspace_id
                - installation_id
      responses:
        "200":
          description: Installation successfully copied

  /w/{workspace}/github_app/installation/{installation_id}:
    delete:
      summary: Delete a GitHub installation from a workspace
      operationId: deleteFromWorkspace
      description: Removes a GitHub installation from the specified workspace. Requires admin privileges.
      tags:
        - Git Sync
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: installation_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
          description: The ID of the GitHub installation to delete
      responses:
        "200":
          description: Installation successfully deleted

  /w/{workspace}/github_app/export/{installationId}:
    get:
      summary: Export GitHub installation JWT token
      description: Exports the JWT token for a specific GitHub installation in the workspace
      operationId: exportInstallation
      tags:
        - Git Sync
      parameters:
        - name: workspace
          in: path
          required: true
          schema:
            type: string
        - name: installationId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Successfully exported the JWT token
          content:
            application/json:
              schema:
                type: object
                properties:
                  jwt_token:
                    type: string

  /w/{workspace}/github_app/import:
    post:
      summary: Import GitHub installation from JWT token
      description: Imports a GitHub installation from a JWT token exported from another instance
      operationId: importInstallation
      tags:
        - Git Sync
      parameters:
        - name: workspace
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - jwt_token
              properties:
                jwt_token:
                  type: string
      responses:
        "200":
          description: Successfully imported the installation

  /w/{workspace}/github_app/ghes_installation_callback:
    post:
      summary: GHES installation callback
      description: Register a self-managed GitHub App installation from GitHub Enterprise Server
      operationId: ghesInstallationCallback
      tags:
        - Git Sync
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - installation_id
              properties:
                installation_id:
                  type: integer
                  format: int64
                  description: The GitHub App installation ID from GHES
      responses:
        "200":
          description: GHES installation registered successfully

  /github_app/ghes_config:
    get:
      summary: Get GHES app config
      description: Returns the GitHub Enterprise Server app configuration (without private key) for constructing the installation URL
      operationId: getGhesConfig
      tags:
        - Git Sync
      responses:
        "200":
          description: GHES app configuration
          content:
            application/json:
              schema:
                type: object
                properties:
                  base_url:
                    type: string
                  app_slug:
                    type: string
                  client_id:
                    type: string
                  app_owner:
                    type: string
                    nullable: true
                required:
                  - base_url
                  - app_slug
                  - client_id

  /github_app/ghes/discover:
    get:
      summary: Discover GHES App installations
      description: |
        Lists every installation the configured self-managed GitHub App can see,
        annotated with the workspaces in this Windmill instance the
        installation is currently assigned to. Super-admin only.
      operationId: discoverGhesInstallations
      tags:
        - Git Sync
      responses:
        "200":
          description: Discovered installations
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - installation_id
                    - account_id
                    - assigned_workspaces
                  properties:
                    installation_id:
                      type: integer
                      format: int64
                    account_id:
                      type: string
                      description: GitHub login of the installation's account (org or user)
                    assigned_workspaces:
                      type: array
                      items:
                        type: object
                        required:
                          - workspace_id
                          - provisioned_by_admin
                        properties:
                          workspace_id:
                            type: string
                          provisioned_by_admin:
                            type: boolean

  /github_app/ghes/assign:
    post:
      summary: Assign GHES installation to a workspace
      description: |
        Assigns a discovered GHES App installation to a workspace. The resulting
        installation is marked as admin-provisioned, so workspace admins cannot
        remove it. Super-admin only.
      operationId: assignGhesInstallation
      tags:
        - Git Sync
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - workspace_id
                - installation_id
              properties:
                workspace_id:
                  type: string
                installation_id:
                  type: integer
                  format: int64
      responses:
        "200":
          description: Installation assigned

  /github_app/ghes/assign/{workspace_id}/{installation_id}:
    delete:
      summary: Unassign GHES installation from a workspace
      description: |
        Removes an installation (admin-provisioned or otherwise) from a
        workspace. Super-admin only. Does not affect the installation on the
        GitHub side.
      operationId: unassignGhesInstallation
      tags:
        - Git Sync
      parameters:
        - name: workspace_id
          in: path
          required: true
          schema:
            type: string
        - name: installation_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: Installation unassigned

  /users/accept_invite:
    post:
      summary: accept invite to workspace
      operationId: acceptInvite
      tags:
        - user
      requestBody:
        description: accept invite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                workspace_id:
                  type: string
                username:
                  type: string
              required:
                - workspace_id
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /users/decline_invite:
    post:
      summary: decline invite to workspace
      operationId: declineInvite
      tags:
        - user
      requestBody:
        description: decline invite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                workspace_id:
                  type: string
              required:
                - workspace_id
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/invite_user:
    post:
      summary: invite user to workspace
      operationId: inviteUser
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceInvite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                is_admin:
                  type: boolean
                operator:
                  type: boolean
                parent_workspace_id:
                  type: string
                  nullable: true
              required:
                - email
                - is_admin
                - operator
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/add_user:
    post:
      summary: add user to workspace (require admin privilege, except for the creator of a fork adding a developer/admin of its parent workspace as a developer of the fork)
      operationId: addUser
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceInvite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                is_admin:
                  type: boolean
                username:
                  type: string
                operator:
                  type: boolean
              required:
                - email
                - is_admin
                - operator
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/create_service_account:
    post:
      summary: create a service account
      operationId: createServiceAccount
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
                is_admin:
                  type: boolean
                  description: Grant the service account workspace admin. Defaults to false. Cannot be combined with operator=true.
                operator:
                  type: boolean
                  description: Make the service account an operator. Defaults to true for backward compatibility. Set to false to count as a developer (1 seat) instead of 0.5 seat.
                add_to_deployers:
                  type: boolean
                  description: Add the service account to the workspace `wm_deployers` group on creation. Recommended when the account will be used as a CLI sync / CI deploy identity so it can deploy on behalf of other users.
              required:
                - username
      responses:
        "201":
          description: service account created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/users/impersonate_service_account:
    post:
      summary: impersonate a service account
      operationId: impersonateServiceAccount
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
              required:
                - username
      responses:
        "201":
          description: impersonation token
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/users/exit_impersonation:
    post:
      summary: exit service account impersonation
      operationId: exitImpersonation
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                token:
                  type: string
              required:
                - token
      responses:
        "200":
          description: exited impersonation
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/delete_invite:
    post:
      summary: delete user invite
      operationId: delete invite
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceInvite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                is_admin:
                  type: boolean
                operator:
                  type: boolean
              required:
                - email
                - is_admin
                - operator
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/archive:
    post:
      summary: archive workspace
      operationId: archiveWorkspace
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /workspaces/unarchive/{workspace}:
    post:
      summary: unarchive workspace
      operationId: unarchiveWorkspace
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /workspaces/delete/{workspace}:
    delete:
      summary: delete workspace (require super admin)
      operationId: deleteWorkspace
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: only_delete_forks
          in: query
          required: false
          schema:
            type: boolean
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/leave:
    post:
      summary: leave workspace
      operationId: leaveWorkspace
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/get_workspace_name:
    get:
      summary: get workspace name
      operationId: getWorkspaceName
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/change_workspace_name:
    post:
      summary: change workspace name
      operationId: changeWorkspaceName
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                new_name:
                  type: string
              required:
                - username
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/change_workspace_id:
    post:
      summary: change workspace id
      operationId: changeWorkspaceId
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                new_id:
                  type: string
                new_name:
                  type: string
              required:
                - username
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/change_workspace_color:
    post:
      summary: change workspace id
      operationId: changeWorkspaceColor
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                color:
                  type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/users/whois/{username}:
    get:
      summary: whois
      operationId: whois
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /w/{workspace}/workspaces/operator_settings:
    post:
      operationId: updateOperatorSettings
      summary: Update operator settings for a workspace
      description: Updates the operator settings for a specific workspace. Requires workspace admin privileges.
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OperatorSettings"
      responses:
        "200":
          description: Operator settings updated successfully
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/compare/{target_workspace_id}:
    get:
      operationId: compareWorkspaces
      summary: Compare two workspaces
      description: Compares the current workspace with a target workspace to find differences in scripts, flows, apps, resources, and variables. Returns information about items that are ahead, behind, or in conflict.
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: target_workspace_id
          in: path
          required: true
          schema:
            type: string
          description: The ID of the workspace to compare with
      responses:
        "200":
          description: Workspace comparison results
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkspaceComparison"

  /w/{workspace}/workspaces/reset_diff_tally/{fork_workspace_id}:
    post:
      operationId: resetDiffTally
      summary: Resets the ahead and behind deployement counter after a deployement
      description: This endpoint should be called after a fork deployement
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: fork_workspace_id
          in: path
          required: true
          schema:
            type: string
          description: The ID of the workspace to compare with

      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /users/exists/{email}:
    get:
      summary: exists email
      operationId: existsEmail
      tags:
        - user
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                type: boolean

  /users/list_as_super_admin:
    get:
      summary: list all users as super admin (require to be super amdin)
      operationId: listUsersAsSuperAdmin
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: active_only
          in: query
          description: filter only active users
          schema:
            type: boolean
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/GlobalUserInfo"

  /w/{workspace}/workspaces/list_pending_invites:
    get:
      summary: list pending invites for a workspace
      operationId: listPendingInvites
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WorkspaceInvite"

  /w/{workspace}/workspaces/get_public_settings:
    get:
      summary: get public settings
      description: Returns the subset of workspace settings safe to expose to any workspace member. The full settings struct is admin-only via `getSettings`.
      operationId: getPublicSettings
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  workspace_id:
                    type: string
                  slack_name:
                    type: string
                  slack_team_id:
                    type: string
                  teams_team_id:
                    type: string
                  teams_team_name:
                    type: string
                  teams_team_guid:
                    type: string
                  large_file_storage:
                    $ref: "#/components/schemas/LargeFileStorage"
                  datatable:
                    $ref: "#/components/schemas/DataTableSettings"
                  deploy_ui:
                    $ref: "#/components/schemas/WorkspaceDeployUISettings"
                  mute_critical_alerts:
                    type: boolean
                required:
                  - workspace_id

  /w/{workspace}/workspaces/get_settings:
    get:
      summary: get settings (admin only)
      description: Returns the full workspace settings including admin-managed integration credentials. Admin-only — non-admin callers should use `getPublicSettings`.
      operationId: getSettings
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  workspace_id:
                    type: string
                  slack_name:
                    type: string
                  slack_team_id:
                    type: string
                  slack_command_script:
                    type: string
                  slack_oauth_client_id:
                    type: string
                  slack_oauth_client_secret:
                    type: string
                  teams_team_id:
                    type: string
                  teams_command_script:
                    type: string
                  teams_team_name:
                    type: string
                  teams_team_guid:
                    type: string
                  auto_invite:
                    $ref: "#/components/schemas/AutoInviteConfig"
                  plan:
                    type: string
                  customer_id:
                    type: string
                  webhook:
                    type: string
                  deploy_to:
                    type: string
                  ai_config:
                    $ref: "#/components/schemas/AIConfig"
                  error_handler:
                    $ref: "#/components/schemas/ErrorHandlerConfig"
                  success_handler:
                    $ref: "#/components/schemas/SuccessHandlerConfig"
                  large_file_storage:
                    $ref: "#/components/schemas/LargeFileStorage"
                  ducklake:
                    $ref: "#/components/schemas/DucklakeSettings"
                  datatable:
                    $ref: "#/components/schemas/DataTableSettings"
                  git_sync:
                    $ref: "#/components/schemas/WorkspaceGitSyncSettings"
                  deploy_ui:
                    $ref: "#/components/schemas/WorkspaceDeployUISettings"
                  default_app:
                    type: string
                  default_scripts:
                    $ref: "#/components/schemas/WorkspaceDefaultScripts"
                  mute_critical_alerts:
                    type: boolean
                  color:
                    type: string
                  operator_settings:
                    $ref: "#/components/schemas/OperatorSettings"
                  public_app_execution_limit_per_minute:
                    type: integer
                    description: Rate limit for public app executions per minute per server. NULL or 0 means disabled.

  /w/{workspace}/workspaces/get_deploy_to:
    get:
      summary: get deploy to
      operationId: getDeployTo
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  deploy_to:
                    type: string

  /w/{workspace}/workspaces/is_premium:
    get:
      summary: get if workspace is premium
      operationId: getIsPremium
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/workspaces/premium_info:
    get:
      summary: get premium info
      operationId: getPremiumInfo
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: skip_subscription_fetch
          in: query
          description: skip fetching subscription status from stripe
          schema:
            type: boolean

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  premium:
                    type: boolean
                  usage:
                    type: number
                  owner:
                    type: string
                  status:
                    type: string
                  is_past_due:
                    type: boolean
                  max_tolerated_executions:
                    type: number
                required:
                  - premium
                  - owner
                  - is_past_due

  /w/{workspace}/workspaces/threshold_alert:
    get:
      summary: get threshold alert info
      operationId: getThresholdAlert
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  threshold_alert_amount:
                    type: number
                  last_alert_sent:
                    type: string
                    format: date-time
    post:
      summary: set threshold alert info
      operationId: setThresholdAlert
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: threshold alert info
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                threshold_alert_amount:
                  type: number

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/rebuild_dependency_map:
    post:
      summary: rebuild dependency map
      operationId: rebuildDependencyMap
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string
  /w/{workspace}/workspaces/get_dependents/{imported_path}:
    get:
      summary: get dependents of an imported path
      operationId: getDependents
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: imported_path
          in: path
          required: true
          schema:
            type: string
          description: The imported path to get dependents for
      responses:
        "200":
          description: list of dependents
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DependencyDependent"

  /w/{workspace}/workspaces/get_imports/{importer_path}:
    get:
      summary: get script imports for an importer path
      operationId: getImports
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: importer_path
          in: path
          required: true
          schema:
            type: string
          description: The script path to get imports for
      responses:
        "200":
          description: list of imported script paths
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/workspaces/get_dependents_amounts:
    post:
      summary: get dependents amounts for multiple imported paths
      operationId: getDependentsAmounts
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: List of imported paths to get dependents counts for
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: string
      responses:
        "200":
          description: list of dependents amounts
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DependentsAmount"

  /w/{workspace}/workspaces/get_dependency_map:
    get:
      summary: get dependency map
      operationId: getDependencyMap
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: dmap
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DependencyMap"

  /w/{workspace}/workspaces/edit_slack_command:
    post:
      summary: edit slack command
      operationId: editSlackCommand
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceInvite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                slack_command_script:
                  type: string

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/slack_oauth_config:
    get:
      summary: get workspace slack oauth config
      operationId: getWorkspaceSlackOauthConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: slack oauth config
          content:
            application/json:
              schema:
                type: object
                properties:
                  slack_oauth_client_id:
                    type: string
                    nullable: true
                  slack_oauth_client_secret:
                    type: string
                    nullable: true
                    description: Masked with *** if set
    post:
      summary: set workspace slack oauth config
      operationId: setWorkspaceSlackOauthConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Slack OAuth Configuration
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - slack_oauth_client_id
                - slack_oauth_client_secret
              properties:
                slack_oauth_client_id:
                  type: string
                slack_oauth_client_secret:
                  type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string
    delete:
      summary: delete workspace slack oauth config
      operationId: deleteWorkspaceSlackOauthConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/edit_teams_command:
    post:
      summary: edit teams command
      operationId: editTeamsCommand
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceInvite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                slack_command_script:
                  type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/available_teams_ids:
    get:
      summary: list available teams ids
      operationId: listAvailableTeamsIds
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: search
          in: query
          description: Search teams by name. If omitted, returns first page of all teams.
          required: false
          schema:
            type: string
        - name: next_link
          in: query
          description: Pagination cursor URL from previous response. Pass this to fetch the next page of results.
          required: false
          schema:
            type: string
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  teams:
                    type: array
                    items:
                      type: object
                      properties:
                        team_name:
                          type: string
                        team_id:
                          type: string
                  total_count:
                    type: integer
                    description: Total number of teams across all pages
                  per_page:
                    type: integer
                    description: Number of teams per page (configurable via TEAMS_PER_PAGE env var)
                  next_link:
                    type: string
                    nullable: true
                    description: URL to fetch next page of results. Null if no more pages.

  /w/{workspace}/workspaces/available_teams_channels:
    get:
      summary: list available channels for a specific team
      operationId: listAvailableTeamsChannels
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: team_id
          in: query
          description: Microsoft Teams team ID
          required: true
          schema:
            type: string
      responses:
        "200":
          description: List of channels for the specified team
          content:
            application/json:
              schema:
                type: object
                properties:
                  channels:
                    type: array
                    items:
                      type: object
                      properties:
                        channel_name:
                          type: string
                        channel_id:
                          type: string
                  total_count:
                    type: integer

  /w/{workspace}/workspaces/connect_teams:
    post:
      summary: connect teams
      operationId: connectTeams
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: connect teams
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                team_id:
                  type: string
                team_name:
                  type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/connect_slack:
    post:
      summary: connect slack (non-interactive; pre-minted bot token)
      operationId: connectSlack
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: connect slack with a pre-minted bot token
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - bot_token
                - team_id
                - team_name
              properties:
                bot_token:
                  type: string
                  description: xoxb-... bot token obtained at api.slack.com/apps
                team_id:
                  type: string
                team_name:
                  type: string
      responses:
        "200":
          description: status

  /w/{workspace}/workspaces/run_slack_message_test_job:
    post:
      summary: run a job that sends a message to Slack
      operationId: runSlackMessageTestJob
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: path to hub script to run and its corresponding args
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                hub_script_path:
                  type: string
                channel:
                  type: string
                test_msg:
                  type: string

      responses:
        "200":
          description: status
          content:
            text/json:
              schema:
                type: object
                properties:
                  job_uuid:
                    type: string

  /w/{workspace}/workspaces/run_teams_message_test_job:
    post:
      summary: run a job that sends a message to Teams
      operationId: runTeamsMessageTestJob
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: path to hub script to run and its corresponding args
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                hub_script_path:
                  type: string
                channel:
                  type: string
                test_msg:
                  type: string

      responses:
        "200":
          description: status
          content:
            text/json:
              schema:
                type: object
                properties:
                  job_uuid:
                    type: string

  /w/{workspace}/workspaces/edit_deploy_to:
    post:
      summary: edit deploy to
      operationId: editDeployTo
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                deploy_to:
                  type: string

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/edit_auto_invite:
    post:
      summary: edit auto invite
      operationId: editAutoInvite
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceInvite
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                operator:
                  type: boolean
                invite_all:
                  type: boolean
                auto_add:
                  type: boolean

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/edit_instance_groups:
    post:
      summary: edit instance groups
      operationId: editInstanceGroups
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Instance Groups Configuration
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                groups:
                  type: array
                  items:
                    type: string
                roles:
                  type: object
                  additionalProperties:
                    type: string

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/edit_webhook:
    post:
      summary: edit webhook
      operationId: editWebhook
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceWebhook
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                webhook:
                  type: string

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/edit_copilot_config:
    post:
      summary: edit copilot config
      operationId: editCopilotConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceCopilotConfig
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AIConfig"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  effective_ai_config:
                    $ref: "#/components/schemas/AIConfig"
                  has_instance_ai_config:
                    type: boolean
                  uses_instance_ai_config:
                    type: boolean
                  instance_ai_summary:
                    $ref: "#/components/schemas/InstanceAISummary"
                required:
                  - effective_ai_config
                  - has_instance_ai_config
                  - uses_instance_ai_config

  /w/{workspace}/workspaces/get_copilot_settings_state:
    get:
      summary: get copilot settings state
      operationId: getCopilotSettingsState
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  has_instance_ai_config:
                    type: boolean
                  uses_instance_ai_config:
                    type: boolean
                  instance_ai_summary:
                    $ref: "#/components/schemas/InstanceAISummary"
                required:
                  - has_instance_ai_config
                  - uses_instance_ai_config

  /w/{workspace}/workspaces/get_copilot_info:
    get:
      summary: get copilot info
      operationId: getCopilotInfo
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AIConfig"

  /w/{workspace}/workspaces/edit_error_handler:
    post:
      summary: edit error handler
      operationId: editErrorHandler
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceErrorHandler
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditErrorHandler"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/edit_success_handler:
    post:
      summary: edit success handler
      operationId: editSuccessHandler
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: WorkspaceSuccessHandler
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditSuccessHandler"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/edit_large_file_storage_config:
    post:
      summary: edit large file storage settings
      operationId: editLargeFileStorageConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: LargeFileStorage info
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                large_file_storage:
                  $ref: "#/components/schemas/LargeFileStorage"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspaces/list_ducklakes:
    get:
      summary: list ducklakes
      operationId: listDucklakes
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/data_metrics/list:
    get:
      summary: list declared measures and dimensions on DuckLake tables
      description: >
        Call this before writing any aggregate query over a DuckLake table. A
        declared measure is the canonical definition of that number, and
        reproducing it yourself will silently disagree with it (a `revenue`
        measure typically excludes refunds or test rows). Filter by `table` for
        one table's declarations, or by `path_prefix` (e.g. `f/analytics`) for
        everything declared under a folder; omit both to browse the whole
        catalog. Results are keyset-paged: a full page may mean more remain, so
        continue with the `cursor_*` params rather than assuming a measure does not exist. Use each returned `expr` verbatim, and when a measure has a
        `filter` write it as
        `expr FILTER (WHERE filter)` so measures with different predicates can
        share one GROUP BY. If a number you need has no declared measure, write
        your own aggregate as usual. Results are limited to declarations whose
        producing script the caller can read.
      operationId: listDataMetrics
      x-mcp-tool: true
      tags:
        - data_metric
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: table
          in: query
          description: DuckLake table path, with or without the `ducklake://` scheme
          schema:
            type: string
        - name: path_prefix
          in: query
          description: Producing script path prefix, e.g. `f/analytics`
          schema:
            type: string
        - name: per_page
          in: query
          description: Results per page, capped at 1000 (default 1000)
          schema:
            type: integer
        - name: cursor_table
          in: query
          description: >
            Keyset cursor. To page, pass the previous response's `next_cursor` fields
            back as `cursor_*`; all four move together, and are omitted for the first
            page. Continue whenever `next_cursor` is present. Every returned row is one
            the caller may read, so the cursor never names a hidden row.
          schema:
            type: string
        - name: cursor_kind
          in: query
          schema:
            type: string
        - name: cursor_name
          in: query
          schema:
            type: string
        - name: cursor_script
          in: query
          schema:
            type: string
      responses:
        "200":
          description: declared measures and dimensions
          content:
            application/json:
              schema:
                type: object
                required: [metrics]
                properties:
                  metrics:
                    type: array
                    items:
                      $ref: "#/components/schemas/DataMetric"
                  next_cursor:
                    description: >
                      Present when more rows may follow: pass its fields back as the
                      `cursor_*` params. Absent means the catalog is exhausted.
                    type: object
                    required: [table_path, kind, name, script_path]
                    properties:
                      table_path:
                        type: string
                      kind:
                        type: string
                      name:
                        type: string
                      script_path:
                        type: string

  /w/{workspace}/workspaces/list_datatables:
    get:
      summary: list Datatables
      operationId: listDataTables
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required: [name, resource_type, resource_path]
                  properties:
                    name:
                      type: string
                    resource_type:
                      type: string
                      enum: [postgres, instance]
                    resource_path:
                      type: string

  /w/{workspace}/workspaces/list_datatable_schemas:
    get:
      summary: list schemas of all connected Datatables
      operationId: listDataTableSchemas
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: schemas of all datatables
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DataTableSchema"

  /w/{workspace}/workspaces/list_datatable_tables:
    get:
      summary: list tables of all connected Datatables
      operationId: listDataTableTables
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: table metadata of all datatables
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DataTableTables"

  /w/{workspace}/workspaces/get_datatable_table_schema:
    get:
      summary: get one Datatable table schema
      operationId: getDataTableTableSchema
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: query
          required: true
          schema:
            type: string
        - name: schema_name
          in: query
          required: true
          schema:
            type: string
        - name: table_name
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: schema of one datatable table
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DataTableTableSchema"

  /w/{workspace}/workspaces/edit_ducklake_config:
    post:
      summary: edit ducklake settings
      operationId: editDucklakeConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Ducklake settings
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [settings]
              properties:
                settings:
                  $ref: "#/components/schemas/DucklakeSettings"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspaces/edit_datatable_config:
    post:
      summary: edit datatable settings
      operationId: editDataTableConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: DataTable settings
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [settings]
              properties:
                settings:
                  $ref: "#/components/schemas/DataTableSettings"
                renames:
                  description: data tables renamed in this save, so their migrations cascade
                  type: array
                  items:
                    type: object
                    required: [from, to]
                    properties:
                      from:
                        type: string
                      to:
                        type: string
                deleted_datatables:
                  description: data tables removed in this save, so their migrations are deleted
                  type: array
                  items:
                    type: string
      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspaces/run_datatable_migrations/{datatable_name}:
    post:
      summary: run pending datatable migrations against a datatable
      operationId: runDatatableMigrations
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
        - name: up_to
          in: query
          required: false
          description: only apply pending migrations up to and including this version
          schema:
            type: integer
            format: int64
        - name: only
          in: query
          required: false
          description: apply only this specific migration version, ignoring others
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: applied migrations
          content:
            application/json:
              schema:
                type: object
                required: [applied]
                properties:
                  applied:
                    type: array
                    items:
                      type: object
                      required: [version, name]
                      properties:
                        version:
                          type: integer
                          format: int64
                        name:
                          type: string

  /w/{workspace}/workspaces/rollback_datatable_migrations/{datatable_name}:
    post:
      summary: roll back the most recently applied migration on a datatable
      operationId: rollbackDatatableMigrations
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
        - name: only
          in: query
          required: false
          description: roll back this specific applied migration version instead of the latest
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: rolled back migrations
          content:
            application/json:
              schema:
                type: object
                required: [rolled_back]
                properties:
                  rolled_back:
                    type: array
                    items:
                      type: object
                      required: [version, name]
                      properties:
                        version:
                          type: integer
                          format: int64
                        name:
                          type: string

  /w/{workspace}/workspaces/list_datatable_migrations:
    get:
      summary: list datatable migrations for a workspace
      operationId: listDatatableMigrations
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: datatable migrations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DatatableMigration"

  /w/{workspace}/workspaces/datatable_migrations_status/{datatable_name}:
    get:
      summary: list a datatable's migrations with their applied status
      operationId: getDatatableMigrationsStatus
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: migrations with status
          content:
            application/json:
              schema:
                type: object
                required: [enabled, migrations]
                properties:
                  enabled:
                    type: boolean
                  migrations:
                    type: array
                    items:
                      $ref: "#/components/schemas/DatatableMigrationWithStatus"
                  error:
                    type: string

  /w/{workspace}/workspaces/enable_datatable_migrations/{datatable_name}:
    post:
      summary: opt a datatable in to migrations (admins / super admins only)
      operationId: enableDatatableMigrations
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/disable_datatable_migrations/{datatable_name}:
    post:
      summary: opt a datatable out of migrations, deleting all of them (admins / super admins only)
      operationId: disableDatatableMigrations
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/create_datatable_migration/{datatable_name}:
    post:
      summary: create a single datatable migration (version generated server-side)
      operationId: createDatatableMigration
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, code_up]
              properties:
                name:
                  type: string
                code_up:
                  type: string
                code_down:
                  type: string
      responses:
        "200":
          description: created migration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DatatableMigration"

  /w/{workspace}/workspaces/delete_datatable_migration/{datatable_name}/{timestamp}:
    delete:
      summary: delete a single datatable migration definition
      operationId: deleteDatatableMigration
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
        - name: timestamp
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/upsert_datatable_migration/{datatable_name}:
    post:
      summary: insert or update a single datatable migration at an explicit version
      operationId: upsertDatatableMigration
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [timestamp, name, code_up]
              properties:
                timestamp:
                  type: integer
                  format: int64
                name:
                  type: string
                code_up:
                  type: string
                code_down:
                  type: string
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/generate_initial_datatable_migration/{datatable_name}:
    post:
      summary: snapshot the current schema as an already-installed initial migration
      operationId: generateInitialDatatableMigration
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: datatable_name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: created migration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DatatableMigration"

  /w/{workspace}/workspaces/create_pg_database:
    post:
      summary: create a new PostgreSQL database for a datatable
      operationId: createPgDatabase
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Create pg database request
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [source, target_dbname]
              properties:
                source:
                  type: string
                  description: "Datatable source to determine connection info: 'datatable://name' or '$res:path'"
                target_dbname:
                  type: string
                  description: "Name for the new database"
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/drop_forked_datatable_databases:
    post:
      summary: drop forked datatable databases
      operationId: dropForkedDatatableDatabases
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [datatable_names]
              properties:
                datatable_names:
                  type: array
                  items:
                    type: string
      responses:
        "200":
          description: list of errors (empty if all succeeded)
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/workspaces/drop_forked_ducklake_namespaces:
    post:
      summary: drop this fork workspace's ducklake namespaces (catalog metadata schemas + data files)
      operationId: dropForkedDucklakeNamespaces
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of errors (empty if all succeeded)
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/workspaces/import_pg_database:
    post:
      summary: import a PostgreSQL database from source to target via pg_dump
      operationId: importPgDatabase
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Import pg database request
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [source, target, fork_behavior]
              properties:
                source:
                  type: string
                  description: "Source database: 'datatable://name' or '$res:path'"
                target:
                  type: string
                  description: "Target database: 'datatable://name' or '$res:path'"
                target_dbname_override:
                  type: string
                  description: "Override the target database name"
                fork_behavior:
                  type: string
                  enum:
                    - schema_only
                    - schema_and_data
                    - keep_original
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/export_pg_schema:
    post:
      summary: export the schema of a PostgreSQL database
      operationId: exportPgSchema
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Export pg schema request
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [source]
              properties:
                source:
                  type: string
                  description: "Source database: 'datatable://name' or '$res:path'"
      responses:
        "200":
          description: schema dump
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/get_datatable_full_schema:
    post:
      summary: get the full schema of a datatable database as TableEditorValues
      operationId: getDatatableFullSchema
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [source]
              properties:
                source:
                  type: string
                  description: "Source datatable, e.g. 'datatable://main'"
      responses:
        "200":
          description: "Schema as { schema_name: { table_name: TableEditorValues } }"
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  additionalProperties:
                    type: object
                    required: [name, columns, foreign_keys]
                    properties:
                      name:
                        type: string
                      columns:
                        type: array
                        items:
                          type: object
                          required: [name, datatype]
                          properties:
                            name:
                              type: string
                            datatype:
                              type: string
                            primary_key:
                              type: boolean
                            default_value:
                              type: string
                            nullable:
                              type: boolean
                      foreign_keys:
                        type: array
                        items:
                          type: object
                          required: [columns, on_delete, on_update]
                          properties:
                            target_table:
                              type: string
                            columns:
                              type: array
                              items:
                                type: object
                                properties:
                                  source_column:
                                    type: string
                                  target_column:
                                    type: string
                            on_delete:
                              type: string
                            on_update:
                              type: string
                            fk_constraint_name:
                              type: string
                      pk_constraint_name:
                        type: string

  /w/{workspace}/workspaces/git_sync_enabled:
    get:
      summary: Check if git sync is available for this workspace
      operationId: getGitSyncEnabled
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: Git sync availability status
          content:
            application/json:
              schema:
                type: object
                properties:
                  enabled:
                    type: boolean
                  reason:
                    type: string
                    nullable: true
                  max_repos:
                    type: integer
                    nullable: true
                  user_count:
                    type: integer
                    nullable: true
                  max_users:
                    type: integer
                    nullable: true

  /w/{workspace}/workspaces/git_sync_deploy_mode:
    get:
      summary: Get how local changes deploy to this workspace via git sync
      operationId: getGitSyncDeployMode
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: branch
          in: query
          required: false
          description: The branch the caller would push.
          schema:
            type: string
      responses:
        "200":
          description: Git sync deploy mode
          content:
            application/json:
              schema:
                type: object
                required:
                  - configured
                  - deploy_on_push
                properties:
                  configured:
                    type: boolean
                    description: At least one git-sync repository is configured.
                  deploy_on_push:
                    type: boolean
                    description: >-
                      True means a `git push` is confirmed to deploy via
                      auto-pull: exactly one licensed, deliverable repository
                      tracks the branch. False is *not confirmed* rather than a
                      definite no — it also covers unlicensed, ambiguous
                      (several repos track it), and conservative false-negatives;
                      determine the deploy path another way (CI `git push`, or
                      `wmill sync push`).

  /w/{workspace}/workspaces/edit_git_sync_config:
    post:
      summary: edit workspace git sync settings
      operationId: editWorkspaceGitSyncConfig
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Workspace Git sync settings
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                git_sync_settings:
                  $ref: "#/components/schemas/WorkspaceGitSyncSettings"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspaces/edit_git_sync_repository:
    post:
      summary: add or update individual git sync repository
      operationId: editGitSyncRepository
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Git sync repository settings to add or update
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                git_repo_resource_path:
                  type: string
                  description: The resource path of the git repository to update
                repository:
                  $ref: "#/components/schemas/GitRepositorySettings"
              required:
                - git_repo_resource_path
                - repository
      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspaces/delete_git_sync_repository:
    delete:
      summary: delete individual git sync repository
      operationId: deleteGitSyncRepository
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Git sync repository to delete
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                git_repo_resource_path:
                  type: string
                  description: The resource path of the git repository to delete
              required:
                - git_repo_resource_path
      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspaces/edit_deploy_ui_config:
    post:
      summary: edit workspace deploy ui settings
      operationId: editWorkspaceDeployUISettings
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Workspace deploy UI settings
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                deploy_ui_settings:
                  $ref: "#/components/schemas/WorkspaceDeployUISettings"

      responses:
        "200":
          description: status
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspaces/edit_default_app:
    post:
      summary: edit default app for workspace
      operationId: editWorkspaceDefaultApp
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Workspace default app
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                default_app_path:
                  type: string

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/default_scripts:
    post:
      summary: edit default scripts for workspace
      operationId: editDefaultScripts
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Workspace default app
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkspaceDefaultScripts"

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string
    get:
      summary: get default scripts for workspace
      operationId: get default scripts
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkspaceDefaultScripts"

  /w/{workspace}/workspaces/set_environment_variable:
    post:
      summary: set environment variable
      operationId: setEnvironmentVariable
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Workspace default app
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                value:
                  type: string
              required: [name]
      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/encryption_key:
    get:
      summary: retrieves the encryption key for this workspace
      operationId: getWorkspaceEncryptionKey
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  key:
                    type: string
                required:
                  - key
    post:
      summary: update the encryption key for this workspace
      operationId: setWorkspaceEncryptionKey
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: New encryption key
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                new_key:
                  type: string
                skip_reencrypt:
                  type: boolean
              required:
                - new_key

      responses:
        "200":
          description: status
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/default_app:
    get:
      summary: get default app for workspace
      operationId: getWorkspaceDefaultApp
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  default_app_path:
                    type: string
                  default_app_raw:
                    type: boolean

  /w/{workspace}/workspaces/usage:
    get:
      summary: get usage
      operationId: getWorkspaceUsage
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: usage
          content:
            text/plain:
              schema:
                type: number

  /w/{workspace}/workspaces/used_triggers:
    get:
      summary: get used triggers
      operationId: getUsedTriggers
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: object
                properties:
                  http_routes_used:
                    type: boolean
                  websocket_used:
                    type: boolean
                  kafka_used:
                    type: boolean
                  nats_used:
                    type: boolean
                  postgres_used:
                    type: boolean
                  mqtt_used:
                    type: boolean
                  amqp_used:
                    type: boolean
                  gcp_used:
                    type: boolean
                  azure_used:
                    type: boolean
                  sqs_used:
                    type: boolean
                  email_used:
                    type: boolean
                  nextcloud_used:
                    type: boolean
                  google_used:
                    type: boolean
                  github_used:
                    type: boolean
                required:
                  - http_routes_used
                  - websocket_used
                  - kafka_used
                  - nats_used
                  - postgres_used
                  - mqtt_used
                  - amqp_used
                  - gcp_used
                  - azure_used
                  - sqs_used
                  - email_used
                  - nextcloud_used
                  - google_used
                  - github_used
  /w/{workspace}/users/list:
    get:
      summary: list users
      operationId: listUsers
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"

  /w/{workspace}/users/list_usage:
    get:
      summary: list users usage
      operationId: listUsersUsage
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/UserUsage"

  /w/{workspace}/users/list_usernames:
    get:
      summary: list usernames
      operationId: listUsernames
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: user
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/users/username_to_email/{username}:
    get:
      summary: get email from username
      operationId: usernameToEmail
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: username
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: email
          content:
            text/plain:
              schema:
                type: string

  /tokens/list/scopes:
    get:
      summary: list of available scopes
      operationId: ListAvailableScopes
      tags:
        - token
      responses:
        "200":
          description: list of available scopes
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ScopeDomain"

  /users/tokens/create:
    post:
      summary: create token
      operationId: createToken
      tags:
        - user
      requestBody:
        description: new token
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewToken"
      responses:
        "201":
          description: token created
          content:
            text/plain:
              schema:
                type: string

  /users/tokens/impersonate:
    post:
      summary: create token to impersonate a user (require superadmin)
      operationId: createTokenImpersonate
      tags:
        - user
      requestBody:
        description: new token
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewTokenImpersonate"
      responses:
        "201":
          description: token created
          content:
            text/plain:
              schema:
                type: string

  /users/tokens/delete/{token_prefix}:
    delete:
      summary: delete token
      operationId: deleteToken
      tags:
        - user
      parameters:
        - name: token_prefix
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: delete token
          content:
            text/plain:
              schema:
                type: string

  /users/tokens/update_scopes/{token_prefix}:
    post:
      summary: update scopes of an existing token (owner only)
      operationId: updateTokenScopes
      tags:
        - user
      parameters:
        - name: token_prefix
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: new scopes (null or omitted = full access)
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                scopes:
                  type: array
                  items:
                    type: string
                  nullable: true
      responses:
        "200":
          description: scopes updated
          content:
            text/plain:
              schema:
                type: string

  /users/tokens/update_label/{token_prefix}:
    post:
      summary: update label of an existing token (owner only)
      operationId: updateTokenLabel
      tags:
        - user
      parameters:
        - name: token_prefix
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: new label (null or omitted = no label)
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                label:
                  type: string
                  nullable: true
      responses:
        "200":
          description: label updated
          content:
            text/plain:
              schema:
                type: string

  /users/tokens/list:
    get:
      summary: list token
      operationId: listTokens
      tags:
        - user
      parameters:
        - name: exclude_ephemeral
          in: query
          schema:
            type: boolean
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: truncated token
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/TruncatedToken"

  /w/{workspace}/oidc/token/{audience}:
    post:
      summary: get OIDC token (ee only)
      operationId: getOidcToken
      tags:
        - oidc
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: audience
          in: path
          required: true
          schema:
            type: string
        - name: expires_in
          in: query
          schema:
            type: number

      responses:
        "200":
          description: new oidc token
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/variables/create:
    post:
      summary: create variable
      operationId: createVariable
      x-mcp-tool: true
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: already_encrypted
          description: whether the variable is already encrypted (default false)
          in: query
          schema:
            type: boolean
      requestBody:
        description: new variable
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateVariable"
      responses:
        "201":
          description: variable created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/variables/encrypt:
    post:
      summary: encrypt value
      operationId: encryptValue
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new variable
        required: true
        content:
          application/json:
            schema:
              type: string
      responses:
        "200":
          description: encrypted value
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/variables/delete/{path}:
    delete:
      summary: delete variable
      operationId: deleteVariable
      x-mcp-tool: true
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: variable deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/variables/delete_bulk:
    delete:
      summary: delete variables in bulk
      operationId: deleteVariablesBulk
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: paths to delete
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                paths:
                  type: array
                  items:
                    type: string
              required:
                - paths
      responses:
        "200":
          description: deleted paths
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/variables/update/{path}:
    post:
      summary: update variable
      operationId: updateVariable
      x-mcp-tool: true
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: already_encrypted
          description: whether the variable is already encrypted (default false)
          in: query
          schema:
            type: boolean
      requestBody:
        description: updated variable
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditVariable"
      responses:
        "200":
          description: variable updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/variables/get/{path}:
    get:
      summary: get variable
      operationId: getVariable
      x-mcp-tool: true
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: decrypt_secret
          description: |
            ask to decrypt secret if this variable is secret
            (if not secret no effect, default: true)
          in: query
          schema:
            type: boolean
        - name: include_encrypted
          description: |
            ask to include the encrypted value if secret and decrypt secret is not true (default: false)
          in: query
          schema:
            type: boolean
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: variable
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/ListableVariable"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/variables/get_value/{path}:
    get:
      summary: get variable value
      operationId: getVariableValue
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: allow_cache
          description: |
            allow getting a cached value for improved performance
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: variable
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/variables/exists/{path}:
    get:
      summary: does variable exists at path
      operationId: existsVariable
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: variable
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/variables/list:
    get:
      summary: list variables
      operationId: listVariable
      x-mcp-tool: true
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: path_start
          description: filter variables by path prefix
          in: query
          schema:
            type: string
        - name: path
          description: exact path match filter
          in: query
          schema:
            type: string
        - name: description
          description: pattern match filter for description field (case-insensitive)
          in: query
          schema:
            type: string
        - name: value
          description: pattern match filter for non-secret variable values (case-insensitive)
          in: query
          schema:
            type: string
        - name: broad_filter
          description: broad search across multiple fields (case-insensitive substring match)
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: label
          description: Filter by label
          in: query
          required: false
          schema:
            type: string
        - name: include_draft_only
          description: |
            When true, append per-user draft variables whose path has no
            deployed variable. Synthesized rows carry `draft_only: true`
            so the home page can render a "Draft" badge.
          in: query
          required: false
          schema:
            type: boolean
      responses:
        "200":
          description: variable list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ListableVariable"

  /w/{workspace}/variables/list_contextual:
    get:
      summary: list contextual variables
      operationId: listContextualVariables
      tags:
        - variable
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: contextual variable list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ContextualVariable"

  /w/{workspace}/workspaces/get_secondary_storage_names:
    get:
      summary: get secondary storage names
      operationId: getSecondaryStorageNames
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: include_default
          in: query
          description: If true, include "_default_" in the list if primary workspace storage is set
          required: false
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: status
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/workspaces/critical_alerts:
    get:
      summary: Get all critical alerts for this workspace
      operationId: workspaceGetCriticalAlerts
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - in: query
          name: page
          schema:
            type: integer
            default: 1
            description: The page number to retrieve (minimum value is 1)
        - in: query
          name: page_size
          schema:
            type: integer
            default: 10
            maximum: 100
            description: Number of alerts per page (maximum is 100)
        - in: query
          name: acknowledged
          schema:
            type: boolean
            nullable: true
            description: Filter by acknowledgment status; true for acknowledged, false for unacknowledged, and omit for all alerts
      responses:
        "200":
          description: Successfully retrieved all critical alerts
          content:
            application/json:
              schema:
                type: object
                properties:
                  alerts:
                    type: array
                    items:
                      $ref: "#/components/schemas/CriticalAlert"
                  total_rows:
                    type: integer
                    description: Total number of rows matching the query.
                    example: 100
                  total_pages:
                    type: integer
                    description: Total number of pages based on the page size.
                    example: 10

  /w/{workspace}/workspaces/critical_alerts/{id}/acknowledge:
    post:
      summary: Acknowledge a critical alert for this workspace
      operationId: workspaceAcknowledgeCriticalAlert
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: The ID of the critical alert to acknowledge
      responses:
        "200":
          description: Successfully acknowledged the critical alert
          content:
            application/json:
              schema:
                type: string
                example: "Critical alert acknowledged"

  /w/{workspace}/workspaces/critical_alerts/acknowledge_all:
    post:
      summary: Acknowledge all unacknowledged critical alerts for this workspace
      operationId: workspaceAcknowledgeAllCriticalAlerts
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: Successfully acknowledged all unacknowledged critical alerts.
          content:
            application/json:
              schema:
                type: string
                example: "All unacknowledged critical alerts acknowledged"

  /w/{workspace}/workspaces/critical_alerts/mute:
    post:
      summary: Mute critical alert UI for this workspace
      operationId: workspaceMuteCriticalAlertsUI
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Boolean flag to mute critical alerts.
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mute_critical_alerts:
                  type: boolean
                  description: Whether critical alerts should be muted.
                  example: true
      responses:
        "200":
          description: Successfully updated mute critical alert settings.
          content:
            application/json:
              schema:
                type: string
                example: "Updated mute critical alert UI settings for workspace: workspace_id"

  /w/{workspace}/workspaces/protection_rules:
    get:
      summary: list all protection rules for a workspace
      operationId: listProtectionRules
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of protection rules
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ProtectionRuleset"
    post:
      summary: create a new protection rule
      operationId: createProtectionRule
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: New protection rule configuration
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - rules
                - bypass_groups
                - bypass_users
              properties:
                name:
                  type: string
                  description: Unique name for the protection rule
                  example: "Production Protection"
                rules:
                  $ref: "#/components/schemas/ProtectionRules"
                bypass_groups:
                  $ref: "#/components/schemas/RuleBypasserGroups"
                bypass_users:
                  $ref: "#/components/schemas/RuleBypasserUsers"
      responses:
        "200":
          description: protection rule created successfully
          content:
            text/plain:
              schema:
                type: string
        "400":
          description: rule with this name already exists

  /w/{workspace}/workspaces/protection_rules/{rule_name}:
    post:
      summary: update an existing protection rule
      operationId: updateProtectionRule
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: rule_name
          in: path
          required: true
          schema:
            type: string
          description: Name of the protection rule to update
      requestBody:
        description: Updated protection rule configuration
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - rules
                - bypass_groups
                - bypass_users
              properties:
                rules:
                  $ref: "#/components/schemas/ProtectionRules"
                bypass_groups:
                  $ref: "#/components/schemas/RuleBypasserGroups"
                bypass_users:
                  $ref: "#/components/schemas/RuleBypasserUsers"
      responses:
        "200":
          description: protection rule updated successfully
          content:
            text/plain:
              schema:
                type: string
        "404":
          description: protection rule not found
    delete:
      summary: delete a protection rule
      operationId: deleteProtectionRule
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: rule_name
          in: path
          required: true
          schema:
            type: string
          description: Name of the protection rule to delete
      responses:
        "200":
          description: protection rule deleted successfully
          content:
            text/plain:
              schema:
                type: string
        "404":
          description: protection rule not found

  /w/{workspace}/deployment_request/eligible_deployers:
    get:
      summary: list users eligible to be deployment request assignees
      description: Returns admins and members of wm_deployers in the parent workspace of the fork at `{workspace}`.
      operationId: listDeploymentRequestEligibleDeployers
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of eligible deployers
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DeploymentRequestEligibleDeployer"

  /w/{workspace}/deployment_request/open:
    get:
      summary: get the currently open deployment request for this fork
      operationId: getOpenDeploymentRequest
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: the open request or null if none exists
          content:
            application/json:
              schema:
                nullable: true
                allOf:
                  - $ref: "#/components/schemas/DeploymentRequest"

  /w/{workspace}/deployment_request:
    post:
      summary: create a new deployment request
      operationId: createDeploymentRequest
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - assignees
              properties:
                assignees:
                  type: array
                  items:
                    type: string
                  description: Usernames in the parent workspace. Must be admin or wm_deployers.
      responses:
        "200":
          description: request created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeploymentRequest"
        "400":
          description: invalid assignees
        "409":
          description: a deployment request is already open for this fork

  /w/{workspace}/deployment_request/{id}/cancel:
    post:
      summary: cancel an open deployment request
      operationId: cancelDeploymentRequest
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: id
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: cancelled
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/deployment_request/{id}/close_merged:
    post:
      summary: close a deployment request after a successful merge
      description: Called by the UI after the deploy loop completes. Closes the request and marks every comment obsolete. Idempotent.
      operationId: closeDeploymentRequestMerged
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: id
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: closed
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/deployment_request/{id}/comment:
    post:
      summary: append a comment to an open deployment request
      operationId: createDeploymentRequestComment
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: id
          in: path
          required: true
          schema:
            type: integer
            format: int64
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - body
              properties:
                body:
                  type: string
                parent_id:
                  type: integer
                  format: int64
                  nullable: true
                anchor_kind:
                  type: string
                  nullable: true
                anchor_path:
                  type: string
                  nullable: true
      responses:
        "200":
          description: comment created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeploymentRequestComment"
        "400":
          description: invalid input or request closed

  /w/{workspace}/workspaces/log_feature_usage:
    post:
      summary: log anonymous feature usage telemetry events
      operationId: logFeatureUsage
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - events
              properties:
                events:
                  type: array
                  items:
                    type: object
                    required:
                      - feature
                      - kind
                    properties:
                      feature:
                        type: string
                      kind:
                        type: string
                      key:
                        type: string
                      entity_id:
                        type: string
                      value:
                        type: integer
      responses:
        "204":
          description: logged

  /w/{workspace}/workspaces/cloud_quotas:
    get:
      summary: get cloud quota usage and limits for workspace
      operationId: getCloudQuotas
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: cloud quota usage and limits
          content:
            application/json:
              schema:
                type: object
                properties:
                  scripts:
                    $ref: "#/components/schemas/QuotaInfo"
                  flows:
                    $ref: "#/components/schemas/QuotaInfo"
                  apps:
                    $ref: "#/components/schemas/QuotaInfo"
                  variables:
                    $ref: "#/components/schemas/QuotaInfo"
                  resources:
                    $ref: "#/components/schemas/QuotaInfo"
                  forks:
                    $ref: "#/components/schemas/QuotaInfo"
                required:
                  - scripts
                  - flows
                  - apps
                  - variables
                  - resources
                  - forks

  /w/{workspace}/workspaces/prune_versions:
    post:
      summary: prune old versions of scripts, flows, or apps
      operationId: pruneVersions
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                resource_type:
                  type: string
                  enum:
                    - scripts
                    - flows
                    - apps
              required:
                - resource_type
      responses:
        "200":
          description: number of pruned versions
          content:
            application/json:
              schema:
                type: object
                properties:
                  pruned:
                    type: integer
                required:
                  - pruned

  /w/{workspace}/workspaces/list_ws_specific:
    get:
      summary: list all workspace-specific items
      operationId: listWsSpecific
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of workspace-specific items
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    item_kind:
                      type: string
                    path:
                      type: string
                  required:
                    - item_kind
                    - path

  /w/{workspace}/workspaces/list_ws_specific_versions:
    get:
      summary: list workspace ids that have a version of the given item
      operationId: listWsSpecificVersions
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: kind
          in: query
          required: true
          schema:
            type: string
            enum:
              - resource
              - variable
        - name: path
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: list of workspace ids that have a version of the item
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/workspaces/set_ws_specific:
    post:
      summary: mark or unmark an item as workspace-specific
      operationId: setWsSpecific
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                item_kind:
                  type: string
                  enum:
                    - resource
                    - variable
                path:
                  type: string
                value:
                  type: boolean
              required:
                - item_kind
                - path
                - value
      responses:
        "200":
          description: workspace-specific flag updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspaces/public_app_rate_limit:
    post:
      summary: Set public app rate limit for this workspace
      operationId: setPublicAppRateLimit
      tags:
        - setting
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Public app rate limit configuration
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                public_app_execution_limit_per_minute:
                  type: integer
                  description: Rate limit for public app executions per minute per server. NULL or 0 to disable.
                  example: 100
      responses:
        "200":
          description: Successfully updated public app rate limit settings.
          content:
            application/json:
              schema:
                type: string
                example: "Updated public app rate limit for workspace: workspace_id"

  /oauth/login_callback/{client_name}:
    post:
      security: []
      summary: login with oauth authorization flow
      operationId: loginWithOauth
      tags:
        - user
      parameters:
        - $ref: "#/components/parameters/ClientName"
      requestBody:
        description: Partially filled script
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                state:
                  type: string

      responses:
        "200":
          description: >
            Successfully authenticated. The session ID is returned in a cookie
            named `token` and as plaintext response. Preferred method of
            authorization is through the bearer token. The cookie is only for
            browser convenience.

          headers:
            Set-Cookie:
              schema:
                type: string
                example: token=abcde12345; Path=/; HttpOnly
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/oauth/connect_slack_callback:
    post:
      summary: connect slack callback
      operationId: connectSlackCallback
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: code endpoint
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                state:
                  type: string
              required:
                - code
                - state
      responses:
        "200":
          description: slack token
          content:
            text/plain:
              schema:
                type: string

  /oauth/connect_slack_callback:
    post:
      summary: connect slack callback instance
      operationId: connectSlackCallbackInstance
      tags:
        - oauth
      requestBody:
        description: code endpoint
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                state:
                  type: string
              required:
                - code
                - state
      responses:
        "200":
          description: success message
          content:
            text/plain:
              schema:
                type: string

  /oauth/connect_slack_instance:
    post:
      summary: connect slack instance (non-interactive; pre-minted bot token)
      operationId: connectSlackInstance
      tags:
        - oauth
      requestBody:
        description: connect slack at the instance level with a pre-minted bot token
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - bot_token
                - team_id
                - team_name
              properties:
                bot_token:
                  type: string
                  description: xoxb-... bot token obtained at api.slack.com/apps
                team_id:
                  type: string
                team_name:
                  type: string
      responses:
        "200":
          description: status

  /oauth/connect_callback/{client_name}:
    post:
      summary: connect callback
      operationId: connectCallback
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/ClientName"
      requestBody:
        description: code endpoint
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                state:
                  type: string
              required:
                - code
                - state
      responses:
        "200":
          description: oauth token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenResponse"

  /w/{workspace}/oauth/create_account:
    post:
      summary: create OAuth account
      operationId: createAccount
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: code endpoint
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                refresh_token:
                  type: string
                  description: "OAuth refresh token. For authorization_code flow, this contains the actual refresh token. For client_credentials flow, this must be set to an empty string."
                expires_in:
                  type: integer
                client:
                  type: string
                grant_type:
                  type: string
                  default: "authorization_code"
                cc_client_id:
                  type: string
                  description: "OAuth client ID for resource-level credentials (client_credentials flow only)"
                cc_client_secret:
                  type: string
                  description: "OAuth client secret for resource-level credentials (client_credentials flow only)"
                cc_instance:
                  type: string
                  description: "Instance name for built-in providers whose client-credentials token URL is instance-templated; substituted into the fixed-host registry template server-side (client_credentials flow only). The token URL is never caller-supplied."
                cc_token_url:
                  type: string
                  description: "Bring-your-own token endpoint override (client_credentials flow only). Only honored together with cc_client_id/cc_client_secret and mutually exclusive with cc_instance; ignored/rejected on the shared-instance path."
                mcp_server_url:
                  type: string
                  description: "MCP server URL for MCP OAuth token refresh"
                scopes:
                  type: array
                  items:
                    type: string
                  description: "OAuth scopes to use for token refresh. Overrides instance-level scopes."
              required:
                - refresh_token
                - expires_in
                - client
      responses:
        "200":
          description: account set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/oauth/connect_client_credentials/{client}:
    post:
      summary: connect OAuth using client credentials
      operationId: connectClientCredentials
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: client
          in: path
          description: OAuth client name
          required: true
          schema:
            type: string
      requestBody:
        description: client credentials flow parameters
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                scopes:
                  type: array
                  items:
                    type: string
                cc_client_id:
                  type: string
                  description: "OAuth client ID. Omit to use the credentials configured on the provider's instance OAuth entry."
                cc_client_secret:
                  type: string
                  description: "OAuth client secret. Omit to use the credentials configured on the provider's instance OAuth entry."
                cc_instance:
                  type: string
                  description: "Instance name for built-in providers whose client-credentials token URL is instance-templated; substituted into the fixed-host registry template server-side. The token URL is never caller-supplied."
                cc_token_url:
                  type: string
                  description: "Bring-your-own token endpoint override. Only honored together with cc_client_id/cc_client_secret and mutually exclusive with cc_instance; rejected on the shared-instance path."
      responses:
        "200":
          description: OAuth token response
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenResponse"

  /w/{workspace}/oauth/refresh_token/{id}:
    post:
      summary: refresh token
      operationId: refreshToken
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/AccountId"
      requestBody:
        description: variable path
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: string
              required:
                - path
      responses:
        "200":
          description: token refreshed
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/oauth/disconnect/{id}:
    post:
      summary: disconnect account
      operationId: disconnectAccount
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/AccountId"
      responses:
        "200":
          description: disconnected client
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/oauth/disconnect_slack:
    post:
      summary: disconnect slack
      operationId: disconnectSlack
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: disconnected slack
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/oauth/disconnect_teams:
    post:
      summary: disconnect teams
      operationId: disconnectTeams
      tags:
        - oauth
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: disconnected teams
          content:
            text/plain:
              schema:
                type: string

  /oauth/list_logins:
    get:
      summary: list oauth logins
      operationId: listOAuthLogins
      tags:
        - oauth
      responses:
        "200":
          description: list of oauth and saml login clients
          content:
            application/json:
              schema:
                type: object
                properties:
                  oauth:
                    type: array
                    items:
                      type: object
                      properties:
                        type:
                          type: string
                        display_name:
                          type: string
                      required:
                        - type
                  saml:
                    type: string
                  auto_login:
                    type: string
                    description: provider type to auto-redirect to on login (oauth key or "saml")
                required:
                  - oauth

  /oauth/list_connects:
    get:
      summary: list oauth connects
      operationId: listOAuthConnects
      tags:
        - oauth
      responses:
        "200":
          description: list of oauth connects clients
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                    supports_client_credentials:
                      type: boolean
                    has_shared_credentials:
                      type: boolean
                  required:
                    - name
                    - supports_client_credentials
                    - has_shared_credentials

  /oauth/get_connect/{client}:
    get:
      summary: get oauth connect
      operationId: getOAuthConnect
      tags:
        - oauth
      parameters:
        - name: client
          description: client name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: get
          content:
            application/json:
              schema:
                type: object
                properties:
                  extra_params:
                    type: object
                  scopes:
                    type: array
                    items:
                      type: string
                  grant_types:
                    type: array
                    items:
                      type: string
                  client_credentials_configured:
                    type: boolean
                    description: "The instance OAuth entry carries shared client-credentials, so the connect dialog can skip the bring-your-own form and run the exchange server-side"

  /teams/activities:
    post:
      summary: send update to Microsoft Teams activity
      description: Respond to a Microsoft Teams activity after a workspace command is run
      operationId: sendMessageToConversation
      tags:
        - teams
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - conversation_id
                - text
              properties:
                conversation_id:
                  type: string
                  description: The ID of the Teams conversation/activity
                success:
                  type: boolean
                  description: Used for styling the card conditionally
                  default: true
                text:
                  type: string
                  description: The message text to be sent in the Teams card
                card_block:
                  type: object
                  description: The card block to be sent in the Teams card

      responses:
        "200":
          description: Activity processed successfully

  /w/{workspace}/resources/create:
    post:
      summary: create resource
      operationId: createResource
      x-mcp-tool: true
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: update_if_exists
          description: update the resource if it already exists (default false)
          in: query
          schema:
            type: boolean
      requestBody:
        description: new resource
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateResource"
      responses:
        "201":
          description: resource created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/resources/delete/{path}:
    delete:
      summary: delete resource
      operationId: deleteResource
      x-mcp-tool: true
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: resource deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/resources/delete_bulk:
    delete:
      summary: delete resources in bulk
      operationId: deleteResourcesBulk
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: paths to delete
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                paths:
                  type: array
                  items:
                    type: string
              required:
                - paths
      responses:
        "200":
          description: deleted paths
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/resources/update/{path}:
    post:
      summary: update resource
      operationId: updateResource
      x-mcp-tool: true
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated resource
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditResource"
      responses:
        "200":
          description: resource updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/resources/update_value/{path}:
    post:
      summary: update resource value
      operationId: updateResourceValue
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated resource
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                value: {}
      responses:
        "200":
          description: resource value updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/resources/get/{path}:
    get:
      summary: get resource
      operationId: getResource
      x-mcp-tool: true
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: resource
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/ListableResource"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/resources/get_value_interpolated/{path}:
    get:
      summary: get resource interpolated (variables and resources are fully unrolled)
      operationId: getResourceValueInterpolated
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: job_id
          description: job id
          in: query
          schema:
            type: string
            format: uuid
        - name: allow_cache
          description: allow getting a cached value for improved performance
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: resource value
          content:
            application/json:
              schema: {}

  /w/{workspace}/resources/get_value/{path}:
    get:
      summary: get resource value
      operationId: getResourceValue
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: resource value
          content:
            application/json:
              schema: {}

  /w/{workspace}/resources/git_commit_hash/{path}:
    get:
      summary: get git repository latest commit hash
      operationId: getGitCommitHash
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: git_ssh_identity
          in: query
          schema:
            type: string
      responses:
        "200":
          description: git commit hash
          content:
            application/json:
              schema:
                type: object
                properties:
                  commit_hash:
                    type: string
                    description: Latest commit hash from git ls-remote
                required:
                  - commit_hash

  /w/{workspace}/resources/exists/{path}:
    get:
      summary: does resource exists
      operationId: existsResource
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: does resource exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/resources/list:
    get:
      summary: list resources
      operationId: listResource
      x-mcp-tool: true
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: resource_type
          description: resource_types to list from, separated by ',',
          in: query
          schema:
            type: string
        - name: resource_type_exclude
          description: resource_types to not list from, separated by ',',
          in: query
          schema:
            type: string
        - name: path_start
          description: filter resources by path prefix
          in: query
          schema:
            type: string
        - name: path
          description: exact path match filter
          in: query
          schema:
            type: string
        - name: description
          description: pattern match filter for description field (case-insensitive)
          in: query
          schema:
            type: string
        - name: value
          description: JSONB subset match filter using base64 encoded JSON
          in: query
          schema:
            type: string
        - name: broad_filter
          description: broad search across multiple fields (case-insensitive substring match)
          in: query
          schema:
            type: string
        - name: label
          description: Filter by label
          in: query
          required: false
          schema:
            type: string
        - name: include_draft_only
          description: |
            When true, append per-user draft resources whose path has
            no deployed resource. Synthesized rows carry
            `draft_only: true`.
          in: query
          required: false
          schema:
            type: boolean
      responses:
        "200":
          description: resource list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ListableResource"

  /w/{workspace}/resources/list_search:
    get:
      summary: list resources for search
      operationId: listSearchResource
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: resource list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    path:
                      type: string
                    value: {}
                  required:
                    - path
                    - value

  /w/{workspace}/resources/mcp_tools/{path}:
    get:
      summary: get MCP tools from resource
      operationId: getMcpTools
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: list of MCP tools
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                    description:
                      type: string
                    parameters:
                      type: object
                  required:
                    - name
                    - parameters

  /w/{workspace}/resources/list_names/{name}:
    get:
      summary: list resource names
      operationId: listResourceNames
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: resource list names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                    path:
                      type: string
                  required:
                    - name
                    - path

  /w/{workspace}/resources/type/create:
    post:
      summary: create resource_type
      operationId: createResourceType
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new resource_type
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ResourceType"
      responses:
        "201":
          description: resource_type created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/resources/file_resource_type_to_file_ext_map:
    get:
      summary: get map from resource type to format extension
      operationId: fileResourceTypeToFileExtMap
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: map from resource type to file resource info
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: object
                  properties:
                    format_extension:
                      type: string
                      nullable: true
                    is_fileset:
                      type: boolean

  /w/{workspace}/resources/type/delete/{path}:
    delete:
      summary: delete resource_type
      operationId: deleteResourceType
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: resource_type deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/resources/type/update/{path}:
    post:
      summary: update resource_type
      operationId: updateResourceType
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated resource_type
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditResourceType"
      responses:
        "200":
          description: resource_type updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/resources/type/get/{path}:
    get:
      summary: get resource_type
      operationId: getResourceType
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: resource_type deleted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ResourceType"

  /w/{workspace}/resources/type/exists/{path}:
    get:
      summary: does resource_type exists
      operationId: existsResourceType
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: does resource_type exist
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/resources/type/list:
    get:
      summary: list resource_types
      operationId: listResourceType
      x-mcp-tool: true
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: resource_type list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ResourceType"

  /w/{workspace}/resources/type/listnames:
    get:
      summary: list resource_types names
      operationId: listResourceTypeNames
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: resource_type list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/npm_proxy/metadata/{package}:
    get:
      summary: get npm package metadata from private registry
      operationId: getNpmPackageMetadata
      tags:
        - npm_proxy
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: package
          description: npm package name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: package metadata
          content:
            application/json:
              schema:
                type: object
                properties:
                  tags:
                    type: object
                    additionalProperties:
                      type: string
                  versions:
                    type: array
                    items:
                      type: string

  /w/{workspace}/npm_proxy/resolve/{package}:
    get:
      summary: resolve npm package version from private registry
      operationId: resolveNpmPackageVersion
      tags:
        - npm_proxy
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: package
          description: npm package name
          in: path
          required: true
          schema:
            type: string
        - name: tag
          description: version tag or reference
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: resolved version
          content:
            application/json:
              schema:
                type: object
                properties:
                  version:
                    type: string
                    nullable: true

  /w/{workspace}/npm_proxy/filetree/{package}/{version}:
    get:
      summary: get npm package file tree from private registry
      operationId: getNpmPackageFiletree
      tags:
        - npm_proxy
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: package
          description: npm package name
          in: path
          required: true
          schema:
            type: string
        - name: version
          description: package version
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: package file tree
          content:
            application/json:
              schema:
                type: object
                properties:
                  default:
                    type: string
                  files:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string

  /w/{workspace}/npm_proxy/file/{package}/{version}/{filepath}:
    get:
      summary: get specific file from npm package in private registry
      operationId: getNpmPackageFile
      tags:
        - npm_proxy
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: package
          description: npm package name
          in: path
          required: true
          schema:
            type: string
        - name: version
          description: package version
          in: path
          required: true
          schema:
            type: string
        - name: filepath
          description: file path within package
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: file content
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/embeddings/query_resource_types:
    get:
      summary: query resource types by similarity
      operationId: queryResourceTypes
      tags:
        - resource
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: text
          description: query text
          in: query
          required: true
          schema:
            type: string
        - name: limit
          description: query limit
          in: query
          required: false
          schema:
            type: number
      responses:
        "200":
          description: resource type details
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                    score:
                      type: number
                    schema: {}
                  required:
                    - name
                    - score

  /integrations/hub/list:
    get:
      summary: list hub integrations
      operationId: listHubIntegrations
      tags:
        - integration
      parameters:
        - name: kind
          description: query integrations kind
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: integrations details
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                  required:
                    - name

  /flows/hub/list:
    get:
      summary: list all hub flows
      operationId: listHubFlows
      tags:
        - flow
      responses:
        "200":
          description: hub flows list
          content:
            application/json:
              schema:
                type: object
                properties:
                  flows:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                        flow_id:
                          type: number
                        summary:
                          type: string
                        apps:
                          type: array
                          items:
                            type: string
                        approved:
                          type: boolean
                        votes:
                          type: number

                      required:
                        - id
                        - flow_id
                        - summary
                        - apps
                        - approved
                        - votes

  /flows/hub/get/{id}:
    get:
      summary: get hub flow by id
      operationId: getHubFlowById
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/PathId"
      responses:
        "200":
          description: flow
          content:
            application/json:
              schema:
                type: object
                properties:
                  flow:
                    $ref: "../../openflow.openapi.yaml#/components/schemas/OpenFlow"

  /apps/hub/list:
    get:
      summary: list all hub apps
      operationId: listHubApps
      tags:
        - app
      responses:
        "200":
          description: hub apps list
          content:
            application/json:
              schema:
                type: object
                properties:
                  apps:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                        app_id:
                          type: number
                        summary:
                          type: string
                        apps:
                          type: array
                          items:
                            type: string
                        approved:
                          type: boolean
                        votes:
                          type: number
                      required:
                        - id
                        - app_id
                        - summary
                        - apps
                        - approved
                        - votes

  /apps/hub/get/{id}:
    get:
      summary: get hub app by id
      operationId: getHubAppById
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/PathId"
      responses:
        "200":
          description: app
          content:
            application/json:
              schema:
                type: object
                properties:
                  app:
                    type: object
                    properties:
                      summary:
                        type: string
                      value: {}
                    required:
                      - summary
                      - value
                required:
                  - app

  /apps/hub/get_raw/{id}:
    get:
      summary: get hub raw app by id
      operationId: getHubRawAppById
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/PathId"
      responses:
        "200":
          description: raw app
          content:
            application/json:
              schema:
                type: object
                properties:
                  app:
                    type: object
                    properties:
                      summary:
                        type: string
                      value: {}
                    required:
                      - summary
                      - value
                required:
                  - app

  /apps_u/public_app_by_custom_path/{custom_path}:
    get:
      summary: get public app by custom path
      operationId: getPublicAppByCustomPath
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/CustomPath"
      responses:
        "200":
          description: app details
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/AppWithLastVersion"
                  - type: object
                    properties:
                      workspace_id:
                        type: string

  /apps_u/embed_token_by_custom_path/{custom_path}:
    get:
      summary: get app embed token by custom path
      operationId: getAppEmbedTokenByCustomPath
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/CustomPath"
      responses:
        "200":
          description: embed token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmbedTokenResponse"

  /scripts/hub/get/{path}:
    get:
      summary: get hub script content by path
      operationId: getHubScriptContentByPath
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script details
          content:
            text/plain:
              schema:
                type: string

  /scripts/hub/get_full/{path}:
    get:
      summary: get full hub script by path
      operationId: getHubScriptByPath
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script details
          content:
            application/json:
              schema:
                type: object
                properties:
                  content:
                    type: string
                  lockfile:
                    type: string
                  schema: {}
                  language:
                    type: string
                  summary:
                    type: string
                required:
                  - content
                  - language

  /scripts/hub/pick/{path}:
    get:
      summary: record hub script pick
      operationId: pickHubScriptByPath
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script pick recorded
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                required:
                  - success

  /scripts/hub/top:
    get:
      summary: get top hub scripts
      operationId: getTopHubScripts
      tags:
        - script
      parameters:
        - name: limit
          description: query limit
          in: query
          required: false
          schema:
            type: number
        - name: app
          description: query scripts app
          in: query
          required: false
          schema:
            type: string
        - name: kind
          description: query scripts kind
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: hub scripts list
          content:
            application/json:
              schema:
                type: object
                properties:
                  asks:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                        ask_id:
                          type: number
                        summary:
                          type: string
                        app:
                          type: string
                        version_id:
                          type: number
                        kind:
                          $ref: "#/components/schemas/HubScriptKind"
                        votes:
                          type: number
                        views:
                          type: number
                      required:
                        - id
                        - ask_id
                        - summary
                        - app
                        - version_id
                        - kind
                        - views
                        - votes

  /embeddings/query_hub_scripts:
    get:
      summary: query hub scripts by similarity
      operationId: queryHubScripts
      tags:
        - script
      parameters:
        - name: text
          description: query text
          in: query
          required: true
          schema:
            type: string
        - name: kind
          description: query scripts kind
          in: query
          required: false
          schema:
            type: string
        - name: limit
          description: query limit
          in: query
          required: false
          schema:
            type: number
        - name: app
          description: query scripts app
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: script details
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    ask_id:
                      type: number
                    id:
                      type: number
                    version_id:
                      type: number
                    summary:
                      type: string
                    app:
                      type: string
                    kind:
                      $ref: "#/components/schemas/HubScriptKind"
                    score:
                      type: number
                  required:
                    - ask_id
                    - id
                    - version_id
                    - summary
                    - app
                    - kind
                    - score

  /w/{workspace}/scripts/list_search:
    get:
      summary: list scripts for search
      operationId: listSearchScript
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: script list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    path:
                      type: string
                    content:
                      type: string
                  required:
                    - path
                    - content

  /w/{workspace}/scripts/list:
    get:
      summary: list all scripts
      operationId: listScripts
      x-mcp-tool: true
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/OrderDesc"
        - $ref: "#/components/parameters/CreatedBy"
        - name: path_start
          description: mask to filter matching starting path
          in: query
          schema:
            type: string
        - name: path_exact
          description: mask to filter exact matching path
          in: query
          schema:
            type: string
        - name: first_parent_hash
          description: mask to filter scripts whom first direct parent has exact hash
          in: query
          schema:
            type: string
        - name: last_parent_hash
          description: |
            mask to filter scripts whom last parent in the chain has exact hash.
            Beware that each script stores only a limited number of parents. Hence
            the last parent hash for a script is not necessarily its top-most parent.
            To find the top-most parent you will have to jump from last to last hash
             until finding the parent
          in: query
          schema:
            type: string
        - name: parent_hash
          description: |
            is the hash present in the array of stored parent hashes for this script.
            The same warning applies than for last_parent_hash. A script only store a
            limited number of direct parent
          in: query
          schema:
            type: string
        - name: show_archived
          description: |
            (default false)
            show only the archived files.
            when multiple archived hash share the same path, only the ones with the latest create_at
            are
            ed.
          in: query
          schema:
            type: boolean
        - name: include_without_main
          description: |
            (default false)
            include scripts without an exported main function
          in: query
          schema:
            type: boolean
        - name: include_draft_only
          description: |
            (default false)
            include scripts that have no deployed version
          in: query
          schema:
            type: boolean
        - name: is_template
          description: |
            (default regardless)
            if true show only the templates
            if false show only the non templates
            if not defined, show all regardless of if the script is a template
          in: query
          schema:
            type: boolean
        - name: kinds
          description: |
            (default regardless)
            script kinds to filter, split by comma
          in: query
          schema:
            type: string
        - name: starred_only
          description: |
            (default false)
            show only the starred items
          in: query
          schema:
            type: boolean
        - name: with_deployment_msg
          description: |
            (default false)
            include deployment message
          in: query
          schema:
            type: boolean
        - name: languages
          in: query
          description: |
            Filter to only include scripts written in the given languages.
            Accepts multiple values as a comma-separated list.
          schema:
            type: string
        - name: without_description
          in: query
          description: |
            (default false)
            If true, the description field will be omitted from the response.
          schema:
            type: boolean
        - name: dedicated_worker
          in: query
          description: |
            (default regardless)
            If true, show only scripts with dedicated_worker enabled.
            If false, show only scripts with dedicated_worker disabled.
          schema:
            type: boolean
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label

      responses:
        "200":
          description: All scripts
          content:
            application/json:
              schema:
                type: array
                items:
                  allOf:
                    - $ref: "#/components/schemas/Script"
                    - type: object
                      properties:
                        is_draft:
                          type: boolean
                          description: |
                            True when the authed user has a draft for this
                            script — either no deployed row exists at this
                            path (draft-only) or the user saved a per-user
                            draft on top of the deployed row.
                        draft_path:
                          type: string
                          description: |
                            User-typed path the editor has staged but not
                            yet deployed. Surfaced for draft-only rows so
                            the home list can render the meaningful name
                            instead of the autogenerated
                            `u/{user}/draft_{uuid}` URL path. Omitted
                            when unchanged.
                        draft_users:
                          description: |
                            Workspace users (including the authed user, and
                            the legacy NULL-email row if any) who have a
                            per-user draft at this path. Drives the home
                            page's user-avatar circles inside the Draft
                            badge. Omitted when no drafts exist.
                          type: array
                          items:
                            type: object
                            properties:
                              username:
                                type: string
                                nullable: true

  /w/{workspace}/scripts/list_paths:
    get:
      summary: list all scripts paths
      operationId: listScriptPaths
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of script paths
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/drafts/list:
    get:
      summary: list every draft the current user has in this workspace, across all kinds
      operationId: listDrafts
      tags:
        - draft
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: all_users
          in: query
          description: List every draft in the workspace (all users), not just the current user's own + legacy rows. Other users' rows come back with `mine=false` (view-only).
          schema:
            type: boolean
        - name: compare_to_workspace
          in: query
          description: A fork passes its parent workspace id here to have each row flagged with `unchanged_from_parent`. Ignored unless it is exactly this workspace's parent.
          schema:
            type: string
      responses:
        "200":
          description: the user's drafts
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    kind:
                      $ref: "#/components/schemas/UserDraftItemKind"
                    path:
                      type: string
                    summary:
                      type: string
                      description: Best-effort, read from the draft JSON's `summary` field when the editor shape carries one.
                    draft_path:
                      type: string
                      description: User-typed friendly path from the draft JSON's `draft_path`, when set and different from the storage path (e.g. a never-deployed item parked at `u/{user}/draft_{uuid}`).
                    draft_only:
                      type: boolean
                      description: No deployed counterpart exists at this path — the draft is the whole item.
                    legacy_draft:
                      type: boolean
                      description: The listed draft is a legacy workspace-level row (email NULL) predating the per-user drafts migration. Only true when no per-user draft exists at this path.
                    created_at:
                      type: string
                      format: date-time
                    can_write:
                      type: boolean
                      description: Whether the current user may deploy/discard this draft (same check the deploy/discard endpoints enforce).
                    mine:
                      type: boolean
                      description: The row belongs to the current user (own draft or the legacy no-owner row) and is therefore actionable. Always true in the default listing; with `all_users=true`, other users' rows are false (view-only).
                    unchanged_from_parent:
                      type: boolean
                      description: Only present when `compare_to_workspace` was passed. True when this draft is identical to the parent's draft at the same path/kind/owner (cloned in on fork and never edited here).
                    draft_users:
                      description: |
                        Draft authors at this (path, kind) — the legacy NULL-email row surfaced as a null username.
                        Populated only for the shared full-page-editor kinds (script/flow/app/raw_app); omitted for
                        drawer kinds, which keep their drafts private. Feeds the Draft badge's owner-avatar circles.
                      type: array
                      items:
                        type: object
                        properties:
                          username:
                            type: string
                            nullable: true
                  required: [kind, path, draft_only, legacy_draft, created_at, can_write, mine]

  /w/{workspace}/drafts/get/{kind}/{path}:
    get:
      summary: fetch a single draft's content by workspace username (or the legacy workspace-level row)
      operationId: getDraftForUser
      tags:
        - draft
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: kind
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/UserDraftItemKind"
        - $ref: "#/components/parameters/ScriptPath"
        - name: username
          in: query
          required: false
          description: Workspace username of the draft owner. Omit to fetch the legacy workspace-level (NULL email) row.
          schema:
            type: string
      responses:
        "200":
          description: draft content
          content:
            application/json:
              schema:
                type: object
                properties:
                  value: {}
                  created_at:
                    type: string
                    format: date-time
                required: [value, created_at]
        "404":
          description: no draft for that owner at that path

  /w/{workspace}/drafts/get_own/{kind}/{path}:
    get:
      summary: fetch the current user's own draft content at a path (any kind)
      operationId: getOwnDraft
      tags:
        - draft
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: kind
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/UserDraftItemKind"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: the user's draft content, or null when none exists
          content:
            application/json:
              schema:
                nullable: true
                type: object
                properties:
                  value: {}
                  created_at:
                    type: string
                    format: date-time
                required: [value, created_at]

  /w/{workspace}/drafts/update/{kind}/{path}:
    post:
      summary: upsert (or clear) the current user's draft at a path
      operationId: updateDraft
      tags:
        - draft
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: kind
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/UserDraftItemKind"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                value:
                  nullable: true
                  description: Draft content to save. `null` (or omitted) signals a delete — the row is removed under the same conflict rules.
                last_sync:
                  type: string
                  format: date-time
                  description: Server timestamp of the client's last known sync for this draft. Omit on first save.
                force:
                  type: boolean
                  description: Skip the conflict check and overwrite the server copy.
                legacy:
                  type: boolean
                  description: Delete-only. Target the legacy workspace-level row (email NULL) instead of the current user's row. Used to discard a legacy draft from the review page.
                created_at:
                  type: string
                  format: date-time
                  description: Upsert-only override for the stored creation timestamp. Normal saves omit it (stamped server-side); the localStorage→DB migration passes the draft's original write time so migrated drafts keep their age.
      responses:
        "200":
          description: save result
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [saved, conflict]
                  current_timestamp:
                    type: string
                    format: date-time
                required: [status, current_timestamp]

  /w/{workspace}/drafts/migrate_legacy/{kind}/{path}:
    post:
      summary: resolve a legacy (workspace-level) draft (admin only)
      description: Delete a legacy draft (email NULL) or assign it to the authed admin as a per-user draft. Workspace admins / superadmins only.
      operationId: migrateLegacyDraft
      tags:
        - draft
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: kind
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/UserDraftItemKind"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  type: string
                  enum: [delete, assign_to_self]
                  description: delete the legacy draft, or take ownership of it.
              required: [action]
      responses:
        "200":
          description: migration result
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/scripts/create:
    post:
      summary: create script
      description: |
        Creates a new script when the path does not already exist.
        Creates a new version of an existing script when called with the same path and the current `parent_hash`.
      operationId: createScript
      x-mcp-tool: true
      x-mcp-instructions: "To create a NEW script, specify the path (e.g., 'f/my_folder/my_script'), the content (source code), and the language, and leave parent_hash unset. For TypeScript, use 'bun' unless deno-specific APIs are needed. To UPDATE an existing script, do NOT delete and recreate it: call this tool with the same path and set parent_hash to the script's current hash, which you can read from the `hash` field returned by getScriptByPath. This creates a new version while preserving the script's history."
      x-mcp-tool-include-fields:
        - path
        - parent_hash
        - content
        - language
        - summary
        - description
        - kind
        - tag
        - deployment_message
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Partially filled script
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewScript"

      responses:
        "201":
          description: script created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/scripts/toggle_workspace_error_handler/p/{path}:
    post:
      summary: Toggle ON and OFF the workspace error handler for a given script
      operationId: toggleWorkspaceErrorHandlerForScript
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: Workspace error handler enabled
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                muted:
                  type: boolean
      responses:
        "200":
          description: error handler toggled
          content:
            text/plain:
              schema:
                type: string

  /workers/custom_tags:
    get:
      summary: get all instance custom tags (tags are used to dispatch jobs to
        different worker groups)
      operationId: getCustomTags
      tags:
        - worker
      parameters:
        - name: show_workspace_restriction
          in: query
          schema:
            type: boolean
          required: false
      responses:
        "200":
          description: list of custom tags
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/workers/custom_tags:
    get:
      summary: get custom tags available for this workspace
      operationId: getCustomTagsForWorkspace
      tags:
        - worker
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of custom tags for workspace
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /workers/get_default_tags:
    get:
      summary: get all instance default tags
      operationId: geDefaultTags
      tags:
        - worker
      responses:
        "200":
          description: list of default tags
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /workers/is_default_tags_per_workspace:
    get:
      summary: is default tags per workspace
      operationId: isDefaultTagsPerWorkspace
      tags:
        - worker
      responses:
        "200":
          description: is the default tags per workspace
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/workspace_dependencies/create:
    post:
      summary: create workspace dependencies
      operationId: createWorkspaceDependencies
      tags:
        - workspace_dependencies
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: New workspace dependencies
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewWorkspaceDependencies"

      responses:
        "201":
          description: workspace dependencies created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/workspace_dependencies/archive/{language}:
    post:
      summary: archive workspace dependencies (require admin)
      operationId: archiveWorkspaceDependencies
      tags:
        - workspace_dependencies
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: language
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/ScriptLang"
        - name: name
          in: query
          required: false
          schema:
            type: string

      responses:
        "200":
          description: result
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspace_dependencies/delete/{language}:
    post:
      summary: delete workspace dependencies (require admin)
      operationId: deleteWorkspaceDependencies
      tags:
        - workspace_dependencies
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: language
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/ScriptLang"
        - name: name
          in: query
          required: false
          schema:
            type: string

      responses:
        "200":
          description: result
          content:
            application/json:
              schema: {}

  /w/{workspace}/workspace_dependencies/list:
    get:
      summary: list all workspace dependencies
      operationId: listWorkspaceDependencies
      tags:
        - workspace_dependencies
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: All workspace dependencies
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WorkspaceDependencies"

  /w/{workspace}/workspace_dependencies/get_latest/{language}:
    get:
      summary: get latest workspace dependencies by language and name
      operationId: getLatestWorkspaceDependencies
      tags:
        - workspace_dependencies
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: language
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/ScriptLang"
        - name: name
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Latest workspace dependencies
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkspaceDependencies"

  /w/{workspace}/scripts/archive/p/{path}:
    post:
      summary: archive script by path
      operationId: archiveScriptByPath
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script archived
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/scripts/archive/h/{hash}:
    post:
      summary: archive script by hash
      operationId: archiveScriptByHash
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptHash"
      responses:
        "200":
          description: script details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Script"

  /w/{workspace}/scripts/delete/h/{hash}:
    post:
      summary: delete script by hash (erase content but keep hash, require admin)
      operationId: deleteScriptByHash
      x-mcp-tool: true
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptHash"
      responses:
        "200":
          description: script details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Script"

  /w/{workspace}/scripts/delete/p/{path}:
    post:
      summary: delete script at a given path (require admin)
      operationId: deleteScriptByPath
      x-mcp-tool: true
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - name: keep_captures
          description: keep captures
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: script path
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/scripts/delete_bulk:
    delete:
      summary: delete scripts in bulk
      operationId: deleteScriptsBulk
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: paths to delete
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                paths:
                  type: array
                  items:
                    type: string
              required:
                - paths
      responses:
        "200":
          description: deleted paths
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/scripts/get/p/{path}:
    get:
      summary: get script by path
      operationId: getScriptByPath
      x-mcp-tool: true
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - name: with_starred_info
          in: query
          schema:
            type: boolean
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: script details
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Script"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/scripts/get_triggers_count/{path}:
    get:
      summary: get triggers count of script
      operationId: getTriggersCountOfScript
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: triggers count
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TriggersCount"

  /w/{workspace}/scripts/list_tokens/{path}:
    get:
      summary: get tokens with script scope
      operationId: listTokensOfScript
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: tokens list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/TruncatedToken"

  /w/{workspace}/scripts/history/p/{path}:
    get:
      summary: get history of a script by path
      operationId: getScriptHistoryByPath
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script history
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ScriptHistory"

  /w/{workspace}/scripts/list_paths_from_workspace_runnable/{path}:
    get:
      summary: list script paths using provided script as a relative import
      operationId: listScriptPathsFromWorkspaceRunnable
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: list of script paths
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/scripts/get_latest_version/{path}:
    get:
      summary: get scripts's latest version (hash)
      operationId: getScriptLatestVersion
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      tags:
        - script
      responses:
        "200":
          description: Script version/hash
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScriptHistory"

  /w/{workspace}/scripts/history_update/h/{hash}/p/{path}:
    post:
      summary: update history of a script
      operationId: updateScriptHistory
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptHash"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: Script deployment message
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                deployment_msg:
                  type: string
      responses:
        "200":
          description: success
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/scripts/list_dedicated_with_deps:
    get:
      summary: list dedicated worker scripts with workspace dependency annotations
      operationId: listDedicatedWithDeps
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of dedicated scripts with their workspace dependency names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    path:
                      type: string
                    language:
                      type: string
                      enum:
                        - python3
                        - deno
                        - go
                        - bash
                        - powershell
                        - postgresql
                        - mysql
                        - bigquery
                        - snowflake
                        - mssql
                        - graphql
                        - nativets
                        - bun
                        - bunnative
                        - php
                        - rust
                        - ansible
                        - csharp
                        - oracledb
                        - duckdb
                        - java
                        - ruby
                    workspace_dep_names:
                      type: array
                      items:
                        type: string
                  required:
                    - path
                    - language
                    - workspace_dep_names

  /w/{workspace}/scripts/raw/p/{path}:
    get:
      summary: raw script by path
      operationId: rawScriptByPath
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script content
          content:
            text/plain:
              schema:
                type: string

  /scripts_u/tokened_raw/{workspace}/{token}/{path}:
    get:
      summary:
        raw script by path with a token (mostly used by lsp to be used with
        import maps to resolve scripts)
      operationId: rawScriptByPathTokened
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Token"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script content
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/scripts/exists/p/{path}:
    get:
      summary: exists script by path
      operationId: existsScriptByPath
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: does it exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/scripts/get/h/{hash}:
    get:
      summary: get script by hash
      operationId: getScriptByHash
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptHash"
        - name: with_starred_info
          in: query
          schema:
            type: boolean
        - name: authed
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: script details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Script"

  /w/{workspace}/scripts/raw/h/{path}:
    get:
      summary: raw script by hash
      operationId: rawScriptByHash
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: script content
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/scripts/deployment_status/h/{hash}:
    get:
      summary: get script deployment status
      operationId: getScriptDeploymentStatus
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptHash"
      responses:
        "200":
          description: script details
          content:
            application/json:
              schema:
                type: object
                properties:
                  lock:
                    type: string
                  lock_error_logs:
                    type: string
                  job_id:
                    type: string
                    format: uuid

  /w/{workspace}/scripts/ci_test_results/{kind}/{path}:
    get:
      summary: get CI test results for a script, flow, or resource
      operationId: getCiTestResults
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: kind
          in: path
          required: true
          schema:
            type: string
            enum: [script, flow, resource]
        - name: path
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: CI test results
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CiTestResult"

  /w/{workspace}/scripts/ci_test_results_batch:
    post:
      summary: get CI test results for multiple items
      operationId: getCiTestResultsBatch
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - items
              properties:
                items:
                  type: array
                  items:
                    type: object
                    required:
                      - path
                      - kind
                    properties:
                      path:
                        type: string
                      kind:
                        type: string
                        enum: [script, flow, resource]
      responses:
        "200":
          description: CI test results by item key
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: array
                  items:
                    $ref: "#/components/schemas/CiTestResult"

  /w/{workspace}/scripts/check_schema_contracts:
    post:
      summary: check a script's asset references against captured producer schemas
      description: |
        Save-time schema-contract check for data pipelines: validates the given
        script content's asset references (body column reads, `// column` lineage,
        `// data_test relationships`) against the latest captured producer schemas
        and returns warnings. Warnings never block a save/deploy; an asset whose
        producer declares `on_schema_change=ignore` is suppressed to a single
        informational entry.
      operationId: checkSchemaContracts
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - language
                - content
              properties:
                language:
                  $ref: "#/components/schemas/ScriptLang"
                content:
                  type: string
      responses:
        "200":
          description: contract warnings (empty when all references match)
          content:
            application/json:
              schema:
                type: object
                required:
                  - warnings
                properties:
                  warnings:
                    type: array
                    items:
                      $ref: "#/components/schemas/ContractWarning"

  /w/{workspace}/scripts/raw_temp/store:
    post:
      summary: store raw script content temporarily for CLI lock generation
      operationId: storeRawScriptTemp
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: script content to store
        required: true
        content:
          application/json:
            schema:
              type: string
      responses:
        "200":
          description: hash of stored content
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/scripts/raw_temp/diff:
    post:
      summary: diff local script hashes against deployed versions
      operationId: diffRawScriptsWithDeployed
      tags:
        - script
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: scripts and workspace deps to diff against deployed versions
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - scripts
              properties:
                scripts:
                  description: map of script path to SHA256 content hash
                  type: object
                  additionalProperties:
                    type: string
                workspace_deps:
                  description: workspace dependencies to diff
                  type: array
                  items:
                    type: object
                    required:
                      - path
                      - language
                      - hash
                    properties:
                      path:
                        description: CLI path (e.g. dependencies/package.json)
                        type: string
                      language:
                        $ref: "#/components/schemas/ScriptLang"
                      name:
                        description: named workspace dependency (null for default)
                        type: string
                      hash:
                        description: SHA256 content hash
                        type: string
      responses:
        "200":
          description: list of paths that differ from deployed versions
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/jobs/list_selected_job_groups:
    # We use post because sending a huge array as a query param can produce
    # URLs that may be too long
    post:
      summary: list selected jobs script/flow schemas grouped by (kind, path)
      operationId: listSelectedJobGroups
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: string
                format: uuid
      responses:
        "200":
          description: result
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    kind:
                      type: string
                      enum: ["script", "flow"]
                    script_path:
                      type: string
                    latest_schema:
                      type: object
                    schemas:
                      type: array
                      items:
                        type: object
                        properties:
                          schema:
                            type: object
                          script_hash:
                            type: string
                          job_ids:
                            type: array
                            items:
                              type: string
                        required: [schema, script_hash, job_ids]
                  required:
                    - kind
                    - script_path
                    - latest_schema
                    - schemas

  /w/{workspace}/jobs/run/p/{path}:
    post:
      summary: run script by path
      operationId: runScriptByPath
      x-mcp-tool: true
      x-mcp-instructions: "You should first use getScriptByPath to retrieve the script's schema and understand what arguments are expected."
      x-mcp-tool-include-query-params: []
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - name: scheduled_for
          description: when to schedule this job (leave empty for immediate run)
          in: query
          schema:
            type: string
            format: date-time
        - name: scheduled_in_secs
          description: schedule the script to execute in the number of seconds starting now
          in: query
          schema:
            type: integer
        - name: skip_preprocessor
          description: skip the preprocessor
          in: query
          schema:
            type: boolean
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - name: invisible_to_owner
          description: make the run invisible to the the script owner (default false)
          in: query
          schema:
            type: boolean
      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run_wait_result/p/{path}:
    post:
      summary: run script by path
      operationId: runWaitResultScriptByPath
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/SkipPreprocessor"

      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

    get:
      summary: run script by path with get
      operationId: runWaitResultScriptByPathGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/Payload"
        - $ref: "#/components/parameters/SkipPreprocessor"

      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/run_wait_result/f/{path}:
    post:
      summary: run flow by path and wait until completion
      operationId: runWaitResultFlowByPath
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid

      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/run_wait_result/fv/{version}:
    post:
      summary: run flow by version and wait until completion
      operationId: runWaitResultFlowByVersion
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: version
          description: flow version ID
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid

      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

    get:
      summary: run flow by version with GET and wait until completion
      operationId: runWaitResultFlowByVersionGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: version
          description: flow version ID
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/Payload"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid

      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/run_and_stream/f/{path}:
    post:
      summary: run flow by path and stream updates via SSE
      operationId: runAndStreamFlowByPath
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      requestBody:
        description: flow args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

    get:
      summary: run flow by path with GET and stream updates via SSE
      operationId: runAndStreamFlowByPathGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/Payload"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

  /w/{workspace}/jobs/run_and_stream/fv/{version}:
    post:
      summary: run flow by version and stream updates via SSE
      operationId: runAndStreamFlowByVersion
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: version
          description: flow version ID
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      requestBody:
        description: flow args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

    get:
      summary: run flow by version with GET and stream updates via SSE
      operationId: runAndStreamFlowByVersionGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: version
          description: flow version ID
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/Payload"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

  /w/{workspace}/jobs/run_and_stream/p/{path}:
    post:
      summary: run script by path and stream updates via SSE
      operationId: runAndStreamScriptByPath
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

    get:
      summary: run script by path with GET and stream updates via SSE
      operationId: runAndStreamScriptByPathGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/Payload"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

  /w/{workspace}/jobs/run_and_stream/h/{hash}:
    post:
      summary: run script by hash and stream updates via SSE
      operationId: runAndStreamScriptByHash
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: hash
          in: path
          required: true
          schema:
            type: string
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

    get:
      summary: run script by hash with GET and stream updates via SSE
      operationId: runAndStreamScriptByHashGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: hash
          in: path
          required: true
          schema:
            type: string
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - $ref: "#/components/parameters/QueueLimit"
        - $ref: "#/components/parameters/Payload"
        - $ref: "#/components/parameters/SkipPreprocessor"
        - name: poll_delay_ms
          description: delay between polling for job updates in milliseconds
          in: query
          schema:
            type: integer
            format: int64

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

  /w/{workspace}/jobs/result_by_id/{flow_job_id}/{node_id}:
    get:
      summary: get job result by id
      operationId: resultById
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: flow_job_id
          in: path
          required: true
          schema:
            type: string
        - name: node_id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/job_view_token/{id}:
    get:
      summary: mint a read-only share token for a job
      description: >
        Returns a stateless `{job_id}.{hmac}` token that grants an authenticated
        workspace member read access to this job (and its flow subtree) via a
        `view_token` query param or `X-View-Token` header. Only callable by a user
        who can already read the job.
      operationId: getJobViewToken
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: the share read token
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flows/list_paths:
    get:
      summary: list all flow paths
      operationId: listFlowPaths
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of flow paths
          content:
            text/plain:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/flows/list_search:
    get:
      summary: list flows for search
      operationId: listSearchFlow
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: flow list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    path:
                      type: string
                    value: {}
                  required:
                    - path
                    - value

  /w/{workspace}/flows/list:
    get:
      summary: list all flows
      operationId: listFlows
      x-mcp-tool: true
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/OrderDesc"
        - $ref: "#/components/parameters/CreatedBy"
        - name: path_start
          description: mask to filter matching starting path
          in: query
          schema:
            type: string
        - name: path_exact
          description: mask to filter exact matching path
          in: query
          schema:
            type: string
        - name: show_archived
          description: |
            (default false)
            show only the archived files.
            when multiple archived hash share the same path, only the ones with the latest create_at
            are displayed.
          in: query
          schema:
            type: boolean
        - name: starred_only
          description: |
            (default false)
            show only the starred items
          in: query
          schema:
            type: boolean
        - name: include_draft_only
          description: |
            (default false)
            include items that have no deployed version
          in: query
          schema:
            type: boolean
        - name: with_deployment_msg
          description: |
            (default false)
            include deployment message
          in: query
          schema:
            type: boolean
        - name: without_description
          in: query
          description: |
            (default false)
            If true, the description field will be omitted from the response.
          schema:
            type: boolean
        - name: dedicated_worker
          in: query
          description: |
            (default regardless)
            If true, show only flows with dedicated_worker enabled.
            If false, show only flows with dedicated_worker disabled.
          schema:
            type: boolean
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
      responses:
        "200":
          description: All flow
          content:
            application/json:
              schema:
                type: array
                items:
                  allOf:
                    - $ref: "#/components/schemas/Flow"
                    - type: object
                      properties:
                        draft_only:
                          type: boolean
                        is_draft:
                          type: boolean
                          description: |
                            True when the authed user has a draft for this
                            flow — either no deployed row exists at this
                            path (draft-only) or the user saved a per-user
                            draft on top of the deployed row.
                        draft_path:
                          type: string
                          description: |
                            User-typed path the editor has staged but not
                            yet deployed. Sourced from the draft JSON's
                            `draft_path` field (the editor only writes it
                            when the typed path differs from the deployed
                            one). Lets the home list render the meaningful
                            name instead of the autogenerated
                            `u/{user}/draft_{uuid}` URL path. Omitted when
                            unchanged.
                        draft_users:
                          description: |
                            Workspace users (including the authed user, and
                            the legacy NULL-email row if any) who have a
                            per-user draft at this path. Drives the home
                            page's user-avatar circles inside the Draft
                            badge. Omitted when no drafts exist.
                          type: array
                          items:
                            type: object
                            properties:
                              username:
                                type: string
                                nullable: true

  /w/{workspace}/flows/history/p/{path}:
    get:
      summary: get flow history by path
      operationId: getFlowHistory
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      tags:
        - flow
      responses:
        "200":
          description: Flow history
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/FlowVersion"

  /w/{workspace}/flows/get_latest_version/{path}:
    get:
      summary: get flow's latest version
      operationId: getFlowLatestVersion
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      tags:
        - flow
      responses:
        "200":
          description: Flow version
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FlowVersion"

  /w/{workspace}/flows/list_paths_from_workspace_runnable/{runnable_kind}/{path}:
    get:
      summary: list flow paths from workspace runnable
      operationId: listFlowPathsFromWorkspaceRunnable
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableKind"
        - $ref: "#/components/parameters/ScriptPath"
        - name: match_path_start
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: list of flow paths
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/flows/get/v/{version}:
    get:
      summary: get flow version
      operationId: getFlowVersion
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: version
          in: path
          required: true
          schema:
            type: number
      tags:
        - flow
      responses:
        "200":
          description: flow details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Flow"

  /w/{workspace}/flows/history_update/v/{version}:
    post:
      summary: update flow history
      operationId: updateFlowHistory
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: version
          in: path
          required: true
          schema:
            type: number
      requestBody:
        description: Flow deployment message
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                deployment_msg:
                  type: string
              required:
                - deployment_msg
      tags:
        - flow
      responses:
        "200":
          description: success
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flows/get/{path}:
    get:
      summary: get flow by path
      operationId: getFlowByPath
      x-mcp-tool: true
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - name: with_starred_info
          in: query
          schema:
            type: boolean
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: flow details
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Flow"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/flows/deployment_status/p/{path}:
    get:
      summary: get flow deployment status
      operationId: getFlowDeploymentStatus
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: flow status
          content:
            application/json:
              schema:
                type: object
                properties:
                  lock_error_logs:
                    type: string
                  job_id:
                    type: string
                    format: uuid

  /w/{workspace}/flows/get_triggers_count/{path}:
    get:
      summary: get triggers count of flow
      operationId: getTriggersCountOfFlow
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: triggers count
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TriggersCount"

  /w/{workspace}/flows/list_tokens/{path}:
    get:
      summary: get tokens with flow scope
      operationId: listTokensOfFlow
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: tokens list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/TruncatedToken"

  /w/{workspace}/flows/toggle_workspace_error_handler/{path}:
    post:
      summary: Toggle ON and OFF the workspace error handler for a given flow
      operationId: toggleWorkspaceErrorHandlerForFlow
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: Workspace error handler enabled
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                muted:
                  type: boolean
      responses:
        "200":
          description: error handler toggled
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flows/exists/{path}:
    get:
      summary: exists flow by path
      operationId: existsFlowByPath
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: flow details
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/flows/create:
    post:
      summary: create flow
      operationId: createFlow
      x-mcp-tool: true
      x-mcp-tool-include-fields:
        - path
        - summary
        - description
        - value
        - schema
        - tag
        - deployment_message
      x-mcp-tool-opaque-fields:
        - value
        - schema
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Partially filled flow
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/OpenFlowWPath"
                - type: object
                  properties:
                    deployment_message:
                      type: string
                    skip_draft_deletion:
                      type: boolean
                      description: "When true (set by the CLI / git sync), deploying this flow does not delete an existing user draft at the same path."
      responses:
        "201":
          description: flow created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flows/update/{path}:
    post:
      summary: update flow
      operationId: updateFlow
      x-mcp-tool: true
      x-mcp-tool-include-fields:
        - path
        - summary
        - description
        - value
        - schema
        - tag
        - deployment_message
      x-mcp-tool-opaque-fields:
        - value
        - schema
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: Partially filled flow
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/EditFlow"
                - type: object
                  properties:
                    deployment_message:
                      type: string
                    skip_draft_deletion:
                      type: boolean
                      description: "When true (set by the CLI / git sync), deploying this flow does not delete an existing user draft at the same path."

      responses:
        "200":
          description: flow updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flows/archive/{path}:
    post:
      summary: archive flow by path
      operationId: archiveFlowByPath
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: archiveFlow
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                archived:
                  type: boolean
      responses:
        "200":
          description: flow archived
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flows/delete/{path}:
    delete:
      summary: delete flow by path
      operationId: deleteFlowByPath
      x-mcp-tool: true
      tags:
        - flow
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - name: keep_captures
          description: keep captures
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: flow delete
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flow_conversations/list:
    get:
      summary: list flow conversations
      operationId: listFlowConversations
      tags:
        - flow_conversations
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: flow_path
          description: filter conversations by flow path
          in: query
          schema:
            type: string
      responses:
        "200":
          description: flow conversations list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/FlowConversation"

  /w/{workspace}/flow_conversations/delete/{conversation_id}:
    delete:
      summary: delete flow conversation
      operationId: deleteFlowConversation
      tags:
        - flow_conversations
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: conversation_id
          description: conversation id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: flow conversation deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/flow_conversations/{conversation_id}/messages:
    get:
      summary: list conversation messages
      operationId: listConversationMessages
      tags:
        - flow_conversations
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: conversation_id
          description: conversation id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: after_seq
          description: Message sequence cursor to fetch only the messages after that cursor
          in: query
          required: false
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: conversation messages
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/FlowConversationMessage"

  /w/{workspace}/path_autocomplete/list_paths:
    get:
      summary: list all paths in a workspace for client-side autocomplete
      description: |
        Returns the flat list of all item paths visible to the caller across
        scripts, flows, apps, raw apps, variables, and resources. Intended to
        feed an entirely client-side path autocomplete UI: the frontend fetches
        once (server caches per workspace for 60s) and performs all prefix/segment
        computation locally. Capped at 20,000 paths (5,000 per table).
      operationId: listPathAutocompletePaths
      tags:
        - path_autocomplete
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: force
          description: |
            bypass the server-side cache and re-query the DB, refreshing the
            cache. Used right after a deploy so the new path appears immediately.
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: deduplicated path list, sorted lexicographically
          content:
            application/json:
              schema:
                type: object
                properties:
                  paths:
                    type: array
                    items:
                      type: string
                required:
                  - paths

  /w/{workspace}/raw_apps/list:
    get:
      summary: list all raw apps
      operationId: listRawApps
      tags:
        - raw_app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/OrderDesc"
        - $ref: "#/components/parameters/CreatedBy"
        - name: path_start
          description: mask to filter matching starting path
          in: query
          schema:
            type: string
        - name: path_exact
          description: mask to filter exact matching path
          in: query
          schema:
            type: string
        - name: starred_only
          description: |
            (default false)
            show only the starred items
          in: query
          schema:
            type: boolean
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: All raw apps
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ListableRawApp"

  /w/{workspace}/shared_ui/get:
    get:
      summary: get the workspace shared UI folder (full content)
      operationId: getSharedUi
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: shared UI content
          content:
            application/json:
              schema:
                type: object
                required:
                  - files
                  - version
                  - edited_at
                  - edited_by
                properties:
                  files:
                    type: object
                    additionalProperties:
                      type: string
                  version:
                    type: integer
                    format: int64
                  edited_at:
                    type: string
                    format: date-time
                  edited_by:
                    type: string

  /w/{workspace}/shared_ui/list:
    get:
      summary: list paths/sizes of the workspace shared UI folder
      operationId: listSharedUi
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: shared UI listing
          content:
            application/json:
              schema:
                type: object
                required:
                  - paths
                  - sizes
                  - version
                  - edited_at
                  - edited_by
                properties:
                  paths:
                    type: array
                    items:
                      type: string
                  sizes:
                    type: object
                    additionalProperties:
                      type: integer
                      format: int64
                  version:
                    type: integer
                    format: int64
                  edited_at:
                    type: string
                    format: date-time
                  edited_by:
                    type: string

  /w/{workspace}/shared_ui/version:
    get:
      summary: get the current version of the workspace shared UI folder
      operationId: getSharedUiVersion
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: shared UI version
          content:
            application/json:
              schema:
                type: object
                required:
                  - version
                properties:
                  version:
                    type: integer
                    format: int64

  /w/{workspace}/shared_ui:
    put:
      summary: replace the workspace shared UI folder (admin only)
      operationId: updateSharedUi
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - files
              properties:
                files:
                  type: object
                  additionalProperties:
                    type: string
      responses:
        "200":
          description: updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/ai_skills/list:
    get:
      summary: list the workspace AI chat skills (name + description only)
      operationId: listAiSkills
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: skill listing
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required:
                    - name
                    - description
                  properties:
                    name:
                      type: string
                    description:
                      type: string

  /w/{workspace}/ai_skills/get/{name}:
    get:
      summary: get a workspace AI chat skill including its instructions
      operationId: getAiSkill
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: skill
          content:
            application/json:
              schema:
                type: object
                required:
                  - name
                  - description
                  - instructions
                properties:
                  name:
                    type: string
                  description:
                    type: string
                  instructions:
                    type: string

  /w/{workspace}/ai_skills/upload:
    post:
      summary: upsert workspace AI chat skills (admin only)
      operationId: uploadAiSkills
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - skills
              properties:
                skills:
                  type: array
                  maxItems: 50
                  items:
                    type: object
                    required:
                      - name
                      - description
                      - instructions
                    properties:
                      name:
                        type: string
                        minLength: 1
                        maxLength: 64
                        pattern: "^[a-z0-9-]+$"
                      description:
                        type: string
                        minLength: 1
                        maxLength: 1024
                      instructions:
                        type: string
                        minLength: 1
                        maxLength: 65536
      responses:
        "200":
          description: uploaded
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/ai_skills/delete/{name}:
    delete:
      summary: delete a workspace AI chat skill (admin only)
      operationId: deleteAiSkill
      tags:
        - workspace
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/get_data/v/{secretWithExtension}:
    get:
      summary: get raw app data by
      operationId: getRawAppData
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: secretWithExtension
          in: path
          required: true
          description: >-
            App version secret suffixed with the requested file type extension.
            Supported extensions are `.js` (JavaScript bundle), `.css`
            (stylesheet), and `.html` (sandboxed wrapper document).
          schema:
            type: string
      responses:
        "200":
          description: app details
          content:
            text/javascript:
              schema:
                type: string
            text/css:
              schema:
                type: string
            text/html:
              schema:
                type: string

  /w/{workspace}/apps/list_search:
    get:
      summary: list apps for search
      operationId: listSearchApp
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: app list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    path:
                      type: string
                    value: {}
                  required:
                    - path
                    - value

  /w/{workspace}/apps/list:
    get:
      summary: list all apps
      operationId: listApps
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/OrderDesc"
        - $ref: "#/components/parameters/CreatedBy"
        - name: path_start
          description: mask to filter matching starting path
          in: query
          schema:
            type: string
        - name: path_exact
          description: mask to filter exact matching path
          in: query
          schema:
            type: string
        - name: starred_only
          description: |
            (default false)
            show only the starred items
          in: query
          schema:
            type: boolean
        - name: include_draft_only
          description: |
            (default false)
            include items that have no deployed version
          in: query
          schema:
            type: boolean
        - name: with_deployment_msg
          description: |
            (default false)
            include deployment message
          in: query
          schema:
            type: boolean
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
      responses:
        "200":
          description: All apps
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ListableApp"

  /w/{workspace}/apps/create:
    post:
      summary: create app
      operationId: createApp
      x-mcp-tool: true
      x-mcp-tool-include-fields:
        - path
        - value
        - summary
        - policy
        - deployment_message
      x-mcp-tool-opaque-fields:
        - value
        - policy
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new app
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: string
                value: {}
                summary:
                  type: string
                policy:
                  $ref: "#/components/schemas/Policy"
                deployment_message:
                  type: string
                custom_path:
                  type: string
                preserve_on_behalf_of:
                  type: boolean
                  description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original on_behalf_of value in the policy instead of overwriting it."
                labels:
                  type: array
                  items:
                    type: string
                skip_draft_deletion:
                  type: boolean
                  description: "When true (set by the CLI / git sync), deploying this app does not delete an existing user draft at the same path."
              required:
                - path
                - value
                - summary
                - policy
      responses:
        "201":
          description: app created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/create_raw:
    post:
      summary: create app raw
      operationId: createAppRaw
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new app
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                app:
                  type: object
                  properties:
                    path:
                      type: string
                    value: {}
                    summary:
                      type: string
                    policy:
                      $ref: "#/components/schemas/Policy"
                    deployment_message:
                      type: string
                    custom_path:
                      type: string
                    preserve_on_behalf_of:
                      type: boolean
                      description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original on_behalf_of value in the policy instead of overwriting it."
                    labels:
                      type: array
                      items:
                        type: string
                    skip_draft_deletion:
                      type: boolean
                      description: "When true (set by the CLI / git sync), deploying this app does not delete an existing user draft at the same path."
                  required:
                    - path
                    - value
                    - summary
                    - policy
                js:
                  type: string
                css:
                  type: string
      responses:
        "201":
          description: app created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/exists/{path}:
    get:
      summary: does an app exisst at path
      operationId: existsApp
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: app exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/apps/get/p/{path}:
    get:
      summary: get app by path
      operationId: getAppByPath
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - name: with_starred_info
          in: query
          schema:
            type: boolean
        - $ref: "#/components/parameters/GetDraft"
        - name: raw_app
          in: query
          description: |
            When no deployed app exists at this path and `get_draft` is set,
            disambiguates which draft kind (`raw_app` or `app`) to look up.
            Ignored when a deployed row exists.
          schema:
            type: boolean
      responses:
        "200":
          description: app details
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/AppWithLastVersion"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/apps/embed_token/p/{path}:
    get:
      summary: get app embed token by path
      operationId: getAppEmbedTokenByPath
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: embed token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmbedTokenResponse"

  /w/{workspace}/apps/get/lite/{path}:
    get:
      summary: get app lite by path
      operationId: getAppLiteByPath
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: app lite details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AppWithLastVersion"

  /w/{workspace}/apps/history/p/{path}:
    get:
      summary: get app history by path
      operationId: getAppHistoryByPath
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: app history
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AppHistory"

  /w/{workspace}/apps/get_latest_version/{path}:
    get:
      summary: get apps's latest version
      operationId: getAppLatestVersion
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      tags:
        - app
      responses:
        "200":
          description: App version
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AppHistory"
  /w/{workspace}/apps/list_paths_from_workspace_runnable/{runnable_kind}/{path}:
    get:
      summary: list app paths from workspace runnable
      operationId: listAppPathsFromWorkspaceRunnable
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableKind"
        - $ref: "#/components/parameters/ScriptPath"
      responses:
        "200":
          description: list of app paths
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/apps/history_update/a/{id}/v/{version}:
    post:
      summary: update app history
      operationId: updateAppHistory
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/PathId"
        - $ref: "#/components/parameters/PathVersion"
      requestBody:
        description: App deployment message
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                deployment_msg:
                  type: string
      responses:
        "200":
          description: success
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps_u/public_app/{path}:
    get:
      summary: get public app by secret
      operationId: getPublicAppBySecret
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: app details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AppWithLastVersion"

  /w/{workspace}/apps_u/embed_token/{secret}:
    get:
      summary: get app embed token by secret
      operationId: getAppEmbedTokenBySecret
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: secret
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: embed token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EmbedTokenResponse"

  /w/{workspace}/apps_u/public_resource/{path}:
    get:
      summary: get public resource
      operationId: get public resource
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: resource value
          content:
            application/json:
              schema: {}

  /w/{workspace}/apps/secret_of/{path}:
    get:
      summary: get public secret of app
      operationId: getPublicSecretOfApp
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: app secret
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/secret_of_latest_version/{path}:
    get:
      summary: get public secret of latest version of an app bundle
      operationId: getPublicSecretOfLatestVersionOfApp
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: app secret
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/get/v/{id}:
    get:
      summary: get app by version
      operationId: getAppByVersion
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/PathId"
      responses:
        "200":
          description: app details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AppWithLastVersion"

  /w/{workspace}/apps/delete/{path}:
    delete:
      summary: delete app
      operationId: deleteApp
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: app deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/update/{path}:
    post:
      summary: update app
      operationId: updateApp
      x-mcp-tool: true
      x-mcp-tool-include-fields:
        - path
        - value
        - summary
        - policy
        - deployment_message
      x-mcp-tool-opaque-fields:
        - value
        - policy
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: update app
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: string
                summary:
                  type: string
                value: {}
                policy:
                  $ref: "#/components/schemas/Policy"
                deployment_message:
                  type: string
                custom_path:
                  type: string
                preserve_on_behalf_of:
                  type: boolean
                  description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original on_behalf_of value in the policy instead of overwriting it."
                labels:
                  type: array
                  items:
                    type: string
                skip_draft_deletion:
                  type: boolean
                  description: "When true (set by the CLI / git sync), deploying this app does not delete an existing user draft at the same path."
      responses:
        "200":
          description: app updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/update_raw/{path}:
    post:
      summary: update app
      operationId: updateAppRaw
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: update app
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                app:
                  type: object
                  properties:
                    path:
                      type: string
                    summary:
                      type: string
                    value: {}
                    policy:
                      $ref: "#/components/schemas/Policy"
                    deployment_message:
                      type: string
                    custom_path:
                      type: string
                    preserve_on_behalf_of:
                      type: boolean
                      description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original on_behalf_of value in the policy instead of overwriting it."
                    labels:
                      type: array
                      items:
                        type: string
                    skip_draft_deletion:
                      type: boolean
                      description: "When true (set by the CLI / git sync), deploying this app does not delete an existing user draft at the same path."
                js:
                  type: string
                css:
                  type: string
      responses:
        "200":
          description: app updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps/custom_path_exists/{custom_path}:
    get:
      summary: check if custom path exists
      operationId: customPathExists
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/CustomPath"
      responses:
        "200":
          description: custom path exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/apps/sign_s3_objects:
    post:
      summary: sign s3 objects (caller must have S3 read permission on each key); the signed URLs can then be used by anonymous users in public apps
      operationId: signS3Objects
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: s3 objects to sign
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                s3_objects:
                  type: array
                  items:
                    $ref: "#/components/schemas/S3Object"
              required:
                - s3_objects
      responses:
        "200":
          description: signed s3 objects
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/S3Object"

  /w/{workspace}/apps_u/execute_component/{path}:
    post:
      summary: executeComponent
      operationId: executeComponent
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: update app
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                component:
                  type: string
                #script: script/<path>
                #flow: flow/<path>
                path:
                  type: string
                version:
                  type: integer
                args: {}
                raw_code:
                  type: object
                  properties:
                    content:
                      type: string
                    language:
                      type: string
                    path:
                      type: string
                    lock:
                      type: string
                    cache_ttl:
                      type: integer
                    tag:
                      type: string
                  required:
                    - content
                    - language
                id:
                  type: integer
                force_viewer_static_fields:
                  type: object
                force_viewer_one_of_fields:
                  type: object
                force_viewer_allow_user_resources:
                  type: array
                  items:
                    type: string
                force_viewer_sensitive_inputs:
                  type: array
                  items:
                    type: string
                force_viewer_delete_after_secs:
                  type: integer
                run_query_params:
                  type: object
                  description: Runnable query parameters
                temp_script_refs:
                  type: object
                  nullable: true
                  description: "Map of relative-import script path -> temp storage hash. Only honored for inline-script (raw_code) execution so app dev resolves those imports from not-yet-deployed local content."
                  additionalProperties:
                    type: string
              required:
                - args
                - component

      responses:
        "200":
          description: job uuid
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps_u/upload_s3_file/{path}:
    post:
      summary: upload s3 file from app
      operationId: uploadS3FileFromApp
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: file_key
          in: query
          required: false
          schema:
            type: string
        - name: file_extension
          in: query
          required: false
          schema:
            type: string
        - name: s3_resource_path
          in: query
          required: false
          schema:
            type: string
        - name: resource_type
          in: query
          required: false
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - name: content_type
          in: query
          schema:
            type: string
        - name: content_disposition
          in: query
          schema:
            type: string
      requestBody:
        description: File content
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
      responses:
        "200":
          description: file uploaded
          content:
            application/json:
              schema:
                type: object
                properties:
                  file_key:
                    type: string
                  delete_token:
                    type: string
                required:
                  - file_key
                  - delete_token

  /w/{workspace}/apps_u/delete_s3_file:
    delete:
      summary: delete s3 file from app
      operationId: deleteS3FileFromApp
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: delete_token
          in: query
          required: true
          schema:
            type: string
      responses:
        "200":
          description: file deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/apps_u/load_file_metadata/{path}:
    get:
      summary: Load metadata of an s3 file on-behalf of the app author (deployed app)
      operationId: appLoadFileMetadata
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/S3Sig"
        - $ref: "#/components/parameters/S3Exp"
      responses:
        "200":
          description: FileMetadata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WindmillFileMetadata"

  /w/{workspace}/apps_u/load_file_preview/{path}:
    get:
      summary: Load a preview of an s3 file on-behalf of the app author (deployed app)
      operationId: appLoadFilePreview
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: file_size_in_bytes
          in: query
          schema:
            type: integer
        - name: file_mime_type
          in: query
          schema:
            type: string
        - name: csv_separator
          in: query
          schema:
            type: string
        - name: csv_has_header
          in: query
          schema:
            type: boolean
        - name: read_bytes_from
          in: query
          required: true
          schema:
            type: integer
        - name: read_bytes_length
          in: query
          required: true
          schema:
            type: integer
        - name: storage
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/S3Sig"
        - $ref: "#/components/parameters/S3Exp"
      responses:
        "200":
          description: FilePreview
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WindmillFilePreview"

  /w/{workspace}/apps_u/load_parquet_preview/{path}:
    get:
      summary: Load a preview of a parquet file on-behalf of the app author (deployed app)
      operationId: appLoadParquetPreview
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: offset
          in: query
          schema:
            type: number
        - name: limit
          in: query
          schema:
            type: number
        - name: sort_col
          in: query
          schema:
            type: string
        - name: sort_desc
          in: query
          schema:
            type: boolean
        - name: search_col
          in: query
          schema:
            type: string
        - name: search_term
          in: query
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/S3Sig"
        - $ref: "#/components/parameters/S3Exp"
      responses:
        "200":
          description: Parquet Preview
          content:
            application/json: {}

  /w/{workspace}/apps_u/load_csv_preview/{path}:
    get:
      summary: Load a preview of a csv file on-behalf of the app author (deployed app)
      operationId: appLoadCsvPreview
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: offset
          in: query
          schema:
            type: number
        - name: limit
          in: query
          schema:
            type: number
        - name: sort_col
          in: query
          schema:
            type: string
        - name: sort_desc
          in: query
          schema:
            type: boolean
        - name: search_col
          in: query
          schema:
            type: string
        - name: search_term
          in: query
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - name: csv_separator
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/S3Sig"
        - $ref: "#/components/parameters/S3Exp"
      responses:
        "200":
          description: Csv Preview
          content:
            application/json: {}

  /w/{workspace}/apps_u/load_table_count/{path}:
    get:
      summary: Load the table row count on-behalf of the app author (deployed app)
      operationId: appLoadTableCount
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: search_col
          in: query
          schema:
            type: string
        - name: search_term
          in: query
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/S3Sig"
        - $ref: "#/components/parameters/S3Exp"
      responses:
        "200":
          description: Table count
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: number

  /w/{workspace}/apps_u/download_s3_parquet_file_as_csv/{path}:
    get:
      summary: Download a parquet s3 file as csv on-behalf of the app author (deployed app)
      operationId: appDownloadS3ParquetFileAsCsv
      tags:
        - app
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/S3Sig"
        - $ref: "#/components/parameters/S3Exp"
      responses:
        "200":
          description: The downloaded file
          content:
            text/csv:
              schema:
                type: string

  /w/{workspace}/jobs/run/f/{path}:
    post:
      summary: run flow by path
      operationId: runFlowByPath
      x-mcp-tool: true
      x-mcp-instructions: "You should first use getFlowByPath to retrieve the flow's schema and understand what arguments are expected."
      x-mcp-tool-include-query-params: []
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
        - name: scheduled_for
          description: when to schedule this job (leave empty for immediate run)
          in: query
          schema:
            type: string
            format: date-time
        - name: scheduled_in_secs
          description: schedule the script to execute in the number of seconds starting now
          in: query
          schema:
            type: integer
        - $ref: "#/components/parameters/SkipPreprocessor"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - name: invisible_to_owner
          description: make the run invisible to the the flow owner (default false)
          in: query
          schema:
            type: boolean
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid
      requestBody:
        description: flow args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"
      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run/fv/{version}:
    post:
      summary: run flow by version
      operationId: runFlowByVersion
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: version
          description: flow version ID
          in: path
          required: true
          schema:
            type: integer
            format: int64
        - name: scheduled_for
          description: when to schedule this job (leave empty for immediate run)
          in: query
          schema:
            type: string
            format: date-time
        - name: scheduled_in_secs
          description: schedule the script to execute in the number of seconds starting now
          in: query
          schema:
            type: integer
        - $ref: "#/components/parameters/SkipPreprocessor"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - name: invisible_to_owner
          description: make the run invisible to the the flow owner (default false)
          in: query
          schema:
            type: boolean
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid
      requestBody:
        description: flow args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ScriptArgs"
      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run/batch_rerun_jobs:
    post:
      summary: re-run multiple jobs
      operationId: batchReRunJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: list of job ids to re run and arg tranforms
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [job_ids, script_options_by_path, flow_options_by_path]
              properties:
                job_ids:
                  type: array
                  items:
                    type: string
                script_options_by_path:
                  type: object
                  additionalProperties:
                    type: object
                    properties:
                      input_transforms:
                        type: object
                        additionalProperties:
                          $ref: "#/components/schemas/InputTransform"
                      use_latest_version:
                        type: boolean
                flow_options_by_path:
                  type: object
                  additionalProperties:
                    type: object
                    properties:
                      input_transforms:
                        type: object
                        additionalProperties:
                          $ref: "#/components/schemas/InputTransform"
                      use_latest_version:
                        type: boolean
      responses:
        "201":
          description: stream of created job uuids separated by \n. Lines may start with 'Error:'
          content:
            text/event-stream:
              schema:
                type: string

  /w/{workspace}/jobs/restart/f/{id}:
    post:
      summary: restart a completed flow at a given step
      operationId: restartFlowAtStep
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: scheduled_for
          description: when to schedule this job (leave empty for immediate run)
          in: query
          schema:
            type: string
            format: date-time
        - name: scheduled_in_secs
          description: schedule the script to execute in the number of seconds starting now
          in: query
          schema:
            type: integer
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - name: invisible_to_owner
          description: make the run invisible to the the flow owner (default false)
          in: query
          schema:
            type: boolean

      requestBody:
        description: restart flow parameters
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - step_id
              properties:
                step_id:
                  type: string
                  description: top-level step id to restart the flow from (or the outermost container when restarting at a nested step)
                branch_or_iteration_n:
                  type: integer
                  description: for branchall or loop at the top level, the iteration at which the flow should restart (optional)
                flow_version:
                  type: integer
                  description: specific flow version to use for restart (optional, uses current version if not specified)
                nested_path:
                  type: array
                  description: path of additional steps to descend into AFTER `step_id`. Each entry represents one level of nesting inside the spawned child of the previous level's container (BranchOne / sequential ForLoop iteration / Subflow). When non-empty, the actual restart point is the LAST entry's step_id.
                  items:
                    type: object
                    required:
                      - step_id
                    properties:
                      step_id:
                        type: string
                        description: step id at this nesting level
                      branch_or_iteration_n:
                        type: integer
                        description: for ForLoop containers, the iteration to restart at (0-based; iterations 0..n-1 are preserved)

      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run/h/{hash}:
    post:
      summary: run script by hash
      operationId: runScriptByHash
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptHash"
        - name: scheduled_for
          description: when to schedule this job (leave empty for immediate run)
          in: query
          schema:
            type: string
            format: date-time
        - name: scheduled_in_secs
          description: schedule the script to execute in the number of seconds starting now
          in: query
          schema:
            type: integer
        - $ref: "#/components/parameters/SkipPreprocessor"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/WorkerTag"
        - $ref: "#/components/parameters/CacheTtl"
        - $ref: "#/components/parameters/NewJobId"
        - $ref: "#/components/parameters/IncludeHeader"
        - name: invisible_to_owner
          description: make the run invisible to the the script owner (default false)
          in: query
          schema:
            type: boolean
      requestBody:
        description: Partially filled args
        required: true
        content:
          application/json:
            schema:
              type: object

      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run/preview:
    post:
      summary: run script preview
      operationId: runScriptPreview
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/IncludeHeader"
        - name: invisible_to_owner
          description: make the run invisible to the the script owner (default false)
          in: query
          schema:
            type: boolean
        - name: timeout
          description: custom timeout in seconds for this preview run
          in: query
          schema:
            type: integer
        - $ref: "#/components/parameters/NewJobId"

      requestBody:
        description: preview
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Preview"

      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run_inline/preview:
    post:
      summary: run script preview without starting a new job
      operationId: runScriptPreviewInline
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: preview
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PreviewInline"

      responses:
        "200":
          description: script result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/run_inline/p/{path}:
    post:
      summary: run script by path without starting a new job
      operationId: runScriptByPathInline
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptPath"
      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InlineScriptArgs"

      responses:
        "200":
          description: script result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/run_inline/h/{hash}:
    post:
      summary: run script by hash without starting a new job
      operationId: runScriptByHashInline
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/ScriptHash"
      requestBody:
        description: script args
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InlineScriptArgs"

      responses:
        "200":
          description: script result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/run_wait_result/preview:
    post:
      summary: run script preview and wait for result
      operationId: runScriptPreviewAndWaitResult
      x-mcp-tool: true
      x-mcp-instructions: Allows testing a script before deploying it. For typescript code, the language to send is either bun or deno. By default, send bun if no deno specific code is detected.
      x-mcp-required-fields:
        - content
        - language
        - args
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      requestBody:
        description: preview
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Preview"

      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/workflow_as_code/{job_id}/{entrypoint}:
    post:
      summary: run code-workflow task
      operationId: runCodeWorkflowTask
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

        - name: job_id
          in: path
          required: true
          schema:
            type: string
        - name: entrypoint
          in: path
          required: true
          schema:
            type: string

      requestBody:
        description: preview
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowTask"

      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run/dependencies:
    post:
      summary: run a one-off dependencies job
      operationId: runRawScriptDependencies
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      requestBody:
        description: raw script content
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                raw_scripts:
                  type: array
                  items:
                    $ref: "#/components/schemas/RawScriptForDependencies"
                entrypoint:
                  type: string
              required:
                - entrypoint
                - raw_scripts
      responses:
        "201":
          description: dependency job result
          content:
            application/json:
              schema:
                type: object
                properties:
                  lock:
                    type: string
                required:
                  - lock

  /w/{workspace}/jobs/run/dependencies_async:
    post:
      summary: queue a one-off dependencies job and return the job uuid
      operationId: runRawScriptDependenciesAsync
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      requestBody:
        description: raw script content
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                raw_scripts:
                  type: array
                  items:
                    $ref: "#/components/schemas/RawScriptForDependencies"
                entrypoint:
                  type: string
              required:
                - entrypoint
                - raw_scripts
      responses:
        "201":
          description: dependency job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run/flow_dependencies_async:
    post:
      summary: queue a one-off flow dependencies job and return the job uuid
      operationId: runFlowDependenciesAsync
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"

      requestBody:
        description: flow value and path
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: string
                flow_value:
                  $ref: "#/components/schemas/FlowValue"
              required:
                - path
                - flow_value
      responses:
        "201":
          description: flow dependencies job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run/preview_flow:
    post:
      summary: run flow preview
      operationId: runFlowPreview
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/IncludeHeader"
        - name: invisible_to_owner
          description: make the run invisible to the the script owner (default false)
          in: query
          schema:
            type: boolean
        - $ref: "#/components/parameters/NewJobId"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid

      requestBody:
        description: preview
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FlowPreview"

      responses:
        "201":
          description: job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/run_wait_result/preview_flow:
    post:
      summary: run flow preview and wait for result
      operationId: runFlowPreviewAndWaitResult
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: memory_id
          description: memory ID for chat-enabled flows
          in: query
          schema:
            type: string
            format: uuid

      requestBody:
        description: preview
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FlowPreview"

      responses:
        "200":
          description: job result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/run/dynamic_select:
    post:
      summary: run dynamic select helper function
      operationId: runDynamicSelect
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: dynamic select request
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DynamicInputData"
      responses:
        "201":
          description: dynamic select job created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/jobs/queue/list:
    get:
      summary: list all queued jobs
      operationId: listQueue
      x-mcp-tool: true
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/OrderDesc"
        - $ref: "#/components/parameters/CreatedBy"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/Worker"
        - $ref: "#/components/parameters/ScriptExactPath"
        - $ref: "#/components/parameters/ScriptStartPath"
        - $ref: "#/components/parameters/SchedulePath"
        - $ref: "#/components/parameters/TriggerPath"
        - $ref: "#/components/parameters/JobTriggerKind"
        - $ref: "#/components/parameters/ScriptExactHash"
        - $ref: "#/components/parameters/StartedBefore"
        - $ref: "#/components/parameters/StartedAfter"
        - $ref: "#/components/parameters/Success"
        - $ref: "#/components/parameters/ScheduledForBeforeNow"
        - $ref: "#/components/parameters/JobKinds"
        - $ref: "#/components/parameters/Suspended"
        - $ref: "#/components/parameters/Running"
        - $ref: "#/components/parameters/ArgsFilter"
        - $ref: "#/components/parameters/ResultFilter"
        - $ref: "#/components/parameters/AllowWildcards"
        - $ref: "#/components/parameters/Tag"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: all_workspaces
          description: get jobs from all workspaces (only valid if request come from the `admins` workspace)
          in: query
          schema:
            type: boolean
        - name: is_not_schedule
          description: is not a scheduled job
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: All queued jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/QueuedJob"

  /w/{workspace}/jobs/queue/count:
    get:
      summary: get queue count
      operationId: getQueueCount
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: all_workspaces
          description: get jobs from all workspaces (only valid if request come from the `admins` workspace)
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: queue count
          content:
            application/json:
              schema:
                type: object
                properties:
                  database_length:
                    type: integer
                  suspended:
                    type: integer
                required:
                  - database_length

  /w/{workspace}/jobs/completed/count:
    get:
      summary: get completed count
      operationId: getCompletedCount
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: completed count
          content:
            application/json:
              schema:
                type: object
                properties:
                  database_length:
                    type: integer
                required:
                  - database_length

  /w/{workspace}/jobs/completed/count_jobs:
    get:
      summary: count number of completed jobs with filter
      operationId: countCompletedJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: completed_after_s_ago
          in: query
          schema:
            type: integer
        - name: success
          in: query
          schema:
            type: boolean
        - name: tags
          in: query
          schema:
            type: string
        - name: all_workspaces
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: Count of completed jobs
          content:
            application/json:
              schema:
                type: integer

  /w/{workspace}/jobs/list_filtered_uuids:
    get:
      summary: get the ids of all jobs matching the given filters
      operationId: listFilteredJobsUuids
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/CreatedBy"
        - $ref: "#/components/parameters/Label"
        - $ref: "#/components/parameters/Worker"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/ScriptExactPath"
        - $ref: "#/components/parameters/ScriptStartPath"
        - $ref: "#/components/parameters/SchedulePath"
        - $ref: "#/components/parameters/ScriptExactHash"
        - $ref: "#/components/parameters/StartedBefore"
        - $ref: "#/components/parameters/StartedAfter"
        - $ref: "#/components/parameters/CreatedBefore"
        - $ref: "#/components/parameters/CreatedAfter"
        - $ref: "#/components/parameters/CompletedBefore"
        - $ref: "#/components/parameters/CompletedAfter"
        - $ref: "#/components/parameters/CreatedBeforeQueue"
        - $ref: "#/components/parameters/CreatedAfterQueue"
        - $ref: "#/components/parameters/Running"
        - $ref: "#/components/parameters/ScheduledForBeforeNow"
        - $ref: "#/components/parameters/JobKinds"
        - $ref: "#/components/parameters/Suspended"
        - $ref: "#/components/parameters/ArgsFilter"
        - $ref: "#/components/parameters/Tag"
        - $ref: "#/components/parameters/ResultFilter"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: is_skipped
          description: is the job skipped
          in: query
          schema:
            type: boolean
        - name: is_flow_step
          description: is the job a flow step
          in: query
          schema:
            type: boolean
        - name: has_null_parent
          description: has null parent
          in: query
          schema:
            type: boolean
        - name: success
          description: filter on successful jobs
          in: query
          schema:
            type: boolean
        - name: status
          description: filter on the exact completed job status. Unlike `success=true` (which also matches `skipped`), `status=success` matches only `success`.
          in: query
          schema:
            type: string
            enum:
              - success
              - failure
              - canceled
              - skipped
        - name: all_workspaces
          description: get jobs from all workspaces (only valid if request come from the `admins` workspace)
          in: query
          schema:
            type: boolean
        - name: is_not_schedule
          description: is not a scheduled job
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: uuids of jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/jobs/queue/list_filtered_uuids:
    get:
      summary: get the ids of all queued jobs matching the given filters
      operationId: listFilteredQueueUuids
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/OrderDesc"
        - $ref: "#/components/parameters/CreatedBy"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/ScriptExactPath"
        - $ref: "#/components/parameters/ScriptStartPath"
        - $ref: "#/components/parameters/SchedulePath"
        - $ref: "#/components/parameters/ScriptExactHash"
        - $ref: "#/components/parameters/StartedBefore"
        - $ref: "#/components/parameters/StartedAfter"
        - $ref: "#/components/parameters/Success"
        - $ref: "#/components/parameters/ScheduledForBeforeNow"
        - $ref: "#/components/parameters/JobKinds"
        - $ref: "#/components/parameters/Suspended"
        - $ref: "#/components/parameters/Running"
        - $ref: "#/components/parameters/ArgsFilter"
        - $ref: "#/components/parameters/ResultFilter"
        - $ref: "#/components/parameters/AllowWildcards"
        - $ref: "#/components/parameters/Tag"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: concurrency_key
          in: query
          required: false
          schema:
            type: string
        - name: all_workspaces
          description: get jobs from all workspaces (only valid if request come from the `admins` workspace)
          in: query
          schema:
            type: boolean
        - name: is_not_schedule
          description: is not a scheduled job
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: uuids of jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/jobs/queue/cancel_selection:
    post:
      summary: cancel jobs based on the given uuids
      operationId: cancelSelection
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: force_cancel
          in: query
          schema:
            type: boolean
        - name: all_workspaces
          in: query
          schema:
            type: boolean
      requestBody:
        description: uuids of the jobs to cancel
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: string
      responses:
        "200":
          description: uuids of canceled jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/jobs/get_otel_traces/{id}:
    get:
      summary: get OpenTelemetry traces for a job
      operationId: getJobOtelTraces
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: list of OTEL Span objects (compatible with OpenTelemetry Span proto)
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object

  /w/{workspace}/trigger/{trigger_kind}/resume_suspended_trigger_jobs/{trigger_path}:
    post:
      summary: resume all suspended jobs for a specific trigger
      operationId: resumeSuspendedTriggerJobs
      tags:
        - trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: trigger_kind
          description: The kind of trigger
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/JobTriggerKind"
        - name: trigger_path
          description: The path of the trigger (can contain forward slashes)
          in: path
          required: true
          schema:
            type: string
          style: simple
          explode: false
      requestBody:
        description: Optional list of job IDs to reassign
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                job_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  description: Optional list of specific job UUIDs to reassign. If not provided, all suspended jobs for the trigger will be reassigned.
      responses:
        "200":
          description: confirmation message
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/trigger/{trigger_kind}/cancel_suspended_trigger_jobs/{trigger_path}:
    post:
      summary: cancel all suspended jobs for a specific trigger
      operationId: cancelSuspendedTriggerJobs
      tags:
        - trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: trigger_kind
          description: The kind of trigger
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/JobTriggerKind"
        - name: trigger_path
          description: The path of the trigger (can contain forward slashes)
          in: path
          required: true
          schema:
            type: string
          style: simple
          explode: false
      requestBody:
        description: Optional list of job IDs to cancel
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                job_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  description: Optional list of specific job UUIDs to cancel. If not provided, all suspended jobs for the trigger will be canceled.
      responses:
        "200":
          description: confirmation message
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/jobs/completed/list:
    get:
      summary: list all completed jobs
      operationId: listCompletedJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/OrderDesc"
        - $ref: "#/components/parameters/CreatedBy"
        - $ref: "#/components/parameters/Label"
        - $ref: "#/components/parameters/Worker"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/ScriptExactPath"
        - $ref: "#/components/parameters/ScriptStartPath"
        - $ref: "#/components/parameters/SchedulePath"
        - $ref: "#/components/parameters/ScriptExactHash"
        - $ref: "#/components/parameters/StartedBefore"
        - $ref: "#/components/parameters/StartedAfter"
        - $ref: "#/components/parameters/Success"
        - name: status
          description: filter on the exact completed job status. Unlike `success=true` (which also matches `skipped`), `status=success` matches only `success`.
          in: query
          schema:
            type: string
            enum:
              - success
              - failure
              - canceled
              - skipped
        - $ref: "#/components/parameters/JobKinds"
        - $ref: "#/components/parameters/ArgsFilter"
        - $ref: "#/components/parameters/ResultFilter"
        - $ref: "#/components/parameters/AllowWildcards"
        - $ref: "#/components/parameters/Tag"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: is_skipped
          description: is the job skipped
          in: query
          schema:
            type: boolean
        - name: is_flow_step
          description: is the job a flow step
          in: query
          schema:
            type: boolean
        - name: has_null_parent
          description: has null parent
          in: query
          schema:
            type: boolean
        - name: is_not_schedule
          description: is not a scheduled job
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: All completed jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CompletedJob"

  /w/{workspace}/jobs/completed/export:
    get:
      summary: export all completed jobs for backup/migration
      operationId: exportCompletedJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: All completed jobs exported
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ExportableCompletedJob"

  /w/{workspace}/jobs/completed/import:
    post:
      summary: import completed jobs from backup/migration
      operationId: importCompletedJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/ExportableCompletedJob"
      responses:
        "200":
          description: Successfully imported completed jobs
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs/queue/export:
    get:
      summary: export all queued jobs for backup/migration
      operationId: exportQueuedJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: All queued jobs exported
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ExportableQueuedJob"

  /w/{workspace}/jobs/queue/import:
    post:
      summary: import queued jobs from backup/migration
      operationId: importQueuedJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/ExportableQueuedJob"
      responses:
        "200":
          description: Successfully imported queued jobs
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs/delete:
    post:
      summary: delete jobs by IDs from all related tables
      operationId: deleteJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: string
                format: uuid
              description: Array of job IDs to delete
      responses:
        "200":
          description: Successfully deleted jobs
          content:
            text/plain:
              schema:
                type: string
                description: Summary of deleted jobs and rows

  /w/{workspace}/jobs/list:
    get:
      summary: list all jobs
      operationId: listJobs
      x-mcp-tool: true
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/CreatedBy"
        - $ref: "#/components/parameters/Label"
        - $ref: "#/components/parameters/Worker"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/ScriptExactPath"
        - $ref: "#/components/parameters/ScriptStartPath"
        - $ref: "#/components/parameters/SchedulePath"
        - $ref: "#/components/parameters/ScriptExactHash"
        - $ref: "#/components/parameters/StartedBefore"
        - $ref: "#/components/parameters/StartedAfter"
        - $ref: "#/components/parameters/CreatedBefore"
        - $ref: "#/components/parameters/CreatedAfter"
        - $ref: "#/components/parameters/CompletedBefore"
        - $ref: "#/components/parameters/CompletedAfter"
        - $ref: "#/components/parameters/CreatedBeforeQueue"
        - $ref: "#/components/parameters/CreatedAfterQueue"
        - $ref: "#/components/parameters/Running"
        - $ref: "#/components/parameters/ScheduledForBeforeNow"
        - $ref: "#/components/parameters/JobKinds"
        - $ref: "#/components/parameters/Suspended"
        - $ref: "#/components/parameters/ArgsFilter"
        - $ref: "#/components/parameters/Tag"
        - $ref: "#/components/parameters/ResultFilter"
        - $ref: "#/components/parameters/AllowWildcards"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/JobTriggerKind"
        - name: is_skipped
          description: is the job skipped
          in: query
          schema:
            type: boolean
        - name: is_flow_step
          description: is the job a flow step
          in: query
          schema:
            type: boolean
        - name: has_null_parent
          description: has null parent
          in: query
          schema:
            type: boolean
        - name: success
          description: filter on successful jobs
          in: query
          schema:
            type: boolean
        - name: status
          description: filter on the exact completed job status. Unlike `success=true` (which also matches `skipped`), `status=success` matches only `success`.
          in: query
          schema:
            type: string
            enum:
              - success
              - failure
              - canceled
              - skipped
        - name: all_workspaces
          description: get jobs from all workspaces (only valid if request come from the `admins` workspace)
          in: query
          schema:
            type: boolean
        - name: is_not_schedule
          description: is not a scheduled job
          in: query
          schema:
            type: boolean
        - name: excludes_entrypoint_override
          description: exclude jobs that were started with a `_ENTRYPOINT_OVERRIDE` arg (e.g. dynamic-select helper runs and preprocessor previews)
          in: query
          schema:
            type: boolean
        - name: broad_filter
          description: broad search across multiple fields (case-insensitive substring match on path, tag, schedule path, trigger kind, label)
          in: query
          schema:
            type: string
      responses:
        "200":
          description: All jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Job"

  /jobs/db_clock:
    get:
      summary: get db clock
      operationId: getDbClock
      tags:
        - job
      responses:
        "200":
          description: the timestamp of the db that can be used to compute the drift
          content:
            application/json:
              schema:
                type: integer

  /jobs/completed/count_by_tag:
    get:
      summary: Count jobs by tag
      operationId: countJobsByTag
      tags:
        - job
      parameters:
        - name: horizon_secs
          in: query
          description: Past Time horizon in seconds (when to start the count = now - horizon) (default is 3600)
          required: false
          schema:
            type: integer
        - name: workspace_id
          in: query
          description: Specific workspace ID to filter results (optional)
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Job counts by tag
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    tag:
                      type: string
                    count:
                      type: integer
                  required:
                    - tag
                    - count

  /w/{workspace}/jobs_u/get/{id}:
    get:
      summary: get job
      operationId: getJob
      x-mcp-tool: true
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: no_logs
          in: query
          schema:
            type: boolean
        - name: no_code
          in: query
          schema:
            type: boolean
        - name: approval_token
          in: query
          description: Approval token granting read access to the job when not logged in. The token must be the one issued for this job's flow (i.e. the flow id used when generating the approval URL).
          schema:
            type: string
      responses:
        "200":
          description: job details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Job"

  /w/{workspace}/jobs_u/get_root_job_id/{id}:
    get:
      summary: get root job id
      operationId: getRootJobId
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: get root job id
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/jobs_u/get_logs/{id}:
    get:
      summary: get job logs
      operationId: getJobLogs
      x-mcp-tool: true
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: remove_ansi_warnings
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: job details
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/get_flow_all_logs/{id}:
    get:
      summary: get all logs for a flow job
      operationId: getFlowAllLogs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: concatenated logs of all flow steps
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/get_flow_all_logs_structured/{id}:
    get:
      summary: get all logs for a flow job in a structured format
      operationId: getFlowAllLogsStructured
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: structured logs of all flow steps, one entry per job
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    job_id:
                      type: string
                    label:
                      type: string
                      description: human-readable label describing the job's position in the flow tree
                    kind:
                      type: string
                      description: job kind (script, flow, forloopflow, ...)
                    flow_step_id:
                      type: string
                      nullable: true
                    step_path:
                      type: string
                      nullable: true
                      description: materialized step path (e.g. "a/b")
                    depth:
                      type: integer
                      description: depth in the flow tree (0 for the root flow job)
                    parent_module_type:
                      type: string
                      nullable: true
                      description: parent module type (forloopflow, branchall, ...)
                    sibling_index:
                      type: integer
                      description: 1-based index of this job among siblings sharing the same step
                    sibling_count:
                      type: integer
                      description: total number of siblings sharing the same step
                    logs:
                      type: string
                  required:
                    - job_id
                    - label
                    - kind
                    - depth
                    - sibling_index
                    - sibling_count
                    - logs

  /w/{workspace}/jobs_u/get_completed_logs_tail/{id}:
    get:
      summary: get completed job logs tail
      operationId: getCompletedJobLogsTail
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: completed job logs tail
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/get_args/{id}:
    get:
      summary: get job args
      operationId: getJobArgs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: job args
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs_u/queue/get_started_at_by_ids:
    post:
      summary: get started at by ids
      operationId: getStartedAtByIds
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: ids
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                type: string
      responses:
        "200":
          description: started at by ids
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                  format: date-time

  /w/{workspace}/jobs_u/getupdate/{id}:
    get:
      summary: get job updates
      operationId: getJobUpdates
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: running
          in: query
          schema:
            type: boolean
        - name: log_offset
          in: query
          schema:
            type: integer
        - name: stream_offset
          in: query
          schema:
            type: integer
        - name: get_progress
          in: query
          schema:
            type: boolean
        - name: no_logs
          in: query
          schema:
            type: boolean

      responses:
        "200":
          description: job details
          content:
            application/json:
              schema:
                type: object
                properties:
                  running:
                    type: boolean
                  completed:
                    type: boolean
                  new_logs:
                    type: string
                  log_offset:
                    type: integer
                  mem_peak:
                    type: integer
                  progress:
                    type: integer
                  stream_offset:
                    type: integer
                  new_result_stream:
                    type: string
                  flow_status:
                    $ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatus"
                  workflow_as_code_status:
                    $ref: "#/components/schemas/WorkflowStatus"

  /w/{workspace}/jobs_u/getupdate_sse/{id}:
    get:
      summary: get job updates via server-sent events
      operationId: getJobUpdatesSSE
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: running
          in: query
          schema:
            type: boolean
        - name: log_offset
          in: query
          schema:
            type: integer
        - name: stream_offset
          in: query
          schema:
            type: integer
        - name: get_progress
          in: query
          schema:
            type: boolean
        - name: only_result
          in: query
          schema:
            type: boolean
        - name: no_logs
          in: query
          schema:
            type: boolean
        - name: fast
          in: query
          schema:
            type: boolean

      responses:
        "200":
          description: server-sent events stream of job updates
          content:
            text/event-stream:
              schema:
                type: string

  /w/{workspace}/jobs_u/get_log_file/{path}:
    get:
      summary: get log file from object store
      operationId: getLogFileFromStore
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: path
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: job log
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/get_flow_debug_info/{id}:
    get:
      summary: get flow debug info
      operationId: getFlowDebugInfo
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: flow debug info details
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs_u/completed/get/{id}:
    get:
      summary: get completed job
      operationId: getCompletedJob
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: job details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompletedJob"

  /w/{workspace}/jobs_u/completed/get_result/{id}:
    get:
      summary: get completed job result
      operationId: getCompletedJobResult
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: suspended_job
          in: query
          schema:
            type: string
        - name: resume_id
          in: query
          schema:
            type: integer
        - name: secret
          in: query
          schema:
            type: string
        - name: approver
          in: query
          schema:
            type: string
      responses:
        "200":
          description: result
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs_u/completed/get_result_maybe/{id}:
    get:
      summary: get completed job result if job is completed
      operationId: getCompletedJobResultMaybe
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - $ref: "#/components/parameters/GetStarted"

      responses:
        "200":
          description: result
          content:
            application/json:
              schema:
                type: object
                properties:
                  completed:
                    type: boolean
                  result: {}
                  success:
                    type: boolean
                  started:
                    type: boolean
                required:
                  - completed
                  - result

  /w/{workspace}/jobs_u/completed/get_timing/{id}:
    get:
      summary: get completed job timing
      operationId: getCompletedJobTiming
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: job timing details
          content:
            application/json:
              schema:
                type: object
                properties:
                  created_at:
                    type: string
                    format: date-time
                  started_at:
                    type: string
                    format: date-time
                  duration_ms:
                    type: integer
                required:
                  - created_at

  /w/{workspace}/jobs_u/dispatch_events/{id}:
    get:
      summary: list asset-trigger dispatch events for a producer job
      description: >
        Returns the chronological log of decisions the asset-trigger
        dispatcher made after this producer job completed. Each row is one
        (subscriber, asset write) decision: `dispatched` (with
        `child_job_id`), `join_pending` (with `received_inputs` /
        `required_inputs` / `partition`), or `skipped` (with `reason`).
        Rows are reaped automatically when the producer's `v2_job` row is
        deleted by the retention sweep.
      operationId: listDispatchEvents
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: dispatch events for this producer job
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    subscriber_path:
                      type: string
                    asset_kind:
                      type: string
                      enum:
                        - s3object
                        - resource
                        - variable
                        - ducklake
                        - datatable
                        - volume
                    asset_path:
                      type: string
                    outcome:
                      type: string
                      enum:
                        - dispatched
                        - join_pending
                        - skipped
                    child_job_id:
                      type: string
                      format: uuid
                    partition:
                      type: string
                    received_inputs:
                      type: integer
                    required_inputs:
                      type: integer
                    debounce_s:
                      type: integer
                    reason:
                      type: string
                    created_at:
                      type: string
                      format: date-time
                  required:
                    - subscriber_path
                    - asset_kind
                    - asset_path
                    - outcome
                    - created_at

  /w/{workspace}/jobs/asset_dispatch_edges:
    get:
      summary: list asset-cascade producer→child job edges for a folder
      description: >
        Returns the `dispatched` asset-trigger edges (producer job → child job)
        whose subscriber lives under `path_start`. Lets a pipeline view
        reconstruct the cascade tree of a folder by job id and group connected
        runs. Visibility follows the producer job's RLS.
      operationId: listAssetDispatchEdges
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: path_start
          in: query
          required: true
          description: Folder path prefix the children live under, e.g. `f/orders/`.
          schema:
            type: string
        - name: created_after
          in: query
          required: false
          description: Only edges dispatched at/after this instant.
          schema:
            type: string
            format: date-time
      responses:
        "200":
          description: asset-cascade edges for the folder
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    producer_job_id:
                      type: string
                      format: uuid
                    child_job_id:
                      type: string
                      format: uuid
                      description: Set for `dispatched`; absent for `join_pending` inputs.
                    subscriber_path:
                      type: string
                    outcome:
                      type: string
                      enum:
                        - dispatched
                        - join_pending
                    asset_kind:
                      type: string
                      enum:
                        - s3object
                        - resource
                        - variable
                        - ducklake
                        - datatable
                        - volume
                    asset_path:
                      type: string
                    created_at:
                      type: string
                      format: date-time
                  required:
                    - producer_job_id
                    - subscriber_path
                    - outcome
                    - asset_kind
                    - asset_path
                    - created_at

  /w/{workspace}/jobs/completed/delete/{id}:
    post:
      summary: delete completed job (erase content but keep run id)
      operationId: deleteCompletedJob
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: job details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompletedJob"

  /w/{workspace}/jobs_u/queue/cancel/{id}:
    post:
      summary: cancel queued or running job
      operationId: cancelQueuedJob
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      requestBody:
        description: reason
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string

      responses:
        "200":
          description: job canceled
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/queue/cancel_persistent/{path}:
    post:
      summary: cancel all queued jobs for persistent script
      operationId: cancelPersistentQueuedJobs
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: reason
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string

      responses:
        "200":
          description: persistent job scaled down to zero
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/queue/force_cancel/{id}:
    post:
      summary: force cancel queued job
      operationId: forceCancelQueuedJob
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      requestBody:
        description: reason
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string

      responses:
        "200":
          description: job canceled
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs/queue/position/{scheduled_for}:
    get:
      summary: get queue position for a job
      operationId: getQueuePosition
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: scheduled_for
          in: path
          required: true
          schema:
            type: integer
            description: The scheduled for timestamp in milliseconds
      responses:
        "200":
          description: queue position information
          content:
            application/json:
              schema:
                type: object
                properties:
                  position:
                    type: integer
                    description: The position in queue (1-based), null if not in queue or already running

  /w/{workspace}/jobs/queue/scheduled_for/{id}:
    get:
      summary: get scheduled for timestamp for a job
      operationId: getScheduledFor
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: scheduled for timestamp
          content:
            application/json:
              schema:
                type: integer

  /w/{workspace}/jobs/job_signature/{id}/{resume_id}:
    get:
      summary: create an HMac signature given a job id and a resume id
      operationId: createJobSignature
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: resume_id
          in: path
          required: true
          schema:
            type: integer
        - name: approver
          in: query
          schema:
            type: string
      responses:
        "200":
          description: job signature
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs/resume_urls/{id}/{resume_id}:
    get:
      summary: get resume urls given a job_id, resume_id and a nonce to resume a flow
      operationId: getResumeUrls
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: resume_id
          in: path
          required: true
          schema:
            type: integer
        - name: approver
          in: query
          schema:
            type: string
        - name: flow_level
          in: query
          description: If true, generate resume URLs for the parent flow instead of the specific step. This allows pre-approvals that can be consumed by any later suspend step in the same flow.
          schema:
            type: boolean
      responses:
        "200":
          description: url endpoints
          content:
            application/json:
              schema:
                type: object
                properties:
                  approvalPage:
                    type: string
                  resume:
                    type: string
                  cancel:
                    type: string
                required:
                  - approvalPage
                  - resume
                  - cancel

  /w/{workspace}/jobs/slack_approval/{id}:
    get:
      summary: generate interactive slack approval for suspended job
      operationId: getSlackApprovalPayload
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: approver
          in: query
          schema:
            type: string
        - name: message
          in: query
          schema:
            type: string
        - name: slack_resource_path
          in: query
          required: true
          schema:
            type: string
        - name: channel_id
          in: query
          required: true
          schema:
            type: string
        - name: flow_step_id
          in: query
          required: true
          schema:
            type: string
        - name: default_args_json
          in: query
          required: false
          schema:
            type: string
        - name: dynamic_enums_json
          in: query
          required: false
          schema:
            type: string
        - name: resume_button_text
          in: query
          required: false
          schema:
            type: string
        - name: cancel_button_text
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Interactive slack approval message sent successfully

  /w/{workspace}/jobs/teams_approval/{id}:
    get:
      summary: generate interactive teams approval for suspended job
      operationId: getTeamsApprovalPayload
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: approver
          in: query
          schema:
            type: string
        - name: message
          in: query
          schema:
            type: string
        - name: team_name
          in: query
          required: true
          schema:
            type: string
        - name: channel_name
          in: query
          required: true
          schema:
            type: string
        - name: flow_step_id
          in: query
          required: true
          schema:
            type: string
        - name: default_args_json
          in: query
          required: false
          schema:
            type: string
        - name: dynamic_enums_json
          in: query
          required: false
          schema:
            type: string
        - name: resume_button_text
          in: query
          required: false
          schema:
            type: string
        - name: cancel_button_text
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Interactive slack approval message sent successfully

  /w/{workspace}/jobs_u/flow/resume_suspended/{job_id}:
    post:
      summary: resume or cancel a suspended flow/WAC job
      description: >
        Resume or cancel a suspended flow/WAC job. Uses approval rules to
        determine authorization. Either a valid approval_token or an
        authenticated session is required.
      operationId: resumeSuspended
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: job_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                payload:
                  description: payload to send to the resumed job
                approval_token:
                  type: string
                  description: approval token for unauthenticated access
                approved:
                  type: boolean
                  description: whether to approve (true) or cancel (false) the job
                  default: true
      responses:
        "201":
          description: job resumed
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/flow/approval_info/{job_id}:
    get:
      summary: get approval info for a suspended flow/WAC job
      description: >
        Get approval info for a suspended flow/WAC job. Returns form schema,
        approval rules, and whether the current user can approve. Either a
        valid token query parameter or an authenticated session is required.
      operationId: getApprovalInfo
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: job_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: token
          in: query
          required: false
          schema:
            type: string
          description: approval token for unauthenticated access
      responses:
        "200":
          description: approval info
          content:
            application/json:
              schema:
                type: object
                required:
                  - flow_id
                  - can_approve
                  - user_auth_required
                  - approvers
                properties:
                  flow_id:
                    type: string
                    format: uuid
                  form_schema:
                    description: form schema for the approval step
                  description:
                    description: description of the approval step
                  approval_conditions:
                    type: object
                    properties:
                      user_auth_required:
                        type: boolean
                      user_groups_required:
                        type: array
                        items:
                          type: string
                      self_approval_disabled:
                        type: boolean
                    required:
                      - user_auth_required
                      - user_groups_required
                      - self_approval_disabled
                  can_approve:
                    type: boolean
                    description: whether the current user/token holder can approve
                  user_auth_required:
                    type: boolean
                    description: whether user authentication is required to approve
                  hide_cancel:
                    type: boolean
                    description: whether to hide the cancel button in the UI
                  approvers:
                    type: array
                    items:
                      type: object
                      required:
                        - resume_id
                        - approver
                      properties:
                        resume_id:
                          type: integer
                        approver:
                          type: string
                  view_token:
                    type: string
                    description: >-
                      Share-read-link token for the flow. An authenticated workspace
                      member can append it as a `view_token` query param on the run
                      page to read a flow they don't otherwise have access to.

  /w/{workspace}/jobs_u/resume/{id}/{resume_id}/{signature}:
    get:
      summary: resume a job for a suspended flow
      operationId: resumeSuspendedJobGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - $ref: "#/components/parameters/Payload"
        - name: resume_id
          in: path
          required: true
          schema:
            type: integer
        - name: signature
          in: path
          required: true
          schema:
            type: string
        - name: approver
          in: query
          schema:
            type: string
      responses:
        "201":
          description: job resumed
          content:
            text/plain:
              schema:
                type: string

    post:
      summary: resume a job for a suspended flow
      operationId: resumeSuspendedJobPost
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: resume_id
          in: path
          required: true
          schema:
            type: integer
        - name: signature
          in: path
          required: true
          schema:
            type: string
        - name: approver
          in: query
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        "201":
          description: job resumed
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs/flow/user_states/{id}/{key}:
    post:
      summary: set flow user state at a given key
      operationId: setFlowUserState
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: key
          in: path
          required: true
          schema:
            type: string
      requestBody:
        description: new value
        required: true
        content:
          application/json:
            schema: {}
      responses:
        "200":
          description: flow user state updated
          content:
            text/plain:
              schema:
                type: string
    get:
      summary: get flow user state at a given key
      operationId: getFlowUserState
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: key
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: flow user state updated
          content:
            application/json:
              schema: {}

  /w/{workspace}/jobs/flow/resume/{id}:
    post:
      summary: resume a job for a suspended flow as an owner
      operationId: resumeSuspendedFlowAsOwner
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        "201":
          description: job resumed
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/cancel/{id}/{resume_id}/{signature}:
    get:
      summary: cancel a job for a suspended flow
      operationId: cancelSuspendedJobGet
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: resume_id
          in: path
          required: true
          schema:
            type: integer
        - name: signature
          in: path
          required: true
          schema:
            type: string
        - name: approver
          in: query
          schema:
            type: string
      responses:
        "201":
          description: job canceled
          content:
            text/plain:
              schema:
                type: string

    post:
      summary: cancel a job for a suspended flow
      operationId: cancelSuspendedJobPost
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: resume_id
          in: path
          required: true
          schema:
            type: integer
        - name: signature
          in: path
          required: true
          schema:
            type: string
        - name: approver
          in: query
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        "201":
          description: job canceled
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/jobs_u/get_flow/{id}/{resume_id}/{signature}:
    get:
      summary: get parent flow job of suspended job
      operationId: getSuspendedJobFlow
      tags:
        - job
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
        - name: resume_id
          in: path
          required: true
          schema:
            type: integer
        - name: signature
          in: path
          required: true
          schema:
            type: string
        - name: approver
          in: query
          schema:
            type: string
      responses:
        "200":
          description: parent flow details
          content:
            application/json:
              schema:
                type: object
                properties:
                  job:
                    $ref: "#/components/schemas/Job"
                  approvers:
                    type: array
                    items:
                      type: object
                      properties:
                        resume_id:
                          type: integer
                        approver:
                          type: string
                      required:
                        - resume_id
                        - approver
                  view_token:
                    type: string
                    description: >-
                      Share-read-link token for the parent flow. An authenticated
                      workspace member can append it as a `view_token` query param
                      on the run page to read a flow they don't otherwise have
                      access to.
                required:
                  - job
                  - approvers

  /schedules/preview:
    post:
      summary: preview schedule
      operationId: previewSchedule
      tags:
        - schedule
      requestBody:
        description: schedule
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                schedule:
                  type: string
                timezone:
                  type: string
                cron_version:
                  type: string
              required:
                - schedule
                - timezone
      responses:
        "200":
          description: List of 5 estimated upcoming execution events (in UTC)
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                  format: date-time

  /w/{workspace}/schedules/create:
    post:
      summary: create schedule
      operationId: createSchedule
      x-mcp-tool: true
      x-mcp-instructions: |
        Creates a new schedule.
        The schedule should include seconds.
        You should get the schema of the script or flow before creating the schedule to correctly specify the arguments needed.
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new schedule
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewSchedule"
      responses:
        "201":
          description: schedule created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/schedules/update/{path}:
    post:
      summary: update schedule
      operationId: updateSchedule
      x-mcp-tool: true
      x-mcp-instructions: |
        Updates a schedule.
        The schedule should include seconds.
        You should get the schema of the script or flow before updating the schedule to correctly specify the arguments needed.
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated schedule
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditSchedule"
      responses:
        "200":
          description: schedule updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/schedules/setenabled/{path}:
    post:
      summary: set enabled schedule
      operationId: setScheduleEnabled
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated schedule enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                enabled:
                  type: boolean
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    schedule in a fork whose parent has the same path enabled.
              required:
                - enabled

      responses:
        "200":
          description: schedule enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/schedules/delete/{path}:
    delete:
      summary: delete schedule
      operationId: deleteSchedule
      x-mcp-tool: true
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: schedule deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/schedules/get/{path}:
    get:
      summary: get schedule
      operationId: getSchedule
      x-mcp-tool: true
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: schedule deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/Schedule"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/schedules/exists/{path}:
    get:
      summary: does schedule exists
      operationId: existsSchedule
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: schedule exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/schedules/list:
    get:
      summary: list schedules
      operationId: listSchedules
      x-mcp-tool: true
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/ArgsFilter"
        - name: path
          description: filter by path (script path)
          in: query
          schema:
            type: string
        - name: is_flow
          description: filter schedules by whether they target a flow
          in: query
          schema:
            type: boolean
        - name: path_start
          description: filter schedules by path prefix
          in: query
          schema:
            type: string
        - name: schedule_path
          description: exact match on the schedule's path
          in: query
          schema:
            type: string
        - name: description
          description: pattern match filter for description field (case-insensitive)
          in: query
          schema:
            type: string
        - name: summary
          description: pattern match filter for summary field (case-insensitive)
          in: query
          schema:
            type: string
        - name: broad_filter
          description: broad search across multiple fields (case-insensitive substring match)
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - name: include_draft_only
          description: |
            When true, append per-user draft schedules whose path has
            no deployed schedule. Synthesized rows carry
            `draft_only: true`.
          in: query
          required: false
          schema:
            type: boolean
      responses:
        "200":
          description: schedule list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Schedule"

  /w/{workspace}/schedules/list_with_jobs:
    get:
      summary: list schedules with last 20 jobs
      operationId: listSchedulesWithJobs
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: schedule list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ScheduleWJobs"

  /w/{workspace}/schedules/setdefaulthandler:
    post:
      summary: Set default error or recoevery handler
      operationId: setDefaultErrorOrRecoveryHandler
      tags:
        - schedule
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: Handler description
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                handler_type:
                  type: string
                  enum: ["error", "recovery", "success"]
                override_existing:
                  type: boolean
                path:
                  type: string
                extra_args:
                  type: object
                number_of_occurence:
                  type: integer
                number_of_occurence_exact:
                  type: boolean
                workspace_handler_muted:
                  type: boolean
              required:
                - handler_type
                - override_existing
      responses:
        "201":
          description: default error handler set

  /w/{workspace}/openapi/generate:
    post:
      summary: generate openapi spec from http routes/webhook
      operationId: generateOpenapiSpec
      tags:
        - openapi
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: openapi spec info and url
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GenerateOpenapiSpec"
      responses:
        "200":
          description: openapi spec
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/openapi/download:
    post:
      summary: Download the OpenAPI v3.1 spec as a file
      operationId: DownloadOpenapiSpec
      tags:
        - openapi
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: openapi spec info and url
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GenerateOpenapiSpec"
      responses:
        "200":
          description: Downloaded OpenAPI spec
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary

  /w/{workspace}/http_triggers/create_many:
    post:
      summary: create many HTTP triggers
      operationId: createHttpTriggers
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new http trigger
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/NewHttpTrigger"
      responses:
        "201":
          description: http trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/http_triggers/create:
    post:
      summary: create http trigger
      operationId: createHttpTrigger
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new http trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewHttpTrigger"
      responses:
        "201":
          description: http trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/http_triggers/update/{path}:
    post:
      summary: update http trigger
      operationId: updateHttpTrigger
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditHttpTrigger"
      responses:
        "200":
          description: http trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/http_triggers/delete/{path}:
    delete:
      summary: delete http trigger
      operationId: deleteHttpTrigger
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: http trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/http_triggers/get/{path}:
    get:
      summary: get http trigger
      operationId: getHttpTrigger
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: http trigger deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/HttpTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/http_triggers/list:
    get:
      summary: list http triggers
      operationId: listHttpTriggers
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: http trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/HttpTrigger"

  /w/{workspace}/http_triggers/exists/{path}:
    get:
      summary: does http trigger exists
      operationId: existsHttpTrigger
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: http trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/http_triggers/route_exists:
    post:
      summary: does route exists
      operationId: existsRoute
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: route exists request
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                route_path:
                  type: string
                http_method:
                  $ref: "#/components/schemas/HttpMethod"
                trigger_path:
                  type: string
                workspaced_route:
                  type: boolean
              required:
                - route_path
                - http_method
      responses:
        "200":
          description: route exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/http_triggers/setmode/{path}:
    post:
      summary: enable/disable http trigger
      operationId: setHttpTriggerMode
      tags:
        - http_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: http trigger enable/disable
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/websocket_triggers/create:
    post:
      summary: create websocket trigger
      operationId: createWebsocketTrigger
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new websocket trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewWebsocketTrigger"
      responses:
        "201":
          description: websocket trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/websocket_triggers/update/{path}:
    post:
      summary: update websocket trigger
      operationId: updateWebsocketTrigger
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditWebsocketTrigger"
      responses:
        "200":
          description: websocket trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/websocket_triggers/delete/{path}:
    delete:
      summary: delete websocket trigger
      operationId: deleteWebsocketTrigger
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: websocket trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/websocket_triggers/get/{path}:
    get:
      summary: get websocket trigger
      operationId: getWebsocketTrigger
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: websocket trigger deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/WebsocketTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/websocket_triggers/list:
    get:
      summary: list websocket triggers
      operationId: listWebsocketTriggers
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: websocket trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WebsocketTrigger"

  /w/{workspace}/websocket_triggers/exists/{path}:
    get:
      summary: does websocket trigger exists
      operationId: existsWebsocketTrigger
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: websocket trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/websocket_triggers/setmode/{path}:
    post:
      summary: set enabled websocket trigger
      operationId: setWebsocketTriggerMode
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated websocket trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: websocket trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/websocket_triggers/test:
    post:
      summary: test websocket connection
      operationId: testWebsocketConnection
      tags:
        - websocket_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test websocket connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                url_runnable_args:
                  $ref: "#/components/schemas/ScriptArgs"
                can_return_message:
                  type: boolean
              required:
                - url
                - can_return_message
      responses:
        "200":
          description: successfuly connected to websocket
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/kafka_triggers/create:
    post:
      summary: create kafka trigger
      operationId: createKafkaTrigger
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new kafka trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewKafkaTrigger"
      responses:
        "201":
          description: kafka trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/kafka_triggers/update/{path}:
    post:
      summary: update kafka trigger
      operationId: updateKafkaTrigger
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditKafkaTrigger"
      responses:
        "200":
          description: kafka trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/kafka_triggers/delete/{path}:
    delete:
      summary: delete kafka trigger
      operationId: deleteKafkaTrigger
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: kafka trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/kafka_triggers/get/{path}:
    get:
      summary: get kafka trigger
      operationId: getKafkaTrigger
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: kafka trigger deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/KafkaTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/kafka_triggers/list:
    get:
      summary: list kafka triggers
      operationId: listKafkaTriggers
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: kafka trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/KafkaTrigger"

  /w/{workspace}/kafka_triggers/exists/{path}:
    get:
      summary: does kafka trigger exists
      operationId: existsKafkaTrigger
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: kafka trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/kafka_triggers/setmode/{path}:
    post:
      summary: set enabled kafka trigger
      operationId: setKafkaTriggerMode
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated kafka trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: kafka trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/kafka_triggers/test:
    post:
      summary: test kafka connection
      operationId: testKafkaConnection
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test kafka connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                connection:
                  type: object
              required:
                - connection
      responses:
        "200":
          description: successfuly connected to kafka brokers
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/kafka_triggers/reset_offsets/{path}:
    post:
      summary: reset kafka trigger offsets to earliest
      operationId: resetKafkaOffsets
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: kafka trigger offsets reset successfully

  /w/{workspace}/kafka_triggers/commit_offsets/{path}:
    post:
      summary: commit kafka offsets for a specific trigger
      operationId: commitKafkaOffsets
      tags:
        - kafka_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: offsets to commit
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                topic:
                  type: string
                partition:
                  type: integer
                  format: int32
                offset:
                  type: integer
                  format: int64
              required:
                - topic
                - partition
                - offset
      responses:
        "200":
          description: kafka offsets committed successfully

  /w/{workspace}/nats_triggers/create:
    post:
      summary: create nats trigger
      operationId: createNatsTrigger
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new nats trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewNatsTrigger"
      responses:
        "201":
          description: nats trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/nats_triggers/update/{path}:
    post:
      summary: update nats trigger
      operationId: updateNatsTrigger
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditNatsTrigger"
      responses:
        "200":
          description: nats trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/nats_triggers/delete/{path}:
    delete:
      summary: delete nats trigger
      operationId: deleteNatsTrigger
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: nats trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/nats_triggers/get/{path}:
    get:
      summary: get nats trigger
      operationId: getNatsTrigger
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: nats trigger deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/NatsTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/nats_triggers/list:
    get:
      summary: list nats triggers
      operationId: listNatsTriggers
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: nats trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/NatsTrigger"

  /w/{workspace}/nats_triggers/exists/{path}:
    get:
      summary: does nats trigger exists
      operationId: existsNatsTrigger
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: nats trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/nats_triggers/setmode/{path}:
    post:
      summary: set enabled nats trigger
      operationId: setNatsTriggerMode
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated nats trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: nats trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/nats_triggers/test:
    post:
      summary: test NATS connection
      operationId: testNatsConnection
      tags:
        - nats_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test nats connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                connection:
                  type: object
              required:
                - connection
      responses:
        "200":
          description: successfuly connected to NATS servers
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/sqs_triggers/create:
    post:
      summary: create sqs trigger
      operationId: createSqsTrigger
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new sqs trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewSqsTrigger"
      responses:
        "201":
          description: sqs trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/sqs_triggers/update/{path}:
    post:
      summary: update sqs trigger
      operationId: updateSqsTrigger
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditSqsTrigger"
      responses:
        "200":
          description: sqs trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/sqs_triggers/delete/{path}:
    delete:
      summary: delete sqs trigger
      operationId: deleteSqsTrigger
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: sqs trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/sqs_triggers/get/{path}:
    get:
      summary: get sqs trigger
      operationId: getSqsTrigger
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: sqs trigger deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/SqsTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/sqs_triggers/list:
    get:
      summary: list sqs triggers
      operationId: listSqsTriggers
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: sqs trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/SqsTrigger"

  /w/{workspace}/sqs_triggers/exists/{path}:
    get:
      summary: does sqs trigger exists
      operationId: existsSqsTrigger
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: sqs trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/sqs_triggers/setmode/{path}:
    post:
      summary: set enabled sqs trigger
      operationId: setSqsTriggerMode
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated sqs trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: sqs trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/sqs_triggers/test:
    post:
      summary: test sqs connection
      operationId: testSqsConnection
      tags:
        - sqs_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test sqs connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                connection:
                  type: object
              required:
                - connection
      responses:
        "200":
          description: successfuly connected to sqs
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/native_triggers/integrations/list:
    get:
      summary: list available native trigger services
      operationId: listNativeTriggerServices
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: native trigger services list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WorkspaceIntegrations"

  /w/{workspace}/native_triggers/integrations/{service_name}/exists:
    get:
      summary: check if integrations for a particular service exists
      operationId: checkIfNativeTriggersServiceExists
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      responses:
        "200":
          description: integration exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/native_triggers/integrations/{service_name}/create:
    post:
      summary: create native trigger service
      operationId: createNativeTriggerService
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      requestBody:
        description: new native trigger service
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkspaceOAuthConfig"
      responses:
        "201":
          description: native trigger service created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/native_triggers/integrations/{service_name}/generate_connect_url:
    post:
      summary: generate connect url for native trigger service
      operationId: generateNativeTriggerServiceConnectUrl
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      requestBody:
        description: redirect_uri
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RedirectUri"
      responses:
        "200":
          description: native trigger service connect url
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/native_triggers/integrations/{service_name}/instance_sharing_available:
    get:
      summary: check if instance-level credential sharing is available for a service
      operationId: checkInstanceSharingAvailable
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      responses:
        "200":
          description: whether instance sharing is available
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/native_triggers/integrations/{service_name}/generate_instance_connect_url:
    post:
      summary: generate connect url using instance-level credentials
      operationId: generateInstanceConnectUrl
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      requestBody:
        description: redirect_uri
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RedirectUri"
      responses:
        "200":
          description: authorization URL using instance credentials
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/native_triggers/integrations/{service_name}/delete:
    delete:
      summary: delete native trigger service
      operationId: deleteNativeTriggerService
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      responses:
        "200":
          description: native trigger service deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/native_triggers/integrations/{service_name}/callback:
    post:
      summary: native trigger service oauth callback
      operationId: nativeTriggerServiceCallback
      tags:
        - workspace_integration
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      requestBody:
        description: OAuth callback data
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                state:
                  type: string
                redirect_uri:
                  type: string
                resource_path:
                  type: string
              required:
                - code
                - state
                - redirect_uri
      responses:
        "200":
          description: native trigger service oauth completed
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/native_triggers/{service_name}/create:
    post:
      summary: create native trigger
      description: |
        Creates a new native trigger for the specified service.
        Requires write access to the script or flow that the trigger will be associated with.
      operationId: createNativeTrigger
      tags:
        - native_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      requestBody:
        description: new native trigger configuration
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NativeTriggerData"
      responses:
        "201":
          description: native trigger created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateTriggerResponse"

  /w/{workspace}/native_triggers/{service_name}/update/{external_id}:
    post:
      summary: update native trigger
      description: |
        Updates an existing native trigger.
        Requires write access to the script or flow that the trigger is associated with.
      operationId: updateNativeTrigger
      tags:
        - native_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
        - name: external_id
          in: path
          required: true
          description: The external ID of the trigger from the external service
          schema:
            type: string
      requestBody:
        description: updated native trigger configuration
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NativeTriggerData"
      responses:
        "200":
          description: native trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/native_triggers/{service_name}/get/{external_id}:
    get:
      summary: get native trigger
      description: |
        Retrieves a native trigger by its external ID.
        Requires write access to the script or flow that the trigger is associated with.
      operationId: getNativeTrigger
      tags:
        - native_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
        - name: external_id
          in: path
          required: true
          description: The external ID of the trigger from the external service
          schema:
            type: string
      responses:
        "200":
          description: native trigger with external configuration
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NativeTriggerWithExternal"

  /w/{workspace}/native_triggers/{service_name}/delete/{external_id}:
    delete:
      summary: delete native trigger
      description: |
        Deletes a native trigger by its external ID.
        Requires write access to the script or flow that the trigger is associated with.
      operationId: deleteNativeTrigger
      tags:
        - native_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
        - name: external_id
          in: path
          required: true
          description: The external ID of the trigger from the external service
          schema:
            type: string
      responses:
        "200":
          description: native trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/native_triggers/{service_name}/list:
    get:
      summary: list native triggers
      description: Lists all native triggers for the specified service in the workspace.
      operationId: listNativeTriggers
      tags:
        - native_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by script path
          in: query
          schema:
            type: string
        - name: is_flow
          description: filter by is_flow
          in: query
          schema:
            type: boolean
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: native triggers list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/NativeTrigger"

  /w/{workspace}/native_triggers/{service_name}/exists/{external_id}:
    get:
      summary: check if native trigger exists
      description: Checks if a native trigger with the given external ID exists.
      operationId: existsNativeTrigger
      tags:
        - native_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
        - name: external_id
          in: path
          required: true
          description: The external ID of the trigger from the external service
          schema:
            type: string
      responses:
        "200":
          description: whether the native trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/native_triggers/{service_name}/sync:
    post:
      summary: sync native triggers with external service
      operationId: syncNativeTriggers
      tags:
        - native_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
      responses:
        "200":
          description: sync completed successfully

  /w/{workspace}/native_triggers/nextcloud/events:
    get:
      summary: list available NextCloud events
      operationId: listNextCloudEvents
      tags:
        - native_trigger
      parameters:
        - name: workspace
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: list of available NextCloud events
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/NextCloudEventType"

  /w/{workspace}/native_triggers/google/calendars:
    get:
      summary: list Google Calendars for the authenticated user
      operationId: listGoogleCalendars
      tags:
        - native_trigger
      parameters:
        - name: workspace
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: list of Google Calendars
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/GoogleCalendarEntry"

  /w/{workspace}/native_triggers/google/drive/files:
    get:
      summary: list or search Google Drive files
      operationId: listGoogleDriveFiles
      tags:
        - native_trigger
      parameters:
        - name: workspace
          in: path
          required: true
          schema:
            type: string
        - name: q
          in: query
          description: search query to filter files by name
          schema:
            type: string
        - name: parent_id
          in: query
          description: folder ID to list children of
          schema:
            type: string
        - name: page_token
          in: query
          description: token for next page of results
          schema:
            type: string
        - name: shared_with_me
          in: query
          description: if true, list files shared with the user
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: list of Google Drive files
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/GoogleDriveFilesResponse"

  /w/{workspace}/native_triggers/google/drive/shared_drives:
    get:
      summary: list shared drives accessible to the user
      operationId: listGoogleSharedDrives
      tags:
        - native_trigger
      parameters:
        - name: workspace
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: list of shared drives
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/SharedDriveEntry"

  /w/{workspace}/native_triggers/github/repos:
    get:
      summary: list GitHub repositories accessible to the user
      operationId: listGithubRepos
      tags:
        - native_trigger
      parameters:
        - name: workspace
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: list of GitHub repositories
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/GithubRepoEntry"

  /native_triggers/{service_name}/w/{workspace_id}/webhook/{internal_id}:
    post:
      summary: receive webhook from external native trigger service
      operationId: nativeTriggerWebhook
      tags:
        - native_trigger
      parameters:
        - name: service_name
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/NativeServiceName"
        - name: workspace_id
          in: path
          required: true
          schema:
            type: string
        - name: internal_id
          in: path
          required: true
          schema:
            type: integer
            format: int64
          description: The internal database ID of the trigger
      requestBody:
        description: webhook payload from external service
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
          text/plain:
            schema:
              type: string
      responses:
        "200":
          description: webhook received successfully
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/mqtt_triggers/create:
    post:
      summary: create mqtt trigger
      operationId: createMqttTrigger
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new mqtt trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewMqttTrigger"
      responses:
        "201":
          description: mqtt trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/mqtt_triggers/update/{path}:
    post:
      summary: update mqtt trigger
      operationId: updateMqttTrigger
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditMqttTrigger"
      responses:
        "200":
          description: mqtt trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/mqtt_triggers/delete/{path}:
    delete:
      summary: delete mqtt trigger
      operationId: deleteMqttTrigger
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: mqtt trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/mqtt_triggers/get/{path}:
    get:
      summary: get mqtt trigger
      operationId: getMqttTrigger
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: mqtt trigger deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/MqttTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/mqtt_triggers/list:
    get:
      summary: list mqtt triggers
      operationId: listMqttTriggers
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: mqtt trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/MqttTrigger"

  /w/{workspace}/mqtt_triggers/exists/{path}:
    get:
      summary: does mqtt trigger exists
      operationId: existsMqttTrigger
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: mqtt trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/mqtt_triggers/setmode/{path}:
    post:
      summary: set enabled mqtt trigger
      operationId: setMqttTriggerMode
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated mqtt trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: mqtt trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/mqtt_triggers/test:
    post:
      summary: test mqtt connection
      operationId: testMqttConnection
      tags:
        - mqtt_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test mqtt connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                connection:
                  type: object
              required:
                - connection
      responses:
        "200":
          description: successfully connected to mqtt
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/amqp_triggers/create:
    post:
      summary: create amqp trigger
      operationId: createAmqpTrigger
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new amqp trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewAmqpTrigger"
      responses:
        "201":
          description: amqp trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/amqp_triggers/update/{path}:
    post:
      summary: update amqp trigger
      operationId: updateAmqpTrigger
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditAmqpTrigger"
      responses:
        "200":
          description: amqp trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/amqp_triggers/delete/{path}:
    delete:
      summary: delete amqp trigger
      operationId: deleteAmqpTrigger
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: amqp trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/amqp_triggers/get/{path}:
    get:
      summary: get amqp trigger
      operationId: getAmqpTrigger
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: amqp trigger retrieved
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/AmqpTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/amqp_triggers/list:
    get:
      summary: list amqp triggers
      operationId: listAmqpTriggers
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: amqp trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AmqpTrigger"

  /w/{workspace}/amqp_triggers/exists/{path}:
    get:
      summary: does amqp trigger exists
      operationId: existsAmqpTrigger
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: amqp trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/amqp_triggers/setmode/{path}:
    post:
      summary: set enabled amqp trigger
      operationId: setAmqpTriggerMode
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated amqp trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: amqp trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/amqp_triggers/test:
    post:
      summary: test amqp connection
      operationId: testAmqpConnection
      tags:
        - amqp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test amqp connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                amqp_resource_path:
                  type: string
                  description: Path to the AMQP resource containing broker connection configuration
              required:
                - amqp_resource_path
      responses:
        "200":
          description: successfully connected to amqp
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/gcp_triggers/create:
    post:
      summary: create gcp trigger
      operationId: createGcpTrigger
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new gcp trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GcpTriggerData"
      responses:
        "201":
          description: gcp trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/gcp_triggers/update/{path}:
    post:
      summary: update gcp trigger
      operationId: updateGcpTrigger
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GcpTriggerData"
      responses:
        "200":
          description: gcp trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/gcp_triggers/delete/{path}:
    delete:
      summary: delete gcp trigger
      operationId: deleteGcpTrigger
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: gcp trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/gcp_triggers/get/{path}:
    get:
      summary: get gcp trigger
      operationId: getGcpTrigger
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: gcp trigger deleted
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/GcpTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/gcp_triggers/list:
    get:
      summary: list gcp triggers
      operationId: listGcpTriggers
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: gcp trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/GcpTrigger"

  /w/{workspace}/gcp_triggers/exists/{path}:
    get:
      summary: does gcp trigger exists
      operationId: existsGcpTrigger
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: gcp trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/gcp_triggers/setmode/{path}:
    post:
      summary: set enabled gcp trigger
      operationId: setGcpTriggerMode
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated gcp trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: gcp trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/gcp_triggers/test:
    post:
      summary: test gcp connection
      operationId: testGcpConnection
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test gcp connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                connection:
                  type: object
              required:
                - connection
      responses:
        "200":
          description: try to connect to a gcp broker
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/gcp_triggers/subscriptions/delete/{path}:
    delete:
      summary: delete gcp trigger
      operationId: deleteGcpSubscription
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: args to delete subscription from google cloud
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DeleteGcpSubscription"
      responses:
        "200":
          description: gcp trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/gcp_triggers/topics/list/{path}:
    get:
      summary: list all topics of google cloud service
      operationId: listGoogleTopics
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: get all google topics
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/gcp_triggers/subscriptions/list/{path}:
    post:
      summary: list all subscription of a give topic from google cloud service
      operationId: listAllTGoogleTopicSubscriptions
      tags:
        - gcp_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: args to get subscription's topic from google cloud
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GetAllTopicSubscription"
      responses:
        "200":
          description: get all google topic subscriptions name
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/azure_triggers/create:
    post:
      summary: create an Azure Event Grid trigger
      operationId: createAzureTrigger
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureTriggerData"
      responses:
        "201":
          description: azure trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/azure_triggers/update/{path}:
    post:
      summary: update an Azure Event Grid trigger
      operationId: updateAzureTrigger
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureTriggerData"
      responses:
        "200":
          description: azure trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/azure_triggers/delete/{path}:
    delete:
      summary: delete an Azure Event Grid trigger
      operationId: deleteAzureTrigger
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: azure trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/azure_triggers/get/{path}:
    get:
      summary: get an Azure Event Grid trigger
      operationId: getAzureTrigger
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: azure trigger
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/AzureTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/azure_triggers/list:
    get:
      summary: list azure triggers
      operationId: listAzureTriggers
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by exact path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: azure trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AzureTrigger"

  /w/{workspace}/azure_triggers/exists/{path}:
    get:
      summary: check whether an azure trigger exists
      operationId: existsAzureTrigger
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: true/false
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/azure_triggers/setmode/{path}:
    post:
      summary: set azure trigger mode
      operationId: setAzureTriggerMode
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: trigger mode updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/azure_triggers/test:
    post:
      summary: test Azure service principal connection
      operationId: testAzureConnection
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TestAzureConnection"
      responses:
        "200":
          description: connection successful
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/azure_triggers/namespaces/topics/list/{path}:
    post:
      summary: list topics under an Event Grid Namespace
      operationId: listAzureNamespaceTopics
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureListTopics"
      responses:
        "200":
          description: topic list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object

  /w/{workspace}/azure_triggers/namespaces/subscriptions/list/{path}:
    post:
      summary: list subscriptions under a Namespace topic
      operationId: listAzureNamespaceSubscriptions
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureListSubscriptions"
      responses:
        "200":
          description: subscription list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object

  /w/{workspace}/azure_triggers/subscriptions/delete/{path}:
    delete:
      summary: delete an Event Grid subscription on Azure
      operationId: deleteAzureSubscription
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AzureDeleteSubscription"
      responses:
        "200":
          description: subscription deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/azure_triggers/namespaces/list/{path}:
    post:
      summary: list Event Grid Namespaces the service principal can access
      operationId: listAzureNamespaces
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: namespace list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AzureArmResource"

  /w/{workspace}/azure_triggers/basic/topics/list/{path}:
    post:
      summary: list Basic Event Grid topics + system topics the service principal can access
      operationId: listAzureBasicTopics
      tags:
        - azure_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: topic list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AzureArmResource"

  /w/{workspace}/postgres_triggers/postgres/version/{path}:
    get:
      summary: get postgres version
      operationId: getPostgresVersion
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: postgres version
          content:
            application/json:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/is_valid_postgres_configuration/{path}:
    get:
      summary: check if postgres configuration is set to logical
      operationId: isValidPostgresConfiguration
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: boolean that indicates if postgres is set to logical level or not
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/postgres_triggers/create_template_script:
    post:
      summary: create template script
      operationId: createTemplateScript
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: template script
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TemplateScript"
      responses:
        "200":
          description: custom id to retrieve template script
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/get_template_script/{id}:
    get:
      summary: get template script
      operationId: getTemplateScript
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Id"
      responses:
        "200":
          description: template script
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/slot/list/{path}:
    get:
      summary: list postgres replication slot
      operationId: listPostgresReplicationSlot
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: list postgres slot
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/SlotList"

  /w/{workspace}/postgres_triggers/slot/create/{path}:
    post:
      summary: create replication slot for postgres
      operationId: createPostgresReplicationSlot
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: new slot for postgres
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Slot"
      responses:
        "201":
          description: slot created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/slot/delete/{path}:
    delete:
      summary: delete postgres replication slot
      operationId: deletePostgresReplicationSlot
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: replication slot of postgres
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Slot"
      responses:
        "200":
          description: postgres replication slot deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/publication/list/{path}:
    get:
      summary: list postgres publication
      operationId: listPostgresPublication
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: database publication list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/postgres_triggers/publication/get/{publication}/{path}:
    get:
      summary: get postgres publication
      operationId: getPostgresPublication
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/PublicationName"
      responses:
        "200":
          description: postgres publication get
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PublicationData"

  /w/{workspace}/postgres_triggers/publication/create/{publication}/{path}:
    post:
      summary: create publication for postgres
      operationId: createPostgresPublication
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/PublicationName"
      requestBody:
        description: new publication for postgres
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PublicationData"
      responses:
        "201":
          description: publication created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/publication/update/{publication}/{path}:
    post:
      summary: update publication for postgres
      operationId: updatePostgresPublication
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/PublicationName"
      requestBody:
        description: update publication for postgres
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PublicationData"
      responses:
        "201":
          description: publication updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/publication/delete/{publication}/{path}:
    delete:
      summary: delete postgres publication
      operationId: deletePostgresPublication
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/PublicationName"
      responses:
        "200":
          description: postgres publication deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/create:
    post:
      summary: create postgres trigger
      operationId: createPostgresTrigger
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new postgres trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewPostgresTrigger"
      responses:
        "201":
          description: postgres trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/update/{path}:
    post:
      summary: update postgres trigger
      operationId: updatePostgresTrigger
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditPostgresTrigger"
      responses:
        "200":
          description: postgres trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/delete/{path}:
    delete:
      summary: delete postgres trigger
      operationId: deletePostgresTrigger
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: postgres trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/get/{path}:
    get:
      summary: get postgres trigger
      operationId: getPostgresTrigger
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: get postgres trigger
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/PostgresTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/postgres_triggers/list:
    get:
      summary: list postgres triggers
      operationId: listPostgresTriggers
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: postgres trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/PostgresTrigger"

  /w/{workspace}/postgres_triggers/exists/{path}:
    get:
      summary: does postgres trigger exists
      operationId: existsPostgresTrigger
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: postgres trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/postgres_triggers/setmode/{path}:
    post:
      summary: set enabled postgres trigger
      operationId: setPostgresTriggerMode
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated postgres trigger enable
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: postgres trigger enabled set
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/postgres_triggers/test:
    post:
      summary: test postgres connection
      operationId: testPostgresConnection
      tags:
        - postgres_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: test postgres connection
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                database:
                  type: string
              required:
                - database
      responses:
        "200":
          description: successfuly connected to postgres
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/email_triggers/create:
    post:
      summary: create email trigger
      operationId: createEmailTrigger
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: new email trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NewEmailTrigger"
      responses:
        "201":
          description: email trigger created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/email_triggers/update/{path}:
    post:
      summary: update email trigger
      operationId: updateEmailTrigger
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: updated trigger
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditEmailTrigger"
      responses:
        "200":
          description: email trigger updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/email_triggers/delete/{path}:
    delete:
      summary: delete email trigger
      operationId: deleteEmailTrigger
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: email trigger deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/email_triggers/get/{path}:
    get:
      summary: get email trigger
      operationId: getEmailTrigger
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - $ref: "#/components/parameters/GetDraft"
      responses:
        "200":
          description: email trigger retrieved
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/EmailTrigger"
                  - $ref: "#/components/schemas/UserDraftOverlay"

  /w/{workspace}/email_triggers/list:
    get:
      summary: list email triggers
      operationId: listEmailTriggers
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
          required: true
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: path
          description: filter by path
          in: query
          schema:
            type: string
        - name: is_flow
          in: query
          schema:
            type: boolean
        - name: path_start
          in: query
          schema:
            type: string
        - name: label
          in: query
          required: false
          schema:
            type: string
          description: Filter by label
        - $ref: "#/components/parameters/IncludeDraftOnly"
      responses:
        "200":
          description: email trigger list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/EmailTrigger"

  /w/{workspace}/email_triggers/exists/{path}:
    get:
      summary: does email trigger exists
      operationId: existsEmailTrigger
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: email trigger exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/email_triggers/local_part_exists:
    post:
      summary: does email local part exists
      operationId: existsEmailLocalPart
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: email local part exists request
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                local_part:
                  type: string
                workspaced_local_part:
                  type: boolean
                trigger_path:
                  type: string

              required:
                - local_part
      responses:
        "200":
          description: email local part exists
          content:
            application/json:
              schema:
                type: boolean
  /w/{workspace}/email_triggers/setmode/{path}:
    post:
      summary: enable/disable email trigger
      operationId: setEmailTriggerMode
      tags:
        - email_trigger
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  $ref: "#/components/schemas/TriggerMode"
                force:
                  type: boolean
                  description: >
                    Bypass the parent-state conflict warning when enabling a
                    trigger in a fork whose parent has the same path enabled.
              required:
                - mode
      responses:
        "200":
          description: email trigger enable/disable
          content:
            text/plain:
              schema:
                type: string

  /groups/list:
    get:
      summary: list instance groups
      operationId: listInstanceGroups
      tags:
        - group
      responses:
        "200":
          description: instance group list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/InstanceGroup"
  /groups/list_with_workspaces:
    get:
      summary: list instance groups with workspace information
      operationId: listInstanceGroupsWithWorkspaces
      tags:
        - group
      responses:
        "200":
          description: instance group list with workspaces
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/InstanceGroupWithWorkspaces"

  /groups/get/{name}:
    get:
      summary: get instance group
      operationId: getInstanceGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: instance group
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InstanceGroupWithWorkspaces"

  /groups/create:
    post:
      summary: create instance group
      operationId: createInstanceGroup
      tags:
        - group
      requestBody:
        description: create instance group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                summary:
                  type: string
              required:
                - name
      responses:
        "200":
          description: instance group created
          content:
            text/plain:
              schema:
                type: string

  /groups/update/{name}:
    post:
      summary: update instance group
      operationId: updateInstanceGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: update instance group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                new_summary:
                  type: string
                instance_role:
                  type: string
                  nullable: true
                  description: "Instance-level role for group members. 'superadmin', 'devops', 'user' or empty to clear."
              required:
                - new_summary
      responses:
        "200":
          description: instance group updated
          content:
            text/plain:
              schema:
                type: string

  /groups/delete/{name}:
    delete:
      summary: delete instance group
      operationId: deleteInstanceGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: instance group deleted
          content:
            text/plain:
              schema:
                type: string

  /groups/adduser/{name}:
    post:
      summary: add user to instance group
      operationId: addUserToInstanceGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: user to add to instance group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
              required:
                - email
      responses:
        "200":
          description: user added to instance group
          content:
            text/plain:
              schema:
                type: string

  /groups/removeuser/{name}:
    post:
      summary: remove user from instance group
      operationId: removeUserFromInstanceGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: user to remove from instance group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
              required:
                - email
      responses:
        "200":
          description: user removed from instance group
          content:
            text/plain:
              schema:
                type: string
  /groups/export:
    get:
      summary: export instance groups
      operationId: exportInstanceGroups
      tags:
        - group
      responses:
        "200":
          description: exported instance groups
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ExportedInstanceGroup"

  /groups/overwrite:
    post:
      summary: overwrite instance groups
      operationId: overwriteInstanceGroups
      tags:
        - group
      requestBody:
        description: overwrite instance groups
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/ExportedInstanceGroup"
      responses:
        "200":
          description: success message
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/groups/list:
    get:
      summary: list groups
      operationId: listGroups
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: group list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Group"

  /w/{workspace}/groups/listnames:
    get:
      summary: list group names
      operationId: listGroupNames
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: only_member_of
          in: query
          description: only list the groups the user is member of (default false)
          schema:
            type: boolean
      responses:
        "200":
          description: group list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/groups/create:
    post:
      summary: create group
      operationId: createGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: create group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                summary:
                  type: string
              required:
                - name
      responses:
        "200":
          description: group created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/groups/update/{name}:
    post:
      summary: update group
      operationId: updateGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: updated group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                summary:
                  type: string
      responses:
        "200":
          description: group updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/groups/delete/{name}:
    delete:
      summary: delete group
      operationId: deleteGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: group deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/groups/get/{name}:
    get:
      summary: get group
      operationId: getGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: group
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Group"

  /w/{workspace}/groups/adduser/{name}:
    post:
      summary: add user to group
      operationId: addUserToGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: added user to group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
      responses:
        "200":
          description: user added to group
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/groups/removeuser/{name}:
    post:
      summary: remove user to group
      operationId: removeUserToGroup
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: added user to group
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
      responses:
        "200":
          description: user removed from group
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/groups_history/get/{name}:
    get:
      summary: get group permission history
      operationId: getGroupPermissionHistory
      tags:
        - group
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: group permission history
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: integer
                    changed_by:
                      type: string
                    changed_at:
                      type: string
                      format: date-time
                    change_type:
                      type: string
                    member_affected:
                      type: string
                      nullable: true

  /w/{workspace}/folders/list:
    get:
      summary: list folders
      operationId: listFolders
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: folder list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Folder"

  /w/{workspace}/folders/listnames:
    get:
      summary: list folder names
      operationId: listFolderNames
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: only_member_of
          in: query
          description: only list the folders the user is member of (default false)
          schema:
            type: boolean
      responses:
        "200":
          description: folder list
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /w/{workspace}/folders/create:
    post:
      summary: create folder
      operationId: createFolder
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: create folder
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                summary:
                  type: string
                owners:
                  type: array
                  items:
                    type: string
                extra_perms:
                  additionalProperties:
                    type: boolean
                default_permissioned_as:
                  $ref: '#/components/schemas/FolderDefaultPermissionedAs'
                labels:
                  type: array
                  items:
                    type: string
              required:
                - name
      responses:
        "200":
          description: folder created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/folders/update/{name}:
    post:
      summary: update folder
      operationId: updateFolder
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: update folder
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                summary:
                  type: string
                owners:
                  type: array
                  items:
                    type: string
                extra_perms:
                  additionalProperties:
                    type: boolean
                default_permissioned_as:
                  $ref: '#/components/schemas/FolderDefaultPermissionedAs'
                labels:
                  type: array
                  items:
                    type: string
      responses:
        "200":
          description: folder updated
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/folders/delete/{name}:
    delete:
      summary: delete folder
      operationId: deleteFolder
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: folder deleted
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/folders/get/{name}:
    get:
      summary: get folder
      operationId: getFolder
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: folder
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Folder"

  /w/{workspace}/folders/exists/{name}:
    get:
      summary: exists folder
      operationId: existsFolder
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: folder exists
          content:
            application/json:
              schema:
                type: boolean

  /w/{workspace}/folders/getusage/{name}:
    get:
      summary: get folder usage
      operationId: getFolderUsage
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: folder
          content:
            application/json:
              schema:
                type: object
                properties:
                  scripts:
                    type: number
                  flows:
                    type: number
                  apps:
                    type: number
                  resources:
                    type: number
                  variables:
                    type: number
                  schedules:
                    type: number
                required:
                  - scripts
                  - flows
                  - apps
                  - resources
                  - variables
                  - schedules

  /w/{workspace}/folders/addowner/{name}:
    post:
      summary: add owner to folder
      operationId: addOwnerToFolder
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: owner user to folder
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner:
                  type: string
              required:
                - owner

      responses:
        "200":
          description: owner added to folder
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/folders/removeowner/{name}:
    post:
      summary: remove owner to folder
      operationId: removeOwnerToFolder
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: added owner to folder
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner:
                  type: string
                write:
                  type: boolean
              required:
                - owner
      responses:
        "200":
          description: owner removed from folder
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/folders_history/get/{name}:
    get:
      summary: get folder permission history
      operationId: getFolderPermissionHistory
      tags:
        - folder
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Name"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: folder permission history
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: integer
                    changed_by:
                      type: string
                    changed_at:
                      type: string
                      format: date-time
                    change_type:
                      type: string
                    affected:
                      type: string
                      nullable: true

  /workers/list:
    get:
      summary: list workers
      operationId: listWorkers
      x-mcp-tool: true
      tags:
        - worker
      parameters:
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - name: ping_since
          in: query
          required: false
          description: number of seconds the worker must have had a last ping more recent of (default to 300)
          schema:
            type: integer
      responses:
        "200":
          description: a list of workers
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/WorkerPing"

  /workers/exists_workers_with_tags:
    get:
      summary: exists workers with tags
      operationId: existsWorkersWithTags
      tags:
        - worker
      parameters:
        - name: tags
          in: query
          required: true
          description: comma separated list of tags
          schema:
            type: string
        - name: workspace
          in: query
          required: false
          description: workspace to filter tags visibility (required when TAGS_ARE_SENSITIVE is enabled for non-superadmins)
          schema:
            type: string
      responses:
        "200":
          description: map of tags to whether at least one worker with the tag exists
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: boolean

  /workers/queue_metrics:
    get:
      summary: get queue metrics
      operationId: getQueueMetrics
      tags:
        - worker
      responses:
        "200":
          description: metrics
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    values:
                      type: array
                      items:
                        type: object
                        properties:
                          created_at:
                            type: string
                          value:
                            type: number
                        required:
                          - created_at
                          - value
                  required:
                    - id
                    - values

  /workers/queue_counts:
    get:
      summary: get counts of jobs waiting for an executor per tag
      operationId: getCountsOfJobsWaitingPerTag
      tags:
        - worker
      responses:
        "200":
          description: queue counts
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: integer

  /workers/queue_running_counts:
    get:
      summary: get counts of currently running jobs per tag
      operationId: getCountsOfRunningJobsPerTag
      tags:
        - worker
      responses:
        "200":
          description: queue running counts
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: integer

  /workers/workspace_fairness_events:
    get:
      summary: list last 100 workspace-fairness cap/uncap events (cloud-only)
      operationId: getWorkspaceFairnessEvents
      tags:
        - worker
      responses:
        "200":
          description: workspace fairness events (empty on non-cloud)
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    timestamp:
                      type: string
                      format: date-time
                    operation:
                      type: string
                    workspace_id:
                      type: string
                      nullable: true
                    parameters:
                      type: object
                      nullable: true
                      additionalProperties: true
                  required:
                    - timestamp
                    - operation

  /configs/list_worker_groups:
    get:
      summary: list worker groups
      operationId: listWorkerGroups
      tags:
        - config
      responses:
        "200":
          description: a list of worker group configs
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                    config: {}
                  required:
                    - name
                    - config

  /configs/get/{name}:
    get:
      summary: get config
      operationId: get config
      tags:
        - config
      parameters:
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: a config
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Configs"

  /configs/update/{name}:
    post:
      summary: Update config
      operationId: updateConfig
      tags:
        - config
      parameters:
        - $ref: "#/components/parameters/Name"
      requestBody:
        description: worker group
        required: true
        content:
          application/json:
            schema: {}
      responses:
        "200":
          description: Update a worker group
          content:
            text/plain:
              schema:
                type: string
    delete:
      summary: Delete Config
      operationId: deleteConfig
      tags:
        - config
      parameters:
        - $ref: "#/components/parameters/Name"
      responses:
        "200":
          description: Delete config
          content:
            text/plain:
              schema:
                type: string

  /configs/list:
    get:
      summary: list configs
      operationId: listConfigs
      tags:
        - config
      responses:
        "200":
          description: list of configs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Config"

  /configs/list_autoscaling_events/{worker_group}:
    get:
      summary: List autoscaling events
      operationId: listAutoscalingEvents
      tags:
        - config
      parameters:
        - name: worker_group
          in: path
          required: true
          schema:
            type: string
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: List of autoscaling events
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AutoscalingEvent"

  /configs/native_kubernetes_autoscaling_healthcheck:
    get:
      summary: Check Kubernetes autoscaling health for a worker group
      operationId: nativeKubernetesAutoscalingHealthcheck
      tags:
        - config
      responses:
        "200":
          description: Kubernetes autoscaling is healthy
        "400":
          description: Error
          content:
            text/plain:
              schema:
                type: string

  /configs/list_available_python_versions:
    get:
      summary: Get currently available python versions provided by UV.
      operationId: listAvailablePythonVersions
      tags:
        - config
      # parameters:
      responses:
        "200":
          description: List of python versions
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

  /configs/list_all_workspace_dependencies:
    get:
      summary: list all workspace dependencies
      operationId: listAllWorkspaceDependencies
      tags:
        - config
      responses:
        "200":
          description: a list of workspace dependency summaries
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    workspace_id:
                      type: string
                    name:
                      type: string
                    language:
                      $ref: "#/components/schemas/ScriptLang"
                  required:
                    - workspace_id
                    - language

  /configs/list_all_dedicated_with_deps:
    get:
      summary: list all dedicated scripts with their dependencies
      operationId: listAllDedicatedWithDeps
      tags:
        - config
      responses:
        "200":
          description: a list of dedicated scripts with workspace dependencies
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    workspace_id:
                      type: string
                    path:
                      type: string
                    language:
                      $ref: "#/components/schemas/ScriptLang"
                    workspace_dep_names:
                      type: array
                      items:
                        type: string
                  required:
                    - workspace_id
                    - path
                    - language
                    - workspace_dep_names

  /agent_workers/create_agent_token:
    post:
      summary: create agent token
      operationId: createAgentToken
      tags:
        - agent_workers
      requestBody:
        description: agent token
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                worker_group:
                  type: string
                tags:
                  type: array
                  items:
                    type: string
                exp:
                  type: integer
              required:
                - worker_group
                - tags
                - exp
      responses:
        "200":
          description: agent token created
          content:
            application/json:
              schema:
                type: string

  /agent_workers/blacklist_token:
    post:
      summary: blacklist agent token (requires super admin)
      operationId: blacklistAgentToken
      tags:
        - agent_workers
      requestBody:
        description: token to blacklist
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                token:
                  type: string
                  description: The agent token to blacklist
                expires_at:
                  type: string
                  format: date-time
                  description: Optional expiration date for the blacklist entry
              required:
                - token
      responses:
        "200":
          description: token blacklisted successfully

  /agent_workers/remove_blacklist_token:
    post:
      summary: remove agent token from blacklist (requires super admin)
      operationId: removeBlacklistAgentToken
      tags:
        - agent_workers
      requestBody:
        description: token to remove from blacklist
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                token:
                  type: string
                  description: The agent token to remove from blacklist
              required:
                - token
      responses:
        "200":
          description: token removed from blacklist successfully

  /agent_workers/list_blacklisted_tokens:
    get:
      summary: list blacklisted agent tokens (requires super admin)
      operationId: listBlacklistedAgentTokens
      tags:
        - agent_workers
      parameters:
        - name: include_expired
          in: query
          description: Whether to include expired blacklisted tokens
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: list of blacklisted tokens
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    token:
                      type: string
                      description: The blacklisted token (without prefix)
                    expires_at:
                      type: string
                      format: date-time
                      description: When the blacklist entry expires
                    blacklisted_at:
                      type: string
                      format: date-time
                      description: When the token was blacklisted
                    blacklisted_by:
                      type: string
                      description: Email of the user who blacklisted the token
                  required:
                    - token
                    - expires_at
                    - blacklisted_at
                    - blacklisted_by

  /agent_workers/get_min_version:
    get:
      summary: get minimum worker version across all workers
      operationId: getMinVersion
      tags:
        - agent_workers
      responses:
        "200":
          description: minimum worker version
          content:
            application/json:
              schema:
                type: string
                description: Minimum semantic version across all workers (e.g. "1.583.0")

  /w/{workspace}/acls/get/{kind}/{path}:
    get:
      summary: get granular acls
      operationId: getGranularAcls
      tags:
        - granular_acl
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: kind
          in: path
          required: true
          schema:
            type: string
            enum:
              [
                script,
                group_,
                resource,
                schedule,
                variable,
                flow,
                folder,
                app,
                raw_app,
                http_trigger,
                websocket_trigger,
                kafka_trigger,
                nats_trigger,
                postgres_trigger,
                mqtt_trigger,
                amqp_trigger,
                gcp_trigger,
                azure_trigger,
                sqs_trigger,
                email_trigger,
                volume,
              ]
      responses:
        "200":
          description: acls
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: boolean

  /w/{workspace}/acls/add/{kind}/{path}:
    post:
      summary: add granular acls
      operationId: addGranularAcls
      tags:
        - granular_acl
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: kind
          in: path
          required: true
          schema:
            type: string
            enum:
              [
                script,
                group_,
                resource,
                schedule,
                variable,
                flow,
                folder,
                app,
                raw_app,
                http_trigger,
                websocket_trigger,
                kafka_trigger,
                nats_trigger,
                postgres_trigger,
                mqtt_trigger,
                amqp_trigger,
                gcp_trigger,
                azure_trigger,
                sqs_trigger,
                email_trigger,
                volume,
              ]
      requestBody:
        description: acl to add
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner:
                  type: string
                write:
                  type: boolean
              required: [owner]
      responses:
        "200":
          description: granular acl added
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/acls/remove/{kind}/{path}:
    post:
      summary: remove granular acls
      operationId: removeGranularAcls
      tags:
        - granular_acl
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: kind
          in: path
          required: true
          schema:
            type: string
            enum:
              [
                script,
                group_,
                resource,
                schedule,
                variable,
                flow,
                folder,
                app,
                raw_app,
                http_trigger,
                websocket_trigger,
                kafka_trigger,
                nats_trigger,
                postgres_trigger,
                mqtt_trigger,
                amqp_trigger,
                gcp_trigger,
                azure_trigger,
                sqs_trigger,
                email_trigger,
                volume,
              ]
      requestBody:
        description: acl to add
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner:
                  type: string
              required: [owner]
      responses:
        "200":
          description: granular acl removed
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/capture/set_config:
    post:
      summary: set capture config
      operationId: setCaptureConfig
      tags:
        - capture
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: capture config
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                trigger_kind:
                  $ref: "#/components/schemas/CaptureTriggerKind"
                path:
                  type: string
                is_flow:
                  type: boolean
                trigger_config:
                  type: object
              required:
                - trigger_kind
                - path
                - is_flow
      responses:
        "200":
          description: capture config set
          content:
            application/json:
              schema:
                type: object

  /w/{workspace}/capture/ping_config/{trigger_kind}/{runnable_kind}/{path}:
    post:
      summary: ping capture config
      operationId: pingCaptureConfig
      tags:
        - capture
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: trigger_kind
          in: path
          required: true
          schema:
            $ref: "#/components/schemas/CaptureTriggerKind"
        - $ref: "#/components/parameters/RunnableKind"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: capture config pinged

  /w/{workspace}/capture/get_configs/{runnable_kind}/{path}:
    get:
      summary: get capture configs for a script or flow
      operationId: getCaptureConfigs
      tags:
        - capture
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableKind"
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: capture configs for a script or flow
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CaptureConfig"

  /w/{workspace}/capture/list/{runnable_kind}/{path}:
    get:
      summary: list captures for a script or flow
      operationId: listCaptures
      tags:
        - capture
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableKind"
        - $ref: "#/components/parameters/Path"
        - name: trigger_kind
          in: query
          schema:
            $ref: "#/components/schemas/CaptureTriggerKind"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: list of captures for a script or flow
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Capture"

  /w/{workspace}/capture/move/{runnable_kind}/{path}:
    post:
      summary: move captures and configs for a script or flow
      operationId: moveCapturesAndConfigs
      tags:
        - capture
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableKind"
        - $ref: "#/components/parameters/Path"
      requestBody:
        description: move captures and configs to a new path
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                new_path:
                  type: string
      responses:
        "200":
          description: captures and configs moved
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/capture/{id}:
    get:
      summary: get a capture
      operationId: getCapture
      tags:
        - capture
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: capture
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Capture"
    delete:
      summary: delete a capture
      operationId: deleteCapture
      tags:
        - capture
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: capture deleted

  /w/{workspace}/favorites/star:
    post:
      summary: star item
      operationId: star
      tags:
        - favorite
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: string
                favorite_kind:
                  type: string
                  enum: [flow, app, script, raw_app, asset]
      responses:
        "200":
          description: star item

  /w/{workspace}/favorites/unstar:
    post:
      summary: unstar item
      operationId: unstar
      tags:
        - favorite
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: string
                favorite_kind:
                  type: string
                  enum: [flow, app, script, raw_app, asset]
      responses:
        "200":
          description: unstar item

  /w/{workspace}/inputs/history:
    get:
      summary: List Inputs used in previously completed jobs
      operationId: getInputHistory
      tags:
        - input
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableId"
        - $ref: "#/components/parameters/RunnableTypeQuery"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/ArgsFilter"
        - name: include_preview
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: Input history for completed jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Input"

  /w/{workspace}/inputs/{jobOrInputId}/args:
    get:
      summary: Get args from history or saved input
      operationId: getArgsFromHistoryOrSavedInput
      tags:
        - input
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: jobOrInputId
          in: path
          required: true
          schema:
            type: string
        - name: input
          in: query
          schema:
            type: boolean
        - name: allow_large
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: args
          content:
            application/json:
              schema: {}

  /w/{workspace}/inputs/list:
    get:
      summary: List saved Inputs for a Runnable
      operationId: listInputs
      tags:
        - input
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableId"
        - $ref: "#/components/parameters/RunnableTypeQuery"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
      responses:
        "200":
          description: Saved Inputs for a Runnable
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Input"

  /w/{workspace}/inputs/create:
    post:
      summary: Create an Input for future use in a script or flow
      operationId: createInput
      tags:
        - input
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/RunnableId"
        - $ref: "#/components/parameters/RunnableTypeQuery"
      requestBody:
        description: Input
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateInput"
      responses:
        "201":
          description: Input created
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/inputs/update:
    post:
      summary: Update an Input
      operationId: updateInput
      tags:
        - input
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: UpdateInput
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateInput"
      responses:
        "201":
          description: Input updated
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/inputs/delete/{input}:
    post:
      summary: Delete a Saved Input
      operationId: deleteInput
      tags:
        - input
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/InputId"
      responses:
        "200":
          description: Input deleted
          content:
            text/plain:
              schema:
                type: string
                format: uuid

  /w/{workspace}/job_helpers/duckdb_connection_settings:
    post:
      summary:
        Converts an S3 resource to the set of instructions necessary to connect
        DuckDB to an S3 bucket
      operationId: duckdbConnectionSettings
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: S3 resource to connect to
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                s3_resource:
                  $ref: "#/components/schemas/S3Resource"
      responses:
        "200":
          description: Connection settings
          content:
            application/json:
              schema:
                type: object
                properties:
                  connection_settings_str:
                    type: string
  /w/{workspace}/job_helpers/v2/duckdb_connection_settings:
    post:
      summary:
        Converts an S3 resource to the set of instructions necessary to connect
        DuckDB to an S3 bucket
      operationId: duckdbConnectionSettingsV2
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description:
          S3 resource path to use to generate the connection settings. If empty,
          the S3 resource defined in the workspace settings will be used
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                s3_resource_path:
                  type: string
      responses:
        "200":
          description: Connection settings
          content:
            application/json:
              schema:
                type: object
                properties:
                  connection_settings_str:
                    type: string
                  azure_container_path:
                    type: string
                required:
                  - connection_settings_str

  /w/{workspace}/job_helpers/polars_connection_settings:
    post:
      summary:
        Converts an S3 resource to the set of arguments necessary to connect
        Polars to an S3 bucket
      operationId: polarsConnectionSettings
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: S3 resource to connect to
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                s3_resource:
                  $ref: "#/components/schemas/S3Resource"
      responses:
        "200":
          description: Connection settings
          content:
            application/json:
              schema:
                type: object
                properties:
                  endpoint_url:
                    type: string
                  key:
                    type: string
                  secret:
                    type: string
                  use_ssl:
                    type: boolean
                  cache_regions:
                    type: boolean
                  client_kwargs:
                    $ref: "#/components/schemas/PolarsClientKwargs"
                required:
                  - endpoint_url
                  - use_ssl
                  - cache_regions
                  - client_kwargs
  /w/{workspace}/job_helpers/v2/polars_connection_settings:
    post:
      summary:
        Converts an S3 resource to the set of arguments necessary to connect
        Polars to an S3 bucket
      operationId: polarsConnectionSettingsV2
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description:
          S3 resource path to use to generate the connection settings. If empty,
          the S3 resource defined in the workspace settings will be used
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                s3_resource_path:
                  type: string
      responses:
        "200":
          description: Connection settings
          content:
            application/json:
              schema:
                type: object
                properties:
                  s3fs_args:
                    type: object
                    properties:
                      endpoint_url:
                        type: string
                      key:
                        type: string
                      secret:
                        type: string
                      use_ssl:
                        type: boolean
                      cache_regions:
                        type: boolean
                      client_kwargs:
                        $ref: "#/components/schemas/PolarsClientKwargs"
                    required:
                      - endpoint_url
                      - use_ssl
                      - cache_regions
                      - client_kwargs
                  storage_options:
                    type: object
                    properties:
                      aws_endpoint_url:
                        type: string
                      aws_access_key_id:
                        type: string
                      aws_secret_access_key:
                        type: string
                      aws_region:
                        type: string
                      aws_allow_http:
                        type: string
                    required:
                      - aws_endpoint_url
                      - aws_region
                      - aws_allow_http
                required:
                  - s3fs_args
                  - storage_options
  /w/{workspace}/job_helpers/v2/s3_resource_info:
    post:
      summary: Returns the s3 resource associated to the provided path, or the
        workspace default S3 resource
      operationId: s3ResourceInfo
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description:
          S3 resource path to use. If empty, the S3 resource defined in the
          workspace settings will be used
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                s3_resource_path:
                  type: string
      responses:
        "200":
          description: Connection settings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/S3Resource"

  /w/{workspace}/job_helpers/test_connection:
    get:
      summary: Test connection to the workspace object storage
      operationId: datasetStorageTestConnection
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Connection settings
          content:
            application/json:
              schema: {}

  /w/{workspace}/job_helpers/storage_usage:
    get:
      summary: Get the storage usage of the workspace object storage, per configured storage. On Community Edition, also returns the workspace storage quota.
      operationId: getStorageUsage
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: refresh
          in: query
          description: recount usage by listing the storage instead of returning cached values
          schema:
            type: boolean
      responses:
        "200":
          description: Storage usage
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_bytes:
                    type: integer
                    format: int64
                  quota_bytes:
                    type: integer
                    format: int64
                    description: only present on Community Edition, where workspace storage is capped
                  storages:
                    type: array
                    items:
                      type: object
                      properties:
                        storage:
                          type: string
                        bytes:
                          type: integer
                          format: int64
                        computed_at:
                          type: string
                          format: date-time
                      required:
                        - storage
                        - bytes
                        - computed_at
                required:
                  - total_bytes
                  - storages

  /w/{workspace}/job_helpers/list_stored_files:
    get:
      summary: List the file keys available in a workspace object storage
      operationId: listStoredFiles
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: max_keys
          in: query
          required: true
          schema:
            type: integer
        - name: marker
          in: query
          schema:
            type: string
        - name: prefix
          in: query
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: List of file keys
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_marker:
                    type: string
                  windmill_large_files:
                    type: array
                    items:
                      $ref: "#/components/schemas/WindmillLargeFile"
                  restricted_access:
                    type: boolean
                required:
                  - windmill_large_files

  /w/{workspace}/job_helpers/load_file_metadata:
    get:
      summary: Load metadata of the file
      operationId: loadFileMetadata
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: FileMetadata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WindmillFileMetadata"

  /w/{workspace}/job_helpers/load_file_preview:
    get:
      summary: Load a preview of the file
      operationId: loadFilePreview
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: file_size_in_bytes
          in: query
          schema:
            type: integer
        - name: file_mime_type
          in: query
          schema:
            type: string
        - name: csv_separator
          in: query
          schema:
            type: string
        - name: csv_has_header
          in: query
          schema:
            type: boolean
        - name: read_bytes_from
          in: query
          schema:
            type: integer
        - name: read_bytes_length
          in: query
          schema:
            type: integer
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: FilePreview
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WindmillFilePreview"

  /w/{workspace}/job_helpers/list_git_repo_files:
    get:
      summary: List the file keys available in instance object storage with resource-based access control
      operationId: listGitRepoFiles
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: max_keys
          in: query
          required: true
          schema:
            type: integer
        - name: marker
          in: query
          schema:
            type: string
        - name: prefix
          in: query
          required: false
          schema:
            type: string
            description: Must follow format gitrepos/{workspace_id}/{resource_path}/...
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: List of file keys
          content:
            application/json:
              schema:
                type: object
                properties:
                  next_marker:
                    type: string
                  windmill_large_files:
                    type: array
                    items:
                      $ref: "#/components/schemas/WindmillLargeFile"
                  restricted_access:
                    type: boolean
                required:
                  - windmill_large_files

  /w/{workspace}/job_helpers/load_git_repo_file_preview:
    get:
      summary: Load a preview of a file from instance storage with resource-based access control
      operationId: loadGitRepoFilePreview
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
            description: Must follow format gitrepos/{workspace_id}/{resource_path}/...
        - name: file_size_in_bytes
          in: query
          schema:
            type: integer
        - name: file_mime_type
          in: query
          schema:
            type: string
        - name: csv_separator
          in: query
          schema:
            type: string
        - name: csv_has_header
          in: query
          schema:
            type: boolean
        - name: read_bytes_from
          in: query
          schema:
            type: integer
        - name: read_bytes_length
          in: query
          schema:
            type: integer
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: FilePreview
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WindmillFilePreview"

  /w/{workspace}/job_helpers/load_git_repo_file_metadata:
    get:
      summary: Load file metadata from instance storage with resource-based access control
      operationId: loadGitRepoFileMetadata
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
            description: Must follow format gitrepos/{workspace_id}/{resource_path}/...
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: FileMetadata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WindmillFileMetadata"

  /w/{workspace}/job_helpers/check_s3_folder_exists:
    get:
      summary: Check if S3 path exists and is a folder
      operationId: checkS3FolderExists
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          description: S3 file key to check (e.g., gitrepos/{workspace_id}/u/user/resource/{commit_hash})
          in: query
          required: true
          schema:
            type: string
        - name: marker_file
          description: |
            If provided, the folder is only considered to exist when this exact
            sentinel file is present under file_key. Lets callers distinguish a
            fully populated folder from a partial upload.
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: S3 folder existence check result
          content:
            application/json:
              schema:
                type: object
                properties:
                  exists:
                    type: boolean
                    description: Whether the path exists
                  is_folder:
                    type: boolean
                    description: Whether the path is a folder (true) or file (false)
                required:
                  - exists
                  - is_folder

  /w/{workspace}/job_helpers/load_parquet_preview/{path}:
    get:
      summary: Load a preview of a parquet file
      operationId: loadParquetPreview
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: offset
          in: query
          schema:
            type: number
        - name: limit
          in: query
          schema:
            type: number
        - name: sort_col
          in: query
          schema:
            type: string
        - name: sort_desc
          in: query
          schema:
            type: boolean
        - name: search_col
          in: query
          schema:
            type: string
        - name: search_term
          in: query
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Parquet Preview
          content:
            application/json: {}

  /w/{workspace}/job_helpers/load_table_count/{path}:
    get:
      summary: Load the table row count
      operationId: loadTableRowCount
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: search_col
          in: query
          schema:
            type: string
        - name: search_term
          in: query
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Table count
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: number

  /w/{workspace}/job_helpers/load_csv_preview/{path}:
    get:
      summary: Load a preview of a csv file
      operationId: loadCsvPreview
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/Path"
        - name: offset
          in: query
          schema:
            type: number
        - name: limit
          in: query
          schema:
            type: number
        - name: sort_col
          in: query
          schema:
            type: string
        - name: sort_desc
          in: query
          schema:
            type: boolean
        - name: search_col
          in: query
          schema:
            type: string
        - name: search_term
          in: query
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - name: csv_separator
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Csv Preview
          content:
            application/json: {}

  /w/{workspace}/job_helpers/delete_s3_file:
    delete:
      summary: Permanently delete file from S3
      operationId: deleteS3File
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Confirmation
          content:
            application/json:
              schema: {}

  /w/{workspace}/job_helpers/move_s3_file:
    get:
      summary: Move a S3 file from one path to the other within the same bucket
      operationId: moveS3File
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: src_file_key
          in: query
          required: true
          schema:
            type: string
        - name: dest_file_key
          in: query
          required: true
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Confirmation
          content:
            application/json:
              schema: {}

  /w/{workspace}/job_helpers/upload_s3_file:
    post:
      summary: Upload file to S3 bucket
      operationId: fileUpload
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: false
          schema:
            type: string
        - name: file_extension
          in: query
          required: false
          schema:
            type: string
        - name: s3_resource_path
          in: query
          required: false
          schema:
            type: string
        - name: resource_type
          in: query
          required: false
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - name: content_type
          in: query
          schema:
            type: string
        - name: content_disposition
          in: query
          schema:
            type: string
      requestBody:
        description: File content
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
      responses:
        "200":
          description: File upload status
          content:
            application/json:
              schema:
                type: object
                properties:
                  file_key:
                    type: string
                required:
                  - file_key

  /w/{workspace}/job_helpers/upload_git_repo_file_to_instance_storage:
    post:
      summary: Upload a file to the instance storage gitrepos section for viewing
      operationId: gitRepoViewerFileUpload
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: false
          schema:
            type: string
        - name: file_extension
          in: query
          required: false
          schema:
            type: string
        - name: s3_resource_path
          in: query
          required: false
          schema:
            type: string
        - name: resource_type
          in: query
          required: false
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
        - name: content_type
          in: query
          schema:
            type: string
        - name: content_disposition
          in: query
          schema:
            type: string
      requestBody:
        description: File content
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
      responses:
        "200":
          description: File upload status
          content:
            application/json:
              schema:
                type: object
                properties:
                  file_key:
                    type: string
                required:
                  - file_key

  /w/{workspace}/job_helpers/download_s3_file:
    get:
      summary: Download file from S3 bucket
      operationId: fileDownload
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: s3_resource_path
          in: query
          required: false
          schema:
            type: string
        - name: resource_type
          in: query
          required: false
          schema:
            type: string
        - name: storage
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Chunk of the downloaded file
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary

  /w/{workspace}/job_helpers/download_s3_parquet_file_as_csv:
    get:
      summary: Download file to S3 bucket
      operationId: fileDownloadParquetAsCsv
      tags:
        - helpers
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: file_key
          in: query
          required: true
          schema:
            type: string
        - name: s3_resource_path
          in: query
          required: false
          schema:
            type: string
        - name: resource_type
          in: query
          required: false
          schema:
            type: string
      responses:
        "200":
          description: The downloaded file
          content:
            text/csv:
              schema:
                type: string

  /w/{workspace}/job_metrics/get/{id}:
    post:
      summary: get job metrics
      operationId: getJobMetrics
      tags:
        - metrics
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      requestBody:
        description: parameters for statistics retrieval
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                timeseries_max_datapoints:
                  type: integer
                from_timestamp:
                  type: string
                  format: date-time
                to_timestamp:
                  type: string
                  format: date-time

      responses:
        "200":
          description: job details
          content:
            application/json:
              schema:
                type: object
                properties:
                  metrics_metadata:
                    type: array
                    items:
                      $ref: "#/components/schemas/MetricMetadata"
                  scalar_metrics:
                    type: array
                    items:
                      $ref: "#/components/schemas/ScalarMetric"
                  timeseries_metrics:
                    type: array
                    items:
                      $ref: "#/components/schemas/TimeseriesMetric"

  /w/{workspace}/job_metrics/set_progress/{id}:
    post:
      summary: set job metrics
      operationId: setJobProgress
      tags:
        - metrics
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      requestBody:
        description: parameters for statistics retrieval
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                percent:
                  type: integer
                flow_job_id:
                  type: string
                  format: uuid

      responses:
        "200":
          description: Job progress updated
          content:
            application/json:
              schema: {}

  /w/{workspace}/job_metrics/get_progress/{id}:
    get:
      summary: get job progress
      operationId: getJobProgress
      tags:
        - metrics
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: job progress between 0 and 99
          content:
            application/json:
              schema:
                type: integer
  /service_logs/list_files:
    get:
      summary: list log files ordered by timestamp
      operationId: listLogFiles
      tags:
        - service_logs
      parameters:
        - $ref: "#/components/parameters/Before"
        - $ref: "#/components/parameters/After"
        - name: with_error
          in: query
          required: false
          schema:
            type: boolean
      responses:
        "200":
          description: time
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    hostname:
                      type: string
                    mode:
                      type: string
                    worker_group:
                      type: string
                    log_ts:
                      type: string
                      format: date-time
                    file_path:
                      type: string
                    ok_lines:
                      type: integer
                    err_lines:
                      type: integer
                    json_fmt:
                      type: boolean
                  required:
                    - hostname
                    - mode
                    - log_ts
                    - file_path
                    - json_fmt

  /service_logs/get_log_file/{path}:
    get:
      summary: get log file by path
      operationId: getLogFile
      tags:
        - service_logs
      parameters:
        - $ref: "#/components/parameters/Path"
      responses:
        "200":
          description: log stream
          content:
            text/plain:
              schema:
                type: string
  /concurrency_groups/list:
    get:
      summary: List all concurrency groups
      operationId: listConcurrencyGroups
      tags:
        - concurrencyGroups
      responses:
        "200":
          description: all concurrency groups
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ConcurrencyGroup"
  /concurrency_groups/prune/{concurrency_id}:
    delete:
      summary: Delete concurrency group
      operationId: deleteConcurrencyGroup
      tags:
        - concurrencyGroups
      parameters:
        - $ref: "#/components/parameters/ConcurrencyId"
      responses:
        "200":
          description: concurrency group removed
          content:
            application/json:
              schema:
                type: object
                properties: {}
  /concurrency_groups/{id}/key:
    get:
      summary: Get the concurrency key for a job that has concurrency limits enabled
      operationId: getConcurrencyKey
      tags:
        - concurrencyGroups
      parameters:
        - $ref: "#/components/parameters/JobId"
      responses:
        "200":
          description: concurrency key for given job
          content:
            application/json:
              schema:
                type: string
  /w/{workspace}/concurrency_groups/list_jobs:
    get:
      summary: Get intervals of job runtime concurrency
      operationId: listExtendedJobs
      tags:
        - concurrencyGroups
        - job
      parameters:
        - name: concurrency_key
          in: query
          required: false
          schema:
            type: string
        - name: row_limit
          in: query
          required: false
          schema:
            type: number
        - $ref: "#/components/parameters/WorkspaceId"
        - $ref: "#/components/parameters/CreatedBy"
        - $ref: "#/components/parameters/Label"
        - $ref: "#/components/parameters/ParentJob"
        - $ref: "#/components/parameters/ScriptExactPath"
        - $ref: "#/components/parameters/ScriptStartPath"
        - $ref: "#/components/parameters/SchedulePath"
        - $ref: "#/components/parameters/ScriptExactHash"
        - $ref: "#/components/parameters/StartedBefore"
        - $ref: "#/components/parameters/StartedAfter"
        - $ref: "#/components/parameters/Running"
        - $ref: "#/components/parameters/ScheduledForBeforeNow"
        - $ref: "#/components/parameters/CompletedBefore"
        - $ref: "#/components/parameters/CompletedAfter"
        - $ref: "#/components/parameters/CreatedBeforeQueue"
        - $ref: "#/components/parameters/CreatedAfterQueue"
        - $ref: "#/components/parameters/JobKinds"
        - $ref: "#/components/parameters/ArgsFilter"
        - $ref: "#/components/parameters/Tag"
        - $ref: "#/components/parameters/ResultFilter"
        - $ref: "#/components/parameters/AllowWildcards"
        - $ref: "#/components/parameters/Page"
        - $ref: "#/components/parameters/PerPage"
        - $ref: "#/components/parameters/JobTriggerKind"
        - name: is_skipped
          description: is the job skipped
          in: query
          schema:
            type: boolean
        - name: is_flow_step
          description: is the job a flow step
          in: query
          schema:
            type: boolean
        - name: has_null_parent
          description: has null parent
          in: query
          schema:
            type: boolean
        - name: success
          description: filter on successful jobs
          in: query
          schema:
            type: boolean
        - name: status
          description: filter on the exact completed job status. Unlike `success=true` (which also matches `skipped`), `status=success` matches only `success`.
          in: query
          schema:
            type: string
            enum:
              - success
              - failure
              - canceled
              - skipped
        - name: all_workspaces
          description: get jobs from all workspaces (only valid if request come from the `admins` workspace)
          in: query
          schema:
            type: boolean
        - name: is_not_schedule
          description: is not a scheduled job
          in: query
          schema:
            type: boolean
      responses:
        "200":
          description: time
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExtendedJobs"

  /srch/w/{workspace}/index/search/job:
    get:
      summary: Search through jobs with a string query
      operationId: searchJobsIndex
      tags:
        - indexSearch
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: search_query
          in: query
          required: true
          schema:
            type: string
        - name: pagination_offset
          in: query
          required: false
          schema:
            type: integer
      responses:
        "200":
          description: search results
          content:
            application/json:
              schema:
                type: object
                properties:
                  query_parse_errors:
                    description: a list of the terms that couldn't be parsed (and thus ignored)
                    type: array
                    items:
                      type: string
                  hits:
                    description: the jobs that matched the query
                    type: array
                    items:
                      $ref: "#/components/schemas/JobSearchHit"
                  hit_count:
                    description: how many jobs matched in total
                    type: number
                  index_metadata:
                    description: Metadata about the index current state
                    type: object
                    properties:
                      indexed_until:
                        description: Datetime of the most recently indexed job
                        type: string
                        format: date-time
                      lost_lock_ownership:
                        description: Is the current indexer service being replaced
                        type: boolean
                      max_index_time_window_secs:
                        description: Maximum time window in seconds for indexing
                        type: number

  /srch/index/search/service_logs:
    get:
      summary: Search through service logs with a string query
      operationId: searchLogsIndex
      tags:
        - indexSearch
      parameters:
        - name: search_query
          in: query
          required: true
          schema:
            type: string
        - name: mode
          in: query
          required: true
          schema:
            type: string
        - name: worker_group
          in: query
          required: false
          schema:
            type: string
        - name: hostname
          in: query
          required: true
          schema:
            type: string
        - name: min_ts
          in: query
          required: false
          schema:
            type: string
            format: date-time
        - name: max_ts
          in: query
          required: false
          schema:
            type: string
            format: date-time
      responses:
        "200":
          description: search results
          content:
            application/json:
              schema:
                type: object
                properties:
                  query_parse_errors:
                    description: a list of the terms that couldn't be parsed (and thus ignored)
                    type: array
                    items:
                      type: string
                  hits:
                    description: log files that matched the query
                    type: array
                    items:
                      $ref: "#/components/schemas/LogSearchHit"

  /srch/index/search/count_service_logs:
    get:
      summary: Search and count the log line hits on every provided host
      operationId: countSearchLogsIndex
      tags:
        - indexSearch
      parameters:
        - name: search_query
          in: query
          required: true
          schema:
            type: string
        - name: min_ts
          in: query
          required: false
          schema:
            type: string
            format: date-time
        - name: max_ts
          in: query
          required: false
          schema:
            type: string
            format: date-time
      responses:
        "200":
          description: search results
          content:
            application/json:
              schema:
                type: object
                properties:
                  query_parse_errors:
                    description: a list of the terms that couldn't be parsed (and thus ignored)
                    type: array
                    items:
                      type: string
                  count_per_host:
                    description: count of log lines that matched the query per hostname
                    type: object

  /srch/index/storage/disk:
    get:
      summary: Get index disk storage sizes from the indexer.
      operationId: getIndexDiskStorageSizes
      tags:
        - indexSearch
      responses:
        "200":
          description: disk storage sizes for each index
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_index_disk_size_bytes:
                    type: integer
                    nullable: true
                  log_index_disk_size_bytes:
                    type: integer
                    nullable: true

  /indexer/delete/{idx_name}:
    delete:
      summary: Clear an index and restart the indexer.
      operationId: clearIndex
      tags:
        - indexSearch
      parameters:
        - name: idx_name
          in: path
          required: true
          schema:
            type: string
            enum:
              - JobIndex
              - ServiceLogIndex
      responses:
        "200":
          description: idx to be deleted and indexer restarting
          content:
            text/plain:
              schema:
                type: string

  /indexer/storage:
    get:
      summary: Get index storage sizes (disk and S3).
      operationId: getIndexStorageSizes
      tags:
        - indexSearch
      responses:
        "200":
          description: storage sizes for each index
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_index:
                    type: object
                    properties:
                      disk_size_bytes:
                        type: integer
                        nullable: true
                      s3_size_bytes:
                        type: integer
                        nullable: true
                  service_log_index:
                    type: object
                    properties:
                      disk_size_bytes:
                        type: integer
                        nullable: true
                      s3_size_bytes:
                        type: integer
                        nullable: true

  /indexer/status:
    get:
      summary: Get indexer status including liveness and storage sizes.
      operationId: getIndexerStatus
      tags:
        - indexSearch
      responses:
        "200":
          description: indexer status for each index
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_indexer:
                    type: object
                    properties:
                      is_alive:
                        type: boolean
                      state:
                        type: string
                        enum:
                          - running
                          - stale
                          - never_started
                      last_locked_at:
                        type: string
                        format: date-time
                        nullable: true
                      owner:
                        type: string
                        nullable: true
                      storage:
                        type: object
                        properties:
                          disk_size_bytes:
                            type: integer
                            nullable: true
                          s3_size_bytes:
                            type: integer
                            nullable: true
                  log_indexer:
                    type: object
                    properties:
                      is_alive:
                        type: boolean
                      state:
                        type: string
                        enum:
                          - running
                          - stale
                          - never_started
                      last_locked_at:
                        type: string
                        format: date-time
                        nullable: true
                      owner:
                        type: string
                        nullable: true
                      storage:
                        type: object
                        properties:
                          disk_size_bytes:
                            type: integer
                            nullable: true
                          s3_size_bytes:
                            type: integer
                            nullable: true

  /w/{workspace}/assets/list:
    get:
      summary: List all assets in the workspace with cursor pagination
      operationId: listAssets
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: per_page
          in: query
          description: Number of items per page (max 1000, default 50)
          schema:
            type: integer
            default: 50
            minimum: 1
            maximum: 1000
        - name: cursor_created_at
          in: query
          description: Cursor timestamp for pagination (created_at of last item from previous page)
          schema:
            type: string
            format: date-time
        - name: cursor_id
          in: query
          description: Cursor ID for pagination (id of last item from previous page)
          schema:
            type: integer
            format: int64
        - name: asset_path
          in: query
          description: Filter by asset path (case-insensitive partial match)
          schema:
            type: string
        - name: usage_path
          in: query
          description: Filter by usage path (case-insensitive partial match)
          schema:
            type: string
        - name: asset_kinds
          in: query
          description: Filter by asset kinds (multiple values allowed)
          schema:
            type: string
        - name: path
          in: query
          description: exact path match filter
          schema:
            type: string
        - name: columns
          in: query
          description: JSONB subset match filter for columns using base64 encoded JSON
          schema:
            type: string
        - name: broad_filter
          description: broad search across multiple fields (case-insensitive substring match)
          in: query
          schema:
            type: string
      responses:
        "200":
          description: paginated assets in the workspace
          content:
            application/json:
              schema:
                type: object
                required: [assets]
                properties:
                  assets:
                    type: array
                    items:
                      type: object
                      required: [path, kind, usages]
                      properties:
                        path:
                          type: string
                        kind:
                          $ref: "#/components/schemas/AssetKind"
                        usages:
                          type: array
                          items:
                            type: object
                            required: [path, kind]
                            properties:
                              path:
                                type: string
                              kind:
                                $ref: "#/components/schemas/AssetUsageKind"
                              access_type:
                                $ref: "#/components/schemas/AssetUsageAccessType"
                              columns:
                                type: object
                                description: The columns used (for tables)
                                additionalProperties:
                                  $ref: "#/components/schemas/AssetUsageAccessType"
                              created_at:
                                type: string
                                format: date-time
                                description: When the asset was detected
                              metadata:
                                type: object
                                properties:
                                  runnable_path:
                                    type: string
                                    description: The path of the script/flow that was run (only present when kind is 'job')
                                  job_kind:
                                    type: string
                                    description: The kind of job (script, flow, preview, etc.) (only present when kind is 'job')
                        metadata:
                          type: object
                          properties:
                            resource_type:
                              type: string
                              description: The type of the resource (only present when kind is 'resource')
                  next_cursor:
                    type: object
                    description: Cursor for the next page (null if no more pages)
                    nullable: true
                    properties:
                      created_at:
                        type: string
                        format: date-time
                        description: Timestamp to use for next page
                      id:
                        type: integer
                        format: int64
                        description: ID to use for next page

  /w/{workspace}/assets/list_by_usages:
    post:
      summary: List all assets used by given usages paths
      operationId: listAssetsByUsage
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        description: list assets by usages
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [usages]
              properties:
                usages:
                  type: array
                  items:
                    type: object
                    required: [path, kind]
                    properties:
                      path:
                        type: string
                      kind:
                        $ref: "#/components/schemas/AssetUsageKind"
      responses:
        "200":
          description: all assets used by the given usage paths, in the same order
          content:
            application/json:
              schema:
                type: array
                items:
                  type: array
                  items:
                    type: object
                    required: [path, kind]
                    properties:
                      path:
                        type: string
                      kind:
                        $ref: "#/components/schemas/AssetKind"
                      access_type:
                        $ref: "#/components/schemas/AssetUsageAccessType"

  /w/{workspace}/assets/list_favorites:
    get:
      summary: List all favorite assets for the authenticated user
      operationId: listFavoriteAssets
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of favorite assets
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required: [path]
                  properties:
                    path:
                      type: string
                      description: The asset path

  /w/{workspace}/assets/graph:
    get:
      summary: Get the workspace-wide asset <-> runnable graph
      operationId: getAssetsGraph
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: asset_kinds
          in: query
          description: Filter by asset kinds (comma-separated list)
          schema:
            type: string
        - name: folder
          in: query
          description: Scope the graph to runnables in a single folder
          schema:
            type: string
      responses:
        "200":
          description: asset graph nodes, lineage edges and trigger edges
          content:
            application/json:
              schema:
                type: object
                required: [assets, runnables, edges, triggers]
                properties:
                  assets:
                    type: array
                    items:
                      type: object
                      required: [kind, path]
                      properties:
                        kind:
                          $ref: "#/components/schemas/AssetKind"
                        path:
                          type: string
                        fork_materialization:
                          type: string
                          enum: [fork, deferred]
                          description: Fork workspaces only — 'fork' when this ducklake asset was materialized in the fork itself, 'deferred' when reads fall back to the parent workspace's current table via a defer view. Omitted otherwise.
                  runnables:
                    type: array
                    items:
                      type: object
                      required: [path, usage_kind]
                      properties:
                        path:
                          type: string
                        usage_kind:
                          $ref: "#/components/schemas/AssetUsageKind"
                        in_pipeline:
                          type: boolean
                          description: True iff the script is a pipeline member (deployed with `// pipeline`). Omitted when false.
                        macros:
                          type: array
                          description: Macros this script provides to the workspace registry (deployed `// macros` library). Omitted when empty.
                          items:
                            type: object
                            required: [name, params, is_table]
                            properties:
                              name:
                                type: string
                              params:
                                type: string
                                description: verbatim parameter list
                              is_table:
                                type: boolean
                  edges:
                    type: array
                    items:
                      type: object
                      required:
                        [runnable_path, runnable_kind, asset_kind, asset_path]
                      properties:
                        runnable_path:
                          type: string
                        runnable_kind:
                          $ref: "#/components/schemas/AssetUsageKind"
                        asset_kind:
                          $ref: "#/components/schemas/AssetKind"
                        asset_path:
                          type: string
                        access_type:
                          $ref: "#/components/schemas/AssetUsageAccessType"
                  triggers:
                    type: array
                    items:
                      oneOf:
                        - type: object
                          description: Asset trigger edge (`// on <asset>`)
                          required:
                            [
                              trigger_kind,
                              asset_kind,
                              asset_path,
                              runnable_kind,
                              runnable_path,
                            ]
                          properties:
                            trigger_kind:
                              type: string
                              enum: [asset]
                            asset_kind:
                              $ref: "#/components/schemas/AssetKind"
                            asset_path:
                              type: string
                            runnable_kind:
                              $ref: "#/components/schemas/AssetUsageKind"
                            runnable_path:
                              type: string
                        - type: object
                          description: Native trigger edge (schedule, email, kafka, ...). `path` is the trigger row's path.
                          required:
                            [trigger_kind, path, runnable_kind, runnable_path]
                          properties:
                            trigger_kind:
                              type: string
                              enum:
                                - schedule
                                - email
                                - kafka
                                - mqtt
                                - nats
                                - postgres
                                - sqs
                                - gcp
                            path:
                              type: string
                            runnable_kind:
                              $ref: "#/components/schemas/AssetUsageKind"
                            runnable_path:
                              type: string
                  macro_edges:
                    type: array
                    description: Macro-library → consumer edges (deploy-recorded call detection plus `// use`). Omitted when empty.
                    items:
                      type: object
                      required: [lib_path, consumer_path, macro_names, via_use]
                      properties:
                        lib_path:
                          type: string
                        consumer_path:
                          type: string
                        macro_names:
                          type: array
                          items:
                            type: string
                        via_use:
                          type: boolean
                  test_edges:
                    type: array
                    description: >-
                      Ordering-only "must-run-after" edges — a `// data_test relationships`
                      (or custom test reading a pipeline asset) requires the referenced
                      asset's producer to run before the tested script. Not a data-consumption
                      edge; fed into the cascade topo-sort so cold runs order correctly.
                      Omitted when empty.
                    items:
                      type: object
                      required:
                        [
                          producer_kind,
                          producer_path,
                          runnable_kind,
                          runnable_path,
                          asset_kind,
                          asset_path,
                        ]
                      properties:
                        producer_kind:
                          $ref: "#/components/schemas/AssetUsageKind"
                        producer_path:
                          type: string
                        runnable_kind:
                          $ref: "#/components/schemas/AssetUsageKind"
                        runnable_path:
                          type: string
                        asset_kind:
                          $ref: "#/components/schemas/AssetKind"
                        asset_path:
                          type: string

  /w/{workspace}/assets/macros:
    get:
      summary: List every workspace DuckDB macro (deployed `// macros` libraries)
      operationId: listWorkspaceMacros
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: all registry macros, ordered by provider then name
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required: [name, params, body, is_table, provider_path]
                  properties:
                    name:
                      type: string
                    params:
                      type: string
                      description: verbatim parameter list
                    body:
                      type: string
                      description: verbatim body after AS [TABLE]
                    is_table:
                      type: boolean
                    provider_path:
                      type: string
                      description: path of the `// macros` library script

  /w/{workspace}/assets/pipelines:
    get:
      summary: List folders that contain at least one pipeline-member script
      operationId: listPipelineFolders
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: folders containing pipeline scripts, with their script counts
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  required: [folder, script_count]
                  properties:
                    folder:
                      type: string
                      description: The folder name (without the `f/` prefix)
                    script_count:
                      type: integer
                      format: int64
                      description: Number of pipeline-member scripts in the folder

  /w/{workspace}/assets/partitions:
    get:
      summary: List materialized partitions for a ducklake asset
      operationId: listAssetPartitions
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: path
          in: query
          required: true
          description: The materialized ducklake asset path (`<ducklake>/<table>`)
          schema:
            type: string
      responses:
        "200":
          description: per-partition materialization status
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/MaterializedPartition"

  /w/{workspace}/assets/partitions_in_range:
    get:
      summary: List expected partitions of a ducklake asset in a date range with their materialization status (enterprise)
      operationId: listAssetPartitionsInRange
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: path
          in: query
          required: true
          description: The materialized ducklake asset path (`<ducklake>/<table>`)
          schema:
            type: string
        - name: from
          in: query
          required: true
          description: Inclusive range start (YYYY-MM-DD), local to the producer's partition tz
          schema:
            type: string
            format: date
        - name: to
          in: query
          required: true
          description: Inclusive range end (YYYY-MM-DD), local to the producer's partition tz
          schema:
            type: string
            format: date
      responses:
        "200":
          description: expected partitions in range with per-slice status — the missing/failed subset is the backfill worklist
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PartitionsInRange"

  /w/{workspace}/assets/asset_schemas:
    get:
      summary: List captured output-schema versions for a ducklake asset
      operationId: listAssetSchemas
      tags:
        - asset
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: path
          in: query
          required: true
          description: The materialized ducklake asset path (`<ducklake>/<table>`)
          schema:
            type: string
      responses:
        "200":
          description: captured schema versions, newest first
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AssetSchemaVersion"

  /w/{workspace}/volumes/list:
    get:
      summary: List all volumes in the workspace
      operationId: listVolumes
      tags:
        - volume
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of volumes
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Volume"

  /w/{workspace}/volumes/storage:
    get:
      summary: Get the volume storage name (secondary storage) or null for primary
      operationId: getVolumeStorage
      tags:
        - volume
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: volume storage name or null
          content:
            application/json:
              schema:
                type: string
                nullable: true

  /w/{workspace}/volumes/create:
    post:
      summary: Create a new volume
      operationId: createVolume
      tags:
        - volume
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              properties:
                name:
                  type: string
      responses:
        "200":
          description: volume created
          content:
            text/plain:
              schema:
                type: string

  /w/{workspace}/volumes/delete/{name}:
    delete:
      summary: Delete a volume (admin only)
      operationId: deleteVolume
      tags:
        - volume
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
        - name: name
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: volume deleted
          content:
            text/plain:
              schema:
                type: string

  /mcp/w/{workspace}/list_tools:
    get:
      summary: list available MCP tools
      operationId: listMcpTools
      tags:
        - mcp
      parameters:
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: list of MCP tools available for the workspace
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/EndpointTool"

  /mcp/oauth/discover:
    post:
      summary: discover MCP server OAuth metadata
      operationId: discoverMcpOAuth
      tags:
        - mcp_oauth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - mcp_server_url
              properties:
                mcp_server_url:
                  type: string
                  description: URL of the MCP server to discover OAuth metadata from
      responses:
        "200":
          description: OAuth metadata from MCP server
          content:
            application/json:
              schema:
                type: object
                properties:
                  scopes_supported:
                    type: array
                    items:
                      type: string
                  authorization_endpoint:
                    type: string
                  token_endpoint:
                    type: string
                  registration_endpoint:
                    type: string
                  supports_dynamic_registration:
                    type: boolean

  /mcp/oauth/start:
    get:
      summary: start MCP OAuth popup flow
      description: Opens in a popup, discovers OAuth metadata, registers client, and redirects to OAuth provider
      operationId: startMcpOAuthPopup
      tags:
        - mcp_oauth
      parameters:
        - name: mcp_server_url
          in: query
          required: true
          schema:
            type: string
          description: URL of the MCP server to connect to
        - name: scopes
          in: query
          required: false
          schema:
            type: string
          description: Comma-separated list of OAuth scopes to request
      responses:
        "302":
          description: Redirect to OAuth provider authorization URL

  /mcp/oauth/callback:
    get:
      security: []
      summary: MCP OAuth callback
      description: Handles OAuth callback, exchanges code for tokens, returns HTML that posts message to opener
      operationId: mcpOAuthCallback
      tags:
        - mcp_oauth
      parameters:
        - name: code
          in: query
          required: true
          schema:
            type: string
          description: OAuth authorization code
        - name: state
          in: query
          required: true
          schema:
            type: string
          description: CSRF state token
      responses:
        "200":
          description: HTML page with JavaScript that posts tokens to opener window and closes
          content:
            text/html:
              schema:
                type: string

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
    cookieAuth:
      type: apiKey
      in: cookie
      name: token

  parameters:
    GetDraft:
      name: get_draft
      in: query
      required: false
      description: When true, overlay the authed user's draft (if any) onto the deployed payload.
      schema:
        type: boolean
    IncludeDraftOnly:
      name: include_draft_only
      in: query
      required: false
      description: |
        When true, append per-user draft rows whose path has no
        deployed counterpart. Synthesized rows carry `draft_only: true`
        so the home page can render a "Draft" badge. Gated to
        non-operators + page 0 + no narrowing filters on the backend so
        picker callers stay deployed-only and pagination stays clean.
      schema:
        type: boolean
    Id:
      name: id
      in: path
      required: true
      schema:
        type: string
    Key:
      name: key
      in: path
      required: true
      schema:
        type: string
    WorkspaceId:
      name: workspace
      in: path
      required: true
      schema:
        type: string
    PublicationName:
      name: publication
      in: path
      required: true
      description: The name of the publication
      schema:
        type: string
    VersionId:
      name: version
      in: path
      required: true
      schema:
        type: number
    Token:
      name: token
      in: path
      required: true
      schema:
        type: string
    AccountId:
      name: id
      in: path
      required: true
      schema:
        type: integer
    ClientName:
      name: client_name
      in: path
      required: true
      schema:
        type: string
    ScriptPath:
      name: path
      in: path
      required: true
      schema:
        type: string
    ScriptHash:
      name: hash
      in: path
      required: true
      schema:
        type: string
    JobId:
      name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    Path:
      name: path
      in: path
      required: true
      schema:
        type: string
    S3Sig:
      name: sig
      in: query
      description: HMAC signature of a presigned S3 object (bypasses the app provenance gate)
      schema:
        type: string
    S3Exp:
      name: exp
      in: query
      description: Expiry timestamp of a presigned S3 object signature
      schema:
        type: string
    CustomPath:
      name: custom_path
      in: path
      required: true
      schema:
        type: string
    PathId:
      name: id
      in: path
      required: true
      schema:
        type: integer
    PathVersion:
      name: version
      in: path
      required: true
      schema:
        type: integer
    Name:
      name: name
      in: path
      required: true
      schema:
        type: string
    Page:
      name: page
      description: which page to return (start at 1, default 1)
      in: query
      schema:
        type: integer
    PerPage:
      name: per_page
      description: number of items to return for a given page (default 30, max 100)
      in: query
      schema:
        type: integer
    JobTriggerKind:
      name: trigger_kind
      description: "filter by trigger kind. Supports comma-separated list (e.g. 'schedule,webhook') and negation by prefixing all values with '!' (e.g. '!schedule,!webhook')"
      in: query
      x-go-name: JobTriggerKindParam
      schema:
        type: string
    OrderDesc:
      name: order_desc
      description: order by desc order (default true)
      in: query
      schema:
        type: boolean
    CreatedBy:
      name: created_by
      description: "filter by exact matching user creator. Supports comma-separated list (e.g. 'alice,bob') and negation by prefixing all values with '!' (e.g. '!alice,!bob')"
      in: query
      schema:
        type: string
    Label:
      name: label
      description: "filter by exact matching job label. Supports comma-separated list (e.g. 'deploy,release') and negation by prefixing all values with '!' (e.g. '!deploy,!release')"
      in: query
      schema:
        type: string
    Worker:
      name: worker
      description: "filter by worker this job ran on. Supports comma-separated list (e.g. 'worker-1,worker-2') and negation by prefixing all values with '!' (e.g. '!worker-1,!worker-2')"
      in: query
      schema:
        type: string
    ParentJob:
      name: parent_job
      description:
        The parent job that is at the origin and responsible for the execution
        of this script if any
      in: query
      schema:
        type: string
        format: uuid
    WorkerTag:
      name: tag
      description: Override the tag to use
      in: query
      schema:
        type: string
    CacheTtl:
      name: cache_ttl
      description: Override the cache time to live (in seconds). Can not be used to disable caching, only override with a new cache ttl
      in: query
      schema:
        type: string
    NewJobId:
      name: job_id
      description:
        The job id to assign to the created job. if missing, job is chosen
        randomly using the ULID scheme. If a job id already exists in the queue
        or as a completed job, the request to create one will fail (Bad Request)
      in: query
      schema:
        type: string
        format: uuid
    IncludeHeader:
      name: include_header
      description: |
        List of headers's keys (separated with ',') whove value are added to the args
        Header's key lowercased and '-'' replaced to '_' such that 'Content-Type' becomes the 'content_type' arg key
      in: query
      schema:
        type: string
    QueueLimit:
      name: queue_limit
      description: |
        The maximum size of the queue for which the request would get rejected if that job would push it above that limit
      in: query
      schema:
        type: string
    SkipPreprocessor:
      name: skip_preprocessor
      description: skip the preprocessor
      in: query
      schema:
        type: boolean
    Payload:
      name: payload
      description: |
        The base64 encoded payload that has been encoded as a JSON. e.g how to encode such payload encodeURIComponent
        `encodeURIComponent(btoa(JSON.stringify({a: 2})))`
      in: query
      schema:
        type: string
    ScriptStartPath:
      name: script_path_start
      description: "filter by script path prefix. Supports comma-separated list (e.g. 'f/folder1,f/folder2') and negation by prefixing all values with '!' (e.g. '!f/folder1,!f/folder2')"
      in: query
      schema:
        type: string
    SchedulePath:
      name: schedule_path
      description: mask to filter by schedule path
      in: query
      schema:
        type: string
    TriggerPath:
      name: trigger_path
      description: "filter by trigger path. Supports comma-separated list (e.g. 'f/trigger1,f/trigger2') and negation by prefixing all values with '!' (e.g. '!f/trigger1,!f/trigger2')"
      in: query
      schema:
        type: string
    ScriptExactPath:
      name: script_path_exact
      description: "filter by exact matching script path. Supports comma-separated list (e.g. 'f/script1,f/script2') and negation by prefixing all values with '!' (e.g. '!f/script1,!f/script2')"
      in: query
      schema:
        type: string
    ScriptExactHash:
      name: script_hash
      description: mask to filter exact matching path
      in: query
      schema:
        type: string
    CreatedBefore:
      name: created_before
      description: filter on created before (inclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time
    CreatedAfter:
      name: created_after
      description: filter on created after (exclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time
    StartedBefore:
      name: started_before
      description: filter on started before (inclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time
    StartedAfter:
      name: started_after
      description: filter on started after (exclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time
    Before:
      name: before
      description: filter on started before (inclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time

    CompletedBefore:
      name: completed_before
      description: filter on started before (inclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time
    CompletedAfter:
      name: completed_after
      description: filter on started after (exclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time

    CreatedAfterQueue:
      name: created_after_queue
      description: filter on jobs created after X for jobs in the queue only
      in: query
      schema:
        type: string
        format: date-time

    CreatedBeforeQueue:
      name: created_before_queue
      description: filter on jobs created before X for jobs in the queue only
      in: query
      schema:
        type: string
        format: date-time

    Success:
      name: success
      description: filter on successful jobs
      in: query
      schema:
        type: boolean
    ScheduledForBeforeNow:
      name: scheduled_for_before_now
      description: filter on jobs scheduled_for before now (hence waitinf for a worker)
      in: query
      schema:
        type: boolean
    Suspended:
      name: suspended
      description: filter on suspended jobs
      in: query
      schema:
        type: boolean
    Running:
      name: running
      description: filter on running jobs
      in: query
      schema:
        type: boolean
    AllowWildcards:
      name: allow_wildcards
      description: allow wildcards (*) in the filter of label, tag, worker
      in: query
      schema:
        type: boolean
    ArgsFilter:
      name: args
      description: filter on jobs containing those args as a json subset (@> in postgres)
      in: query
      schema:
        type: string
    Tag:
      name: tag
      description: "filter by tag/worker group. Supports comma-separated list (e.g. 'gpu,highmem') and negation by prefixing all values with '!' (e.g. '!gpu,!highmem')"
      in: query
      schema:
        type: string
    ResultFilter:
      name: result
      description: filter on jobs containing those result as a json subset (@> in postgres)
      in: query
      schema:
        type: string
    After:
      name: after
      description: filter on created after (exclusive) timestamp
      in: query
      schema:
        type: string
        format: date-time
    Username:
      name: username
      description: filter on exact username of user
      in: query
      schema:
        type: string
    Operation:
      name: operation
      description: filter on exact or prefix name of operation
      in: query
      schema:
        type: string
    ResourceName:
      name: resource
      description: filter on exact or prefix name of resource
      in: query
      schema:
        type: string
    ActionKind:
      name: action_kind
      description: filter on type of operation
      in: query
      schema:
        type: string
        enum: [Create, Update, Delete, Execute]
    JobKinds:
      name: job_kinds
      description: "filter by job kind. Supports comma-separated list of values ('preview', 'script', 'dependencies', 'flow') and negation by prefixing all values with '!' (e.g. '!preview,!dependencies')"
      in: query
      schema:
        type: string
      # correct type is below but explode not supported by our codegen
      #   type: array
      #   items:
      #     type: string
      #     enum: ["preview", "script", "dependencies"]
      # explode: false
    RunnableId:
      name: runnable_id
      in: query
      schema:
        type: string
    RunnableTypeQuery:
      name: runnable_type
      in: query
      schema:
        $ref: "#/components/schemas/RunnableType"
    InputId:
      name: input
      in: path
      required: true
      schema:
        type: string
    GetStarted:
      name: get_started
      in: query
      schema:
        type: boolean
    ConcurrencyId:
      name: concurrency_id
      in: path
      required: true
      schema:
        type: string
    RunnableKind:
      name: runnable_kind
      in: path
      required: true
      schema:
        type: string
        enum: [script, flow]

  schemas:
    # NOTE: Not so many generators and validators support this format:
    # $ref: "../../openflow.openapi.yaml#/components/schemas"
    # This is why it is better to inline each of schemas for better compat
    UserDraftOverlay:
      type: object
      description: |
        Overlay fields added to every "get by path" response that accepts
        the `get_draft` query parameter. The deployed payload is sent
        untouched in the response body; the authed user's saved draft
        for this path — whatever shape the editor wrote — is attached
        as the sibling `draft` field when `get_draft=true` and a draft
        exists. The frontend pairs the two to present diff / reset /
        discard UI; the server never merges them.

        When `no_deployed=true` there is no deployed row at this path —
        the response body is a best-effort stand-in synthesized from
        the draft, and only `draft` is canonical. Callers should disable
        "diff vs deployed" UI in that case.
      properties:
        is_draft:
          type: boolean
        draft_saved_at:
          type: string
          format: date-time
        no_deployed:
          type: boolean
        draft:
          type: object
          additionalProperties: true
        other_drafts_users:
          description: |
            Other workspace users (and the legacy NULL-email row, if any)
            with a saved draft at the same path. Populated only on the
            authed user's "get by path" responses for kinds the editor
            surfaces a fork banner for (script, flow, app, raw_app).
            Empty / omitted for kinds without that UI.
          type: array
          items:
            type: object
            properties:
              username:
                type: string
                nullable: true
                description: |
                  Workspace username of the draft owner. `null` represents
                  the legacy workspace-level (NULL-email) row. Emails never
                  leave the server.
              draft_saved_at:
                type: string
                format: date-time
                description: |
                  When this user's draft was last saved (`draft.created_at`),
                  surfaced in the fork modal as "Last updated".
            required: [draft_saved_at]
      required: [is_draft]
    UserDraftItemKind:
      type: string
      description: |
        Closed set of item kinds a user can autosave as a draft. Mirrors the
        Postgres `DRAFT_KIND` enum and the backend `UserDraftItemKind`.
      enum:
        - script
        - flow
        - app
        - raw_app
        - resource
        - variable
        - trigger_schedule
        - trigger_webhook
        - trigger_default_email
        - trigger_email
        - trigger_http
        - trigger_websocket
        - trigger_postgres
        - trigger_kafka
        - trigger_nats
        - trigger_mqtt
        - trigger_amqp
        - trigger_sqs
        - trigger_gcp
        - trigger_azure
        - trigger_poll
        - trigger_cli
        - trigger_nextcloud
        - trigger_google
        - trigger_github
        - data_pipeline
    # Do not change next line. It is used by python-client for pre-processing
    # -- INLINE START --
    OpenFlow:
      $ref: "../../openflow.openapi.yaml#/components/schemas/OpenFlow"
    FlowValue:
      $ref: "../../openflow.openapi.yaml#/components/schemas/FlowValue"
    Retry:
      $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
    StopAfterIf:
      $ref: "../../openflow.openapi.yaml#/components/schemas/StopAfterIf"
    FlowModule:
      $ref: "../../openflow.openapi.yaml#/components/schemas/FlowModule"
    InputTransform:
      $ref: "../../openflow.openapi.yaml#/components/schemas/InputTransform"
    StaticTransform:
      $ref: "../../openflow.openapi.yaml#/components/schemas/StaticTransform"
    JavascriptTransform:
      $ref: "../../openflow.openapi.yaml#/components/schemas/JavascriptTransform"
    AiTransform:
      $ref: "../../openflow.openapi.yaml#/components/schemas/AiTransform"
    ProviderConfig:
      $ref: "../../openflow.openapi.yaml#/components/schemas/ProviderConfig"
    MemoryConfig:
      $ref: "../../openflow.openapi.yaml#/components/schemas/MemoryConfig"
    FlowModuleValue:
      $ref: "../../openflow.openapi.yaml#/components/schemas/FlowModuleValue"
    RawScript:
      $ref: "../../openflow.openapi.yaml#/components/schemas/RawScript"
    PathScript:
      $ref: "../../openflow.openapi.yaml#/components/schemas/PathScript"
    PathFlow:
      $ref: "../../openflow.openapi.yaml#/components/schemas/PathFlow"
    ForloopFlow:
      $ref: "../../openflow.openapi.yaml#/components/schemas/ForloopFlow"
    WhileloopFlow:
      $ref: "../../openflow.openapi.yaml#/components/schemas/WhileloopFlow"
    BranchOne:
      $ref: "../../openflow.openapi.yaml#/components/schemas/BranchOne"
    BranchAll:
      $ref: "../../openflow.openapi.yaml#/components/schemas/BranchAll"
    AiAgent:
      $ref: "../../openflow.openapi.yaml#/components/schemas/AiAgent"
    Identity:
      $ref: "../../openflow.openapi.yaml#/components/schemas/Identity"
    FlowStatus:
      $ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatus"
    FlowStatusModule:
      $ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatusModule"
    FlowNote:
      $ref: "../../openflow.openapi.yaml#/components/schemas/FlowNote"
    # -- INLINE END --
    # Do not change line above

    CiTestResult:
      type: object
      properties:
        test_script_path:
          type: string
        job_id:
          type: string
          format: uuid
          nullable: true
        status:
          type: string
          nullable: true
        started_at:
          type: string
          format: date-time
          nullable: true
      required:
        - test_script_path

    HealthStatusResponse:
      type: object
      description: Health status response (cached with 5s TTL)
      required:
        - status
        - checked_at
        - database_healthy
        - workers_alive
      properties:
        status:
          type: string
          enum: [healthy, degraded, unhealthy]
          description: Overall health status
        checked_at:
          type: string
          format: date-time
          description: Timestamp when the health check was actually performed (not cache return time)
        database_healthy:
          type: boolean
          description: Whether the database is reachable
        workers_alive:
          type: integer
          format: int64
          description: Number of workers that pinged within last 5 minutes

    DetailedHealthResponse:
      type: object
      description: Detailed health status response (always fresh, no caching)
      required:
        - status
        - checked_at
        - version
        - checks
      properties:
        status:
          type: string
          enum: [healthy, degraded, unhealthy]
          description: Overall health status
        checked_at:
          type: string
          format: date-time
          description: Timestamp when the health check was performed
        version:
          type: string
          description: Server version (e.g., "EE 1.615.3")
        checks:
          $ref: "#/components/schemas/HealthChecks"

    HealthChecks:
      type: object
      description: Detailed health checks
      required:
        - database
        - readiness
      properties:
        database:
          $ref: "#/components/schemas/DatabaseHealth"
        workers:
          $ref: "#/components/schemas/WorkersHealth"
          description: Worker status (null if database is unreachable)
          nullable: true
        queue:
          $ref: "#/components/schemas/QueueHealth"
          description: Queue status (null if database is unreachable)
          nullable: true
        readiness:
          $ref: "#/components/schemas/ReadinessHealth"

    DatabaseHealth:
      type: object
      description: Database health status
      required:
        - healthy
        - latency_ms
        - pool
      properties:
        healthy:
          type: boolean
          description: Whether the database is reachable
        latency_ms:
          type: integer
          format: int64
          description: Database query latency in milliseconds
        pool:
          $ref: "#/components/schemas/PoolStats"

    PoolStats:
      type: object
      description: Database connection pool statistics
      required:
        - size
        - idle
        - max_connections
      properties:
        size:
          type: integer
          description: Current number of connections in the pool
        idle:
          type: integer
          description: Number of idle connections
        max_connections:
          type: integer
          description: Maximum number of connections allowed

    WorkersHealth:
      type: object
      description: Workers health status
      required:
        - healthy
        - active_count
        - worker_groups
        - min_version
        - versions
      properties:
        healthy:
          type: boolean
          description: Whether any workers are active
        active_count:
          type: integer
          format: int64
          description: Number of active workers (pinged in last 5 minutes)
        worker_groups:
          type: array
          items:
            type: string
          description: List of active worker groups
        min_version:
          type: string
          description: Minimum required worker version
        versions:
          type: array
          items:
            type: string
          description: List of active worker versions

    QueueHealth:
      type: object
      description: Job queue status
      required:
        - pending_jobs
        - running_jobs
      properties:
        pending_jobs:
          type: integer
          format: int64
          description: Number of pending jobs in the queue
        running_jobs:
          type: integer
          format: int64
          description: Number of currently running jobs

    ReadinessHealth:
      type: object
      description: Server readiness status
      required:
        - healthy
      properties:
        healthy:
          type: boolean
          description: Whether the server is ready to accept requests

    AutoInviteConfig:
      type: object
      description: Configuration for auto-inviting users to the workspace
      properties:
        enabled:
          type: boolean
          default: false
        domain:
          type: string
        operator:
          type: boolean
          default: false
          description: If true, auto-invited users are added as operators. If false, they are added as developers.
        mode:
          type: string
          enum: ["invite", "add"]
          default: "invite"
        instance_groups:
          type: array
          items:
            type: string
        instance_groups_roles:
          type: object
          additionalProperties:
            type: string

    ErrorHandlerConfig:
      type: object
      description: Configuration for the workspace error handler
      properties:
        path:
          type: string
          description: Path to the error handler script or flow
        extra_args:
          $ref: "#/components/schemas/ScriptArgs"
        muted_on_cancel:
          type: boolean
          default: false
        muted_on_user_path:
          type: boolean
          default: false

    SuccessHandlerConfig:
      type: object
      description: Configuration for the workspace success handler
      properties:
        path:
          type: string
          description: Path to the success handler script or flow
        extra_args:
          $ref: "#/components/schemas/ScriptArgs"

    EditErrorHandler:
      description: Request body for editing the workspace error handler. Accepts both new grouped format and legacy flat format for backward compatibility.
      oneOf:
        - $ref: "#/components/schemas/EditErrorHandlerNew"
        - $ref: "#/components/schemas/EditErrorHandlerLegacy"

    EditErrorHandlerNew:
      type: object
      description: New grouped format for editing error handler
      properties:
        path:
          type: string
          description: Path to the error handler script or flow
        extra_args:
          $ref: "#/components/schemas/ScriptArgs"
        muted_on_cancel:
          type: boolean
          default: false
        muted_on_user_path:
          type: boolean
          default: false

    EditErrorHandlerLegacy:
      type: object
      description: Legacy flat format for editing error handler (deprecated, use new format)
      properties:
        error_handler:
          type: string
          description: Path to the error handler script or flow
        error_handler_extra_args:
          $ref: "#/components/schemas/ScriptArgs"
        error_handler_muted_on_cancel:
          type: boolean
          default: false

    EditSuccessHandler:
      description: Request body for editing the workspace success handler. Accepts both new grouped format and legacy flat format for backward compatibility.
      oneOf:
        - $ref: "#/components/schemas/EditSuccessHandlerNew"
        - $ref: "#/components/schemas/EditSuccessHandlerLegacy"

    EditSuccessHandlerNew:
      type: object
      description: New grouped format for editing success handler
      properties:
        path:
          type: string
          description: Path to the success handler script or flow
        extra_args:
          $ref: "#/components/schemas/ScriptArgs"

    EditSuccessHandlerLegacy:
      type: object
      description: Legacy flat format for editing success handler (deprecated, use new format)
      properties:
        success_handler:
          type: string
          description: Path to the success handler script or flow
        success_handler_extra_args:
          $ref: "#/components/schemas/ScriptArgs"

    VaultSettings:
      type: object
      required:
        - address
        - mount_path
      properties:
        address:
          type: string
          description: HashiCorp Vault server address (e.g., https://vault.company.com:8200)
        mount_path:
          type: string
          description: KV v2 secrets engine mount path (e.g., windmill)
        kv_secret_path_prefix:
          type: string
          description: Optional path prefix inserted between the KV data/metadata segment and the workspace id (e.g., "apps/windmill"). When set, secrets are stored at `<mount>/data/<prefix>/<workspace>/<secret>`, allowing a Vault policy scoped to exactly `<mount>/data/<prefix>/*`.
        jwt_role:
          type: string
          description: Vault JWT auth role name for Windmill (optional, if not provided token auth is used)
        jwt_mount_path:
          type: string
          description: Mount path for the JWT auth method in Vault (optional, defaults to "jwt"). Set this when the JWT auth method is mounted at a non-default path, e.g. via `vault auth enable -path=<mount> jwt`.
        namespace:
          type: string
          description: Vault Enterprise namespace (optional)
        token:
          type: string
          description: Static Vault token for testing/development (optional, if provided this is used instead of JWT authentication)
        skip_ssl_verify:
          type: boolean
          description: Skip TLS certificate verification when connecting to Vault. Only use for self-signed certificates in development environments.

    AzureKeyVaultSettings:
      type: object
      required:
        - vault_url
        - tenant_id
        - client_id
      properties:
        vault_url:
          type: string
          description: Azure Key Vault URL (e.g., https://myvault.vault.azure.net)
        tenant_id:
          type: string
          description: Azure AD tenant ID
        client_id:
          type: string
          description: Azure AD application (client) ID
        client_secret:
          type: string
          description: >-
            Azure AD client secret. Optional — when omitted, the integration falls back to
            Azure Workload Identity Federation, exchanging the Kubernetes-projected service-account
            JWT at AZURE_FEDERATED_TOKEN_FILE for an access token (no long-lived secret stored).
        token:
          type: string
          description: Static Bearer token for testing/development (optional, if provided this is used instead of OAuth2 authentication)

    AwsSecretsManagerSettings:
      type: object
      required:
        - region
      properties:
        region:
          type: string
          description: AWS region (e.g., us-east-1)
        access_key_id:
          type: string
          description: AWS Access Key ID (optional, uses default credential chain if not provided)
        secret_access_key:
          type: string
          description: AWS Secret Access Key (optional)
        endpoint_url:
          type: string
          description: Custom endpoint URL for testing (e.g., LocalStack)
        prefix:
          type: string
          description: Prefix for secret names (e.g., windmill/)

    SecretMigrationFailure:
      type: object
      required:
        - workspace_id
        - path
        - error
      properties:
        workspace_id:
          type: string
          description: Workspace ID where the secret is located
        path:
          type: string
          description: Path of the secret that failed to migrate
        error:
          type: string
          description: Error message

    SecretMigrationReport:
      type: object
      required:
        - total_secrets
        - migrated_count
        - failed_count
        - failures
      properties:
        total_secrets:
          type: integer
          format: int64
          description: Total number of secrets found
        migrated_count:
          type: integer
          format: int64
          description: Number of secrets successfully migrated
        failed_count:
          type: integer
          format: int64
          description: Number of secrets that failed to migrate
        failures:
          type: array
          items:
            $ref: "#/components/schemas/SecretMigrationFailure"
          description: Details of any failures encountered during migration

    JwksResponse:
      type: object
      required:
        - keys
      properties:
        keys:
          type: array
          items:
            type: object
            additionalProperties: true
          description: Array of JSON Web Keys for JWT verification

    FlowConversation:
      type: object
      required:
        [id, workspace_id, flow_path, created_at, updated_at, created_by]
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the conversation
        workspace_id:
          type: string
          description: The workspace ID where the conversation belongs
        flow_path:
          type: string
          description: Path of the flow this conversation is for
        title:
          type: string
          description: Optional title for the conversation
          nullable: true
        created_at:
          type: string
          format: date-time
          description: When the conversation was created
        updated_at:
          type: string
          format: date-time
          description: When the conversation was last updated
        created_by:
          type: string
          description: Username who created the conversation

    FlowConversationMessage:
      type: object
      required: [id, conversation_id, message_type, content, created_at, created_seq]
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the message
        conversation_id:
          type: string
          format: uuid
          description: The conversation this message belongs to
        message_type:
          type: string
          enum: [user, assistant, system, tool]
          description: Type of the message
        content:
          type: string
          description: The message content
        job_id:
          type: string
          format: uuid
          nullable: true
          description: Associated job ID if this message came from a flow run
        created_at:
          type: string
          format: date-time
          description: When the message was created
        created_seq:
          type: integer
          format: int64
          description: Monotonic cursor assigned when the message is inserted
        step_name:
          type: string
          description: The step name that produced that message
        success:
          type: boolean
          description: Whether the message is a success

    EndpointTool:
      type: object
      required: [name, description, instructions, path, method]
      properties:
        name:
          type: string
          description: The tool name/operation ID
        description:
          type: string
          description: Short description of the tool
        instructions:
          type: string
          description: Detailed instructions for using the tool
        path:
          type: string
          description: API endpoint path
        method:
          type: string
          description: HTTP method (GET, POST, etc.)
        path_params_schema:
          type: object
          description: JSON schema for path parameters
          nullable: true
        query_params_schema:
          type: object
          description: JSON schema for query parameters
          nullable: true
        body_schema:
          type: object
          description: JSON schema for request body
          nullable: true

    AIProvider:
      type: string
      enum:
        [
          openai,
          azure_openai,
          azure_foundry,
          anthropic,
          mistral,
          deepseek,
          googleai,
          groq,
          openrouter,
          togetherai,
          aws_bedrock,
          customai,
        ]

    GitSyncObjectType:
      type: string
      enum:
        - script
        - flow
        - app
        - folder
        - resource
        - variable
        - secret
        - resourcetype
        - schedule
        - user
        - group
        - trigger
        - settings
        - key
        - workspacedependencies

    AIProviderModel:
      type: object
      properties:
        model:
          type: string
        provider:
          $ref: "#/components/schemas/AIProvider"
      required:
        - model
        - provider

    AIProviderConfig:
      type: object
      properties:
        resource_path:
          type: string
        models:
          type: array
          items:
            type: string
        web_search_enabled:
          type: boolean
      required:
        - resource_path
        - models

    AIConfig:
      type: object
      properties:
        providers:
          type: object
          additionalProperties:
            $ref: "#/components/schemas/AIProviderConfig"
        default_model:
          $ref: "#/components/schemas/AIProviderModel"
        metadata_model:
          $ref: "#/components/schemas/AIProviderModel"
        code_completion_model:
          $ref: "#/components/schemas/AIProviderModel"
        custom_prompts:
          type: object
          additionalProperties:
            type: string
        max_tokens_per_model:
          type: object
          additionalProperties:
            type: integer
            minimum: 1
            maximum: 2000000

    InstanceAIProviderSummary:
      type: object
      properties:
        provider:
          $ref: "#/components/schemas/AIProvider"
        models:
          type: array
          items:
            type: string
      required:
        - provider
        - models

    InstanceAISummary:
      type: object
      properties:
        providers:
          type: array
          items:
            $ref: "#/components/schemas/InstanceAIProviderSummary"
        default_model:
          $ref: "#/components/schemas/AIProviderModel"
        metadata_model:
          $ref: "#/components/schemas/AIProviderModel"
        code_completion_model:
          $ref: "#/components/schemas/AIProviderModel"
      required:
        - providers

    Alert:
      type: object
      properties:
        name:
          type: string
        tags_to_monitor:
          type: array
          items:
            type: string
        jobs_num_threshold:
          type: integer
        alert_cooldown_seconds:
          type: integer
        alert_time_threshold_seconds:
          type: integer
      required:
        - name
        - tags_to_monitor
        - jobs_num_threshold
        - alert_cooldown_seconds
        - alert_time_threshold_seconds

    Configs:
      type: object
      nullable: true
      properties:
        alerts:
          type: array
          items:
            $ref: "#/components/schemas/Alert"

    WorkspaceDependencies:
      type: object
      properties:
        id:
          type: integer
        archived:
          type: boolean
        name:
          type: string
        description:
          type: string
        content:
          type: string
        language:
          $ref: "#/components/schemas/ScriptLang"
        workspace_id:
          type: string
        created_at:
          type: string
          format: date-time
      required:
        - workspace_id
        - language
        - created_at
        - content
        - id
        - archived

    NewWorkspaceDependencies:
      type: object
      properties:
        workspace_id:
          type: string
        language:
          $ref: "#/components/schemas/ScriptLang"
        name:
          type: string
        description:
          type: string
        content:
          type: string
      required:
        - workspace_id
        - language
        - content

    Script:
      type: object
      properties:
        workspace_id:
          type: string
        hash:
          type: string
        path:
          type: string
        parent_hashes:
          type: array
          description: |
            The first element is the direct parent of the script, the second is the parent of the first, etc
          items:
            type: string
        summary:
          type: string
        description:
          type: string
        content:
          type: string
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        archived:
          type: boolean
        schema:
          type: object
        deleted:
          type: boolean
        is_template:
          type: boolean
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        lock:
          type: string
        lock_error_logs:
          type: string
        language:
          $ref: "#/components/schemas/ScriptLang"
        kind:
          type: string
          enum: [script, failure, trigger, command, approval, preprocessor]
        starred:
          type: boolean
        tag:
          type: string
        draft_only:
          type: boolean
        envs:
          type: array
          items:
            type: string
        concurrent_limit:
          type: integer
        concurrency_time_window_s:
          type: integer
        concurrency_key:
          type: string
        debounce_key:
          type: string
        debounce_delay_s:
          type: integer
        debounce_args_to_accumulate:
          type: array
          items:
            type: string
        max_total_debouncing_time:
          type: integer
        max_total_debounces_amount:
          type: integer
        cache_ttl:
          type: number
        dedicated_worker:
          type: boolean
        ws_error_handler_muted:
          type: boolean
        priority:
          type: integer
        restart_unless_cancelled:
          type: boolean
        timeout:
          type: integer
        delete_after_secs:
          type: integer
          description: If set, delete the job's args, result and logs after this many seconds following job completion
        visible_to_runner_only:
          type: boolean
        auto_kind:
          type: string
        codebase:
          type: string
        has_preprocessor:
          type: boolean
        on_behalf_of_email:
          type: string
        modules:
          type: object
          nullable: true
          description: "Additional script modules keyed by relative file path"
          additionalProperties:
            $ref: "#/components/schemas/ScriptModule"
        labels:
          type: array
          items:
            type: string
          default: []
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.

      required:
        - hash
        - path
        - summary
        - description
        - content
        - created_by
        - created_at
        - archived
        - deleted
        - is_template
        - extra_perms
        - language
        - kind
        - starred
        - has_preprocessor


    NewScript:
      type: object
      properties:
        path:
          type: string
        parent_hash:
          type: string
        auto_parent:
          type: boolean
          description: >-
            When true, the backend resolves the parent to the current deployed
            head for this path within the transaction (ignoring parent_hash),
            instead of failing with a "lineage must be linear" error when the
            supplied parent_hash is stale.
        summary:
          type: string
        description:
          type: string
        content:
          type: string
        schema:
          type: object
        is_template:
          type: boolean
        lock:
          type: string
        language:
          $ref: "#/components/schemas/ScriptLang"
        kind:
          type: string
          enum: [script, failure, trigger, command, approval, preprocessor]
        tag:
          type: string
        envs:
          type: array
          items:
            type: string
        concurrent_limit:
          type: integer
        concurrency_time_window_s:
          type: integer
        cache_ttl:
          type: number
        cache_ignore_s3_path:
          type: boolean
        dedicated_worker:
          type: boolean
        ws_error_handler_muted:
          type: boolean
        priority:
          type: integer
        restart_unless_cancelled:
          type: boolean
        timeout:
          type: integer
        delete_after_secs:
          type: integer
          description: If set, delete the job's args, result and logs after this many seconds following job completion
        deployment_message:
          type: string
        concurrency_key:
          type: string
        debounce_key:
          type: string
        debounce_delay_s:
          type: integer
        debounce_args_to_accumulate:
          type: array
          items:
            type: string
        max_total_debouncing_time:
          type: integer
        max_total_debounces_amount:
          type: integer
        visible_to_runner_only:
          type: boolean
        auto_kind:
          type: string
        codebase:
          type: string
        has_preprocessor:
          type: boolean
        on_behalf_of_email:
          type: string
        preserve_on_behalf_of:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original on_behalf_of_email value instead of overwriting it."
        assets:
          type: array
          items:
            type: object
            required:
              - path
              - kind
            properties:
              path:
                type: string
              kind:
                $ref: "#/components/schemas/AssetKind"
              access_type:
                type: string
                enum: [r, w, rw]
              alt_access_type:
                type: string
                enum: [r, w, rw]
        modules:
          type: object
          nullable: true
          description: "Additional script modules keyed by relative file path"
          additionalProperties:
            $ref: "#/components/schemas/ScriptModule"
        labels:
          type: array
          items:
            type: string
        skip_draft_deletion:
          type: boolean
          description: "When true (set by the CLI / git sync), deploying this script does not delete an existing user draft at the same path."

      required:
        - path
        - summary
        - content
        - language

    ScriptHistory:
      type: object
      properties:
        script_hash:
          type: string
        deployment_msg:
          type: string
      required:
        - script_hash

    ScriptArgs:
      type: object
      description: The arguments to pass to the script or flow
      additionalProperties: true

    Input:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        is_public:
          type: boolean
        success:
          type: boolean
      required:
        - id
        - name
        - args
        - created_by
        - created_at
        - is_public

    CreateInput:
      type: object
      properties:
        name:
          type: string
        args:
          type: object
      required:
        - name
        - args
        - created_by

    UpdateInput:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        is_public:
          type: boolean
      required:
        - id
        - name
        - is_public

    RunnableType:
      type: string
      enum: ["ScriptHash", "ScriptPath", "FlowPath"]

    QueuedJob:
      type: object
      properties:
        workspace_id:
          type: string
        id:
          type: string
          format: uuid
        parent_job:
          type: string
          format: uuid
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
        scheduled_for:
          type: string
          format: date-time
        running:
          type: boolean
        script_path:
          type: string
        script_hash:
          type: string
        args:
          $ref: "#/components/schemas/ScriptArgs"
        logs:
          type: string
        raw_code:
          type: string
        canceled:
          type: boolean
        canceled_by:
          type: string
        canceled_reason:
          type: string
        last_ping:
          type: string
          format: date-time
        job_kind:
          type: string
          enum:
            [
              "script",
              "preview",
              "dependencies",
              "flowdependencies",
              "appdependencies",
              "flow",
              "flowpreview",
              "script_hub",
              "identity",
              "deploymentcallback",
              "singlestepflow",
              "flowscript",
              "flownode",
              "appscript",
              "aiagent",
              "unassigned_script",
              "unassigned_flow",
              "unassigned_singlestepflow",
            ]
        schedule_path:
          type: string
        permissioned_as:
          type: string
          description: |
            The user (u/userfoo) or group (g/groupfoo) whom
            the execution of this script will be permissioned_as and by extension its DT_TOKEN.
        flow_status:
          $ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatus"
        workflow_as_code_status:
          $ref: "#/components/schemas/WorkflowStatus"
        raw_flow:
          $ref: "../../openflow.openapi.yaml#/components/schemas/FlowValue"
        is_flow_step:
          type: boolean
        language:
          $ref: "#/components/schemas/ScriptLang"
        email:
          type: string
        visible_to_owner:
          type: boolean
        mem_peak:
          type: integer
        tag:
          type: string
        priority:
          type: integer
        self_wait_time_ms:
          type: number
        aggregate_wait_time_ms:
          type: number
        suspend:
          type: number
        preprocessed:
          type: boolean
        is_retry:
          type: boolean
        worker:
          type: string
      required:
        - id
        - running
        - canceled
        - job_kind
        - permissioned_as
        - is_flow_step
        - email
        - visible_to_owner
        - tag

    CompletedJob:
      type: object
      properties:
        workspace_id:
          type: string
        id:
          type: string
          format: uuid
        parent_job:
          type: string
          format: uuid
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        duration_ms:
          type: integer
        success:
          type: boolean
        script_path:
          type: string
        script_hash:
          type: string
        args:
          $ref: "#/components/schemas/ScriptArgs"
        result: {}
        logs:
          type: string
        deleted:
          type: boolean
        raw_code:
          type: string
        canceled:
          type: boolean
        canceled_by:
          type: string
        canceled_reason:
          type: string
        job_kind:
          type: string
          enum:
            [
              "script",
              "preview",
              "dependencies",
              "flow",
              "flowdependencies",
              "appdependencies",
              "flowpreview",
              "script_hub",
              "identity",
              "deploymentcallback",
              "singlestepflow",
              "flowscript",
              "flownode",
              "appscript",
              "aiagent",
              "unassigned_script",
              "unassigned_flow",
              "unassigned_singlestepflow",
            ]
        schedule_path:
          type: string
        permissioned_as:
          type: string
          description: |
            The user (u/userfoo) or group (g/groupfoo) whom
            the execution of this script will be permissioned_as and by extension its DT_TOKEN.
        flow_status:
          $ref: "../../openflow.openapi.yaml#/components/schemas/FlowStatus"
        workflow_as_code_status:
          $ref: "#/components/schemas/WorkflowStatus"
        raw_flow:
          $ref: "../../openflow.openapi.yaml#/components/schemas/FlowValue"
        is_flow_step:
          type: boolean
        language:
          $ref: "#/components/schemas/ScriptLang"
        is_skipped:
          type: boolean
        email:
          type: string
        visible_to_owner:
          type: boolean
        mem_peak:
          type: integer
        tag:
          type: string
        priority:
          type: integer
        labels:
          type: array
          items:
            type: string
        self_wait_time_ms:
          type: number
        aggregate_wait_time_ms:
          type: number
        preprocessed:
          type: boolean
        is_retry:
          type: boolean
        worker:
          type: string
      required:
        - id
        - created_by
        - duration_ms
        - created_at
        - started_at
        - success
        - canceled
        - job_kind
        - permissioned_as
        - is_flow_step
        - is_skipped
        - email
        - visible_to_owner
        - tag

    ExportableCompletedJob:
      type: object
      description: Completed job with full data for export/import operations
      properties:
        id:
          type: string
          format: uuid
        parent_job:
          type: string
          format: uuid
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        duration_ms:
          type: integer
        script_path:
          type: string
        script_hash:
          type: string
        args:
          type: object
          description: Full job arguments without size restrictions
        result:
          type: object
          description: Full job result without size restrictions
        logs:
          type: string
          description: Complete job logs from v2_job table
        raw_code:
          type: string
        raw_lock:
          type: string
        canceled_by:
          type: string
        canceled_reason:
          type: string
        job_kind:
          type: string
          enum:
            [
              "script",
              "preview",
              "dependencies",
              "flow",
              "flowdependencies",
              "appdependencies",
              "flowpreview",
              "script_hub",
              "identity",
              "deploymentcallback",
              "singlestepflow",
              "flowscript",
              "flownode",
              "appscript",
              "aiagent",
              "unassigned_script",
              "unassigned_flow",
              "unassigned_singlestepflow",
            ]
        trigger:
          type: string
          description: Trigger path for the job (replaces schedule_path)
        trigger_kind:
          type: string
          enum:
            [
              "webhook",
              "http",
              "websocket",
              "kafka",
              "email",
              "nats",
              "schedule",
              "app",
              "ui",
              "postgres",
              "sqs",
              "gcp",
            ]
        permissioned_as:
          type: string
        permissioned_as_email:
          type: string
        flow_status:
          type: object
          description: Flow status from v2_job_status table
        workflow_as_code_status:
          type: object
        raw_flow:
          type: object
        is_flow_step:
          type: boolean
        language:
          $ref: "#/components/schemas/ScriptLang"
        is_skipped:
          type: boolean
        email:
          type: string
        visible_to_owner:
          type: boolean
        mem_peak:
          type: integer
        tag:
          type: string
        priority:
          type: integer
        labels:
          type: array
          items:
            type: string
        same_worker:
          type: boolean
        flow_step_id:
          type: string
        flow_innermost_root_job:
          type: string
          format: uuid
        concurrent_limit:
          type: integer
        concurrency_time_window_s:
          type: integer
        timeout:
          type: integer
        cache_ttl:
          type: integer
        self_wait_time_ms:
          type: integer
        aggregate_wait_time_ms:
          type: integer
        preprocessed:
          type: boolean
        worker:
          type: string
        status:
          type: string
          description: Actual job status from database
      required:
        - id
        - created_by
        - created_at
        - job_kind
        - permissioned_as
        - email
        - visible_to_owner

    ExportableQueuedJob:
      type: object
      description: Queued job with full data for export/import operations
      properties:
        id:
          type: string
          format: uuid
        parent_job:
          type: string
          format: uuid
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
        scheduled_for:
          type: string
          format: date-time
        script_path:
          type: string
        script_hash:
          type: string
        args:
          type: object
          description: Full job arguments without size restrictions
        logs:
          type: string
          description: Complete job logs from v2_job table
        raw_code:
          type: string
        raw_lock:
          type: string
        canceled_by:
          type: string
        canceled_reason:
          type: string
        job_kind:
          type: string
          enum:
            [
              "script",
              "preview",
              "dependencies",
              "flowdependencies",
              "appdependencies",
              "flow",
              "flowpreview",
              "script_hub",
              "identity",
              "deploymentcallback",
              "singlestepflow",
              "flowscript",
              "flownode",
              "appscript",
              "aiagent",
              "unassigned_script",
              "unassigned_flow",
              "unassigned_singlestepflow",
            ]
        trigger:
          type: string
          description: Trigger path for the job (replaces schedule_path)
        trigger_kind:
          type: string
          enum:
            [
              "webhook",
              "http",
              "websocket",
              "kafka",
              "email",
              "nats",
              "schedule",
              "app",
              "ui",
              "postgres",
              "sqs",
              "gcp",
            ]
        permissioned_as:
          type: string
        permissioned_as_email:
          type: string
        flow_status:
          type: object
          description: Flow status from v2_job_status table
        workflow_as_code_status:
          type: object
        raw_flow:
          type: object
        is_flow_step:
          type: boolean
        language:
          $ref: "#/components/schemas/ScriptLang"
        email:
          type: string
        visible_to_owner:
          type: boolean
        mem_peak:
          type: integer
        tag:
          type: string
        priority:
          type: integer
        labels:
          type: array
          items:
            type: string
        same_worker:
          type: boolean
        flow_step_id:
          type: string
        flow_innermost_root_job:
          type: string
          format: uuid
        concurrent_limit:
          type: integer
        concurrency_time_window_s:
          type: integer
        timeout:
          type: integer
        cache_ttl:
          type: integer
        self_wait_time_ms:
          type: integer
        aggregate_wait_time_ms:
          type: integer
        preprocessed:
          type: boolean
        suspend:
          type: integer
        suspend_until:
          type: string
          format: date-time
      required:
        - id
        - created_by
        - created_at
        - job_kind
        - permissioned_as
        - email
        - visible_to_owner

    ObscuredJob:
      type: object
      properties:
        typ:
          type: string
        started_at:
          type: string
          format: date-time
        duration_ms:
          type: number
    Job:
      oneOf:
        - allOf:
            - $ref: "#/components/schemas/CompletedJob"
            - type: object
              properties:
                type:
                  type: string
                  enum: [CompletedJob]
        - allOf:
            - $ref: "#/components/schemas/QueuedJob"
            - type: object
              properties:
                type:
                  type: string
                  enum: [QueuedJob]
      discriminator:
        propertyName: type

    User:
      type: object
      properties:
        email:
          type: string
        username:
          type: string
        is_admin:
          type: boolean
        name:
          type: string
        is_super_admin:
          type: boolean
        created_at:
          type: string
          format: date-time
        operator:
          type: boolean
        disabled:
          type: boolean
        groups:
          type: array
          items:
            type: string
        folders:
          type: array
          items:
            type: string
        folders_read:
          type: array
          items:
            type: string
        folders_owners:
          type: array
          items:
            type: string
        added_via:
          nullable: true
          allOf:
            - $ref: "#/components/schemas/UserSource"
        is_service_account:
          type: boolean
        non_member:
          type: boolean
          description: "True when this is a superadmin viewing a workspace they are not a member of (is_admin/role reflect the superadmin fallback, not an actual membership)."
      required:
        - email
        - username
        - is_admin
        - is_super_admin
        - created_at
        - operator
        - disabled
        - folders
        - folders_read
        - folders_owners

    UserSource:
      type: object
      properties:
        source:
          type: string
          enum: [domain, instance_group, manual]
          description: "How the user was added to the workspace"
        domain:
          type: string
          description: "The domain used for auto-invite (when source is 'domain')"
        group:
          type: string
          description: "The instance group name (when source is 'instance_group')"
      required:
        - source

    UserUsage:
      type: object
      properties:
        email:
          type: string
        executions:
          type: number

    Login:
      type: object
      properties:
        email:
          type: string
        password:
          type: string
      required:
        - email
        - password

    PasswordResetResponse:
      type: object
      properties:
        message:
          type: string
      required:
        - message

    EditWorkspaceUser:
      type: object
      properties:
        is_admin:
          type: boolean
        operator:
          type: boolean
        disabled:
          type: boolean

    OffboardAffectedPaths:
      type: object
      properties:
        scripts:
          type: array
          items:
            type: string
        flows:
          type: array
          items:
            type: string
        apps:
          type: array
          items:
            type: string
        resources:
          type: array
          items:
            type: string
        variables:
          type: array
          items:
            type: string
        schedules:
          type: array
          items:
            type: string
        triggers:
          type: object
          additionalProperties:
            type: array
            items:
              type: string

    OffboardPreview:
      type: object
      properties:
        owned:
          $ref: "#/components/schemas/OffboardAffectedPaths"
          description: "Objects under u/{username}/ that will be reassigned"
        executing_on_behalf:
          $ref: "#/components/schemas/OffboardAffectedPaths"
          description: "Objects not under the user's path but that execute on behalf of this user (permissioned_as/on_behalf_of will be updated)"
        referencing:
          $ref: "#/components/schemas/OffboardAffectedPaths"
          description: "Scripts/flows/apps/resources whose content or value references this user's paths (may break after reassignment)"
        tokens:
          type: array
          items:
            $ref: "#/components/schemas/OffboardTokenInfo"
          description: "Tokens owned by this user (will be deleted)"
        http_triggers:
          type: integer
          description: "HTTP triggers under the user's path (webhook URLs will change)"
        email_triggers:
          type: integer
          description: "Email triggers under the user's path (email addresses will change)"
      required:
        - owned
        - executing_on_behalf
        - referencing
        - tokens
        - http_triggers
        - email_triggers

    OffboardTokenInfo:
      type: object
      properties:
        label:
          type: string
        scopes:
          type: array
          items:
            type: string
        expiration:
          type: string
      required:
        - label
        - scopes

    OffboardRequest:
      type: object
      properties:
        reassign_to:
          type: string
          description: "Target for reassignment: 'u/{username}' or 'f/{folder}'"
        new_on_behalf_of_user:
          type: string
          description: "Required when reassign_to is a folder. The username whose identity will be used as permissioned_as for schedules and triggers."
        delete_user:
          type: boolean
          default: true
          description: "Whether to also remove the user from the workspace"
      required:
        - reassign_to

    OffboardResponse:
      type: object
      properties:
        conflicts:
          type: array
          items:
            type: string
          description: "List of path conflicts that block the offboarding. Empty on success."
        summary:
          $ref: "#/components/schemas/OffboardSummary"

    OffboardSummary:
      type: object
      properties:
        scripts_reassigned:
          type: integer
        flows_reassigned:
          type: integer
        apps_reassigned:
          type: integer
        resources_reassigned:
          type: integer
        variables_reassigned:
          type: integer
        schedules_reassigned:
          type: integer
        triggers_reassigned:
          type: integer
        drafts_deleted:
          type: integer
      required:
        - scripts_reassigned
        - flows_reassigned
        - apps_reassigned
        - resources_reassigned
        - variables_reassigned
        - schedules_reassigned
        - triggers_reassigned
        - drafts_deleted

    GlobalOffboardPreview:
      type: object
      properties:
        workspaces:
          type: array
          items:
            $ref: "#/components/schemas/WorkspaceOffboardPreview"
      required:
        - workspaces

    WorkspaceOffboardPreview:
      type: object
      properties:
        workspace_id:
          type: string
        username:
          type: string
        preview:
          $ref: "#/components/schemas/OffboardPreview"
      required:
        - workspace_id
        - username
        - preview

    GlobalOffboardRequest:
      type: object
      properties:
        reassignments:
          type: object
          additionalProperties:
            $ref: "#/components/schemas/WorkspaceReassignment"
          description: "Map of workspace_id to reassignment config"
        delete_user:
          type: boolean
          default: true
          description: "Whether to also remove the user from the instance"

    WorkspaceReassignment:
      type: object
      properties:
        reassign_to:
          type: string
          description: "Target: 'u/{username}' or 'f/{folder}'"
        new_on_behalf_of_user:
          type: string
          description: "Required when reassign_to is a folder. Username to use as permissioned_as."
      required:
        - reassign_to

    TruncatedToken:
      type: object
      properties:
        label:
          type: string
        expiration:
          type: string
          format: date-time
        token_prefix:
          type: string
        created_at:
          type: string
          format: date-time
        last_used_at:
          type: string
          format: date-time
        scopes:
          type: array
          items:
            type: string
        email:
          type: string
        workspace_id:
          type: string
        read_only:
          type: boolean
      required:
        - token_prefix
        - created_at
        - last_used_at
        - read_only

    ExternalJwtToken:
      type: object
      properties:
        jwt_hash:
          type: integer
          format: int64
        email:
          type: string
        username:
          type: string
        is_admin:
          type: boolean
        is_operator:
          type: boolean
        workspace_id:
          type: string
        label:
          type: string
        scopes:
          type: array
          items:
            type: string
        last_used_at:
          type: string
          format: date-time
      required:
        - jwt_hash
        - email
        - username
        - is_admin
        - is_operator
        - last_used_at

    NewToken:
      type: object
      properties:
        label:
          type: string
        expiration:
          type: string
          format: date-time
        scopes:
          type: array
          items:
            type: string
        workspace_id:
          type: string
        read_only:
          type: boolean
          description: |
            If true, the token is restricted to read-only HTTP methods
            (GET/HEAD/OPTIONS). Mutating endpoints and job-run actions are
            rejected with 403, regardless of the scopes attached.

    NewTokenImpersonate:
      type: object
      properties:
        label:
          type: string
        expiration:
          type: string
          format: date-time
        impersonate_email:
          type: string
        workspace_id:
          type: string
      required:
        - impersonate_email

    ListableVariable:
      type: object
      properties:
        workspace_id:
          type: string
        path:
          type: string
        value:
          type: string
        is_secret:
          type: boolean
        description:
          type: string
        account:
          type: integer
        is_oauth:
          type: boolean
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        is_expired:
          type: boolean
        refresh_error:
          type: string
        is_linked:
          type: boolean
        is_refreshed:
          type: boolean
        expires_at:
          type: string
          format: date-time
        labels:
          type: array
          items:
            type: string
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.
        ws_specific:
          type: boolean
        edited_at:
          type: string
          format: date-time
        edited_by:
          type: string
        draft_only:
          description: |
            True when this row is a per-user draft with no deployed
            variable at the same path. Frontend renders a "Draft" badge.
          type: boolean
        is_draft:
          description: |
            True when the authed user has a per-user draft at this path
            (over a deployed row or a synthesized draft-only row).
            Frontend appends a `*` to the displayed name.
          type: boolean
      required:
        - workspace_id
        - path
        - is_secret
        - extra_perms

    ContextualVariable:
      type: object
      properties:
        name:
          type: string
        value:
          type: string
        description:
          type: string
        is_custom:
          type: boolean
      required:
        - name
        - value
        - description
        - is_custom

    CreateVariable:
      type: object
      properties:
        path:
          type: string
          description: The path to the variable
        value:
          type: string
          description: The value of the variable
        is_secret:
          type: boolean
          description: Whether the variable is a secret
        description:
          type: string
          description: The description of the variable
        account:
          type: integer
          description: The account identifier
        is_oauth:
          type: boolean
          description: Whether the variable is an OAuth variable
        expires_at:
          type: string
          description: The expiration date of the variable
          format: date-time
        labels:
          type: array
          items:
            type: string
        ws_specific:
          type: boolean
      required:
        - path
        - value
        - is_secret
        - description

    EditVariable:
      type: object
      properties:
        path:
          type: string
          description: The path to the variable
        value:
          type: string
          description: The new value of the variable
        is_secret:
          type: boolean
          description: Whether the variable is a secret
        description:
          type: string
          description: The new description of the variable
        labels:
          type: array
          items:
            type: string
        ws_specific:
          type: boolean

    AuditLog:
      type: object
      properties:
        workspace_id:
          type: string
        id:
          type: integer
        timestamp:
          type: string
          format: date-time
        username:
          type: string
        operation:
          type: string
          enum:
            - "jobs.run"
            - "jobs.run.script"
            - "jobs.run.preview"
            - "jobs.run.flow"
            - "jobs.run.flow_preview"
            - "jobs.run.script_hub"
            - "jobs.run.dependencies"
            - "jobs.run.identity"
            - "jobs.run.noop"
            - "jobs.flow_dependencies"
            - "jobs"
            - "jobs.cancel"
            - "jobs.force_cancel"
            - "jobs.disapproval"
            - "jobs.delete"
            - "account.delete"
            - "ai.request"
            - "resources.create"
            - "resources.update"
            - "resources.delete"
            - "resource_types.create"
            - "resource_types.update"
            - "resource_types.delete"
            - "schedule.create"
            - "schedule.setenabled"
            - "schedule.edit"
            - "schedule.delete"
            - "scripts.create"
            - "scripts.update"
            - "scripts.archive"
            - "scripts.delete"
            - "users.create"
            - "users.delete"
            - "users.update"
            - "users.login"
            - "users.login_failure"
            - "users.logout"
            - "users.accept_invite"
            - "users.decline_invite"
            - "users.token.create"
            - "users.token.delete"
            - "users.add_to_workspace"
            - "users.add_global"
            - "users.setpassword"
            - "users.impersonate"
            - "users.leave_workspace"
            - "oauth.login"
            - "oauth.login_failure"
            - "oauth.signup"
            - "variables.create"
            - "variables.delete"
            - "variables.update"
            - "flows.create"
            - "flows.update"
            - "flows.delete"
            - "flows.archive"
            - "apps.create"
            - "apps.update"
            - "apps.delete"
            - "folder.create"
            - "folder.update"
            - "folder.delete"
            - "folder.add_owner"
            - "folder.remove_owner"
            - "group.create"
            - "group.delete"
            - "group.edit"
            - "group.adduser"
            - "group.removeuser"
            - "igroup.create"
            - "igroup.delete"
            - "igroup.adduser"
            - "igroup.removeuser"
            - "variables.decrypt_secret"
            - "workspaces.edit_command_script"
            - "workspaces.edit_deploy_to"
            - "workspaces.edit_auto_invite_domain"
            - "workspaces.edit_webhook"
            - "workspaces.edit_copilot_config"
            - "workspaces.edit_error_handler"
            - "workspaces.create"
            - "workspaces.update"
            - "workspaces.archive"
            - "workspaces.unarchive"
            - "workspaces.delete"
        action_kind:
          type: string
          enum: ["Created", "Updated", "Delete", "Execute"]
        resource:
          type: string
        parameters:
          type: object
        span:
          type: string
      required:
        - workspace_id
        - id
        - timestamp
        - username
        - operation
        - action_kind

    MainArgSignature:
      type: object
      properties:
        type:
          type: string
          enum: ["Valid", "Invalid"]
        error:
          type: string
        star_args:
          type: boolean
        star_kwargs:
          type: boolean
        args:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              typ:
                oneOf:
                  - type: string
                    enum:
                      [
                        "float",
                        "int",
                        "bool",
                        "email",
                        "unknown",
                        "bytes",
                        "dict",
                        "datetime",
                        "sql",
                      ]
                  - type: object
                    properties:
                      resource:
                        type: string
                        nullable: true
                    required:
                      - resource
                  - type: object
                    properties:
                      str:
                        type: array
                        items:
                          type: string
                        nullable: true
                    required:
                      - str
                  - type: object
                    properties:
                      object:
                        type: object
                        properties:
                          name:
                            type: string
                          props:
                            type: array
                            items:
                              type: object
                              properties:
                                key:
                                  type: string
                                typ:
                                  oneOf:
                                    - type: string
                                      enum:
                                        [
                                          "float",
                                          "int",
                                          "bool",
                                          "email",
                                          "unknown",
                                          "bytes",
                                          "dict",
                                          "datetime",
                                          "sql",
                                        ]
                                    - type: object
                                      properties:
                                        str: {}
                                      required: [str]
                              required:
                                - key
                                - typ
                    required:
                      - object
                  - type: object
                    properties:
                      list:
                        oneOf:
                          - type: string
                            enum:
                              [
                                "float",
                                "int",
                                "bool",
                                "email",
                                "unknown",
                                "bytes",
                                "dict",
                                "datetime",
                                "sql",
                              ]
                          - type: object
                            properties:
                              str: {}
                            required: [str]
                        nullable: true
                    required:
                      - list
              has_default:
                type: boolean
              default: {}
            required:
              - name
              - typ
        auto_kind:
          type: string
          nullable: true
        has_preprocessor:
          type: boolean
          nullable: true
      required:
        - star_args
        - start_kwargs
        - args
        - type
        - error
        - auto_kind
        - has_preprocessor

    ScriptLang:
      type: string
      enum: [
          python3,
          deno,
          go,
          bash,
          powershell,
          postgresql,
          mysql,
          bigquery,
          snowflake,
          mssql,
          oracledb,
          graphql,
          nativets,
          bun,
          php,
          rust,
          ansible,
          csharp,
          nu,
          java,
          ruby,
          rlang,
          duckdb,
          bunnative,
          # for related places search: ADD_NEW_LANG
        ]

    ScriptModule:
      type: object
      description: "An additional module file associated with a script"
      properties:
        content:
          type: string
          description: "The source code content of this module"
        language:
          $ref: "#/components/schemas/ScriptLang"
        lock:
          type: string
          nullable: true
          description: "Lock file content for this module's dependencies"
      required:
        - content
        - language

    Preview:
      type: object
      properties:
        content:
          type: string
          description: The code to run
        path:
          type: string
          description: The path to the script
        script_hash:
          type: string
          description: The hash of the script
        args:
          $ref: "#/components/schemas/ScriptArgs"
        language:
          $ref: "#/components/schemas/ScriptLang"
        tag:
          type: string
        kind:
          type: string
          enum: [code, identity, http]
        dedicated_worker:
          type: boolean
        lock:
          type: string
        flow_path:
          type: string
        modules:
          type: object
          nullable: true
          description: "Additional script modules keyed by relative file path"
          additionalProperties:
            $ref: "#/components/schemas/ScriptModule"
        temp_script_refs:
          type: object
          nullable: true
          description: "Map of relative-import script path -> temp storage hash so the preview job resolves those imports from not-yet-deployed local content instead of the deployed script"
          additionalProperties:
            type: string
      required:
        - args

    PreviewInline:
      type: object
      properties:
        content:
          type: string
          description: The code to run
        args:
          $ref: "#/components/schemas/ScriptArgs"
        language:
          $ref: "#/components/schemas/ScriptLang"
      required: [content, args, language]

    InlineScriptArgs:
      type: object
      properties:
        args:
          $ref: "#/components/schemas/ScriptArgs"

    WorkflowTask:
      type: object
      properties:
        args:
          $ref: "#/components/schemas/ScriptArgs"
      required:
        - args

    WorkflowStatusRecord:
      type: object
      additionalProperties:
        $ref: "#/components/schemas/WorkflowStatus"

    WorkflowStatus:
      type: object
      properties:
        scheduled_for:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
        duration_ms:
          type: number
        name:
          type: string

    CreateResource:
      type: object
      properties:
        path:
          type: string
          description: The path to the resource
        value: {}
        description:
          type: string
          description: The description of the resource
        resource_type:
          type: string
          description: The resource_type associated with the resource
        labels:
          type: array
          items:
            type: string
        ws_specific:
          type: boolean
      required:
        - path
        - value
        - resource_type

    EditResource:
      type: object
      properties:
        path:
          type: string
          description: The path to the resource
        description:
          type: string
          description: The new description of the resource
        value: {}
        resource_type:
          type: string
          description: The new resource_type to be associated with the resource
        labels:
          type: array
          items:
            type: string
        ws_specific:
          type: boolean

    Resource:
      type: object
      properties:
        workspace_id:
          type: string
        path:
          type: string
        description:
          type: string
        resource_type:
          type: string
        value: {}
        is_oauth:
          type: boolean
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        created_by:
          type: string
        edited_at:
          type: string
          format: date-time
        labels:
          type: array
          items:
            type: string
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.
        ws_specific:
          type: boolean
      required:
        - path
        - resource_type
        - is_oauth

    ListableResource:
      type: object
      properties:
        workspace_id:
          type: string
        path:
          type: string
        description:
          type: string
        resource_type:
          type: string
        value: {}
        is_oauth:
          type: boolean
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        is_expired:
          type: boolean
        refresh_error:
          type: string
        is_linked:
          type: boolean
        is_refreshed:
          type: boolean
        account:
          type: number
        created_by:
          type: string
        edited_at:
          type: string
          format: date-time
        labels:
          type: array
          items:
            type: string
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.
        ws_specific:
          type: boolean
        draft_only:
          description: |
            True when this row is a per-user draft with no deployed
            resource at the same path. Frontend renders a "Draft" badge.
          type: boolean
        is_draft:
          description: |
            True when the authed user has a per-user draft at this path
            (over a deployed row or a synthesized draft-only row).
            Frontend appends a `*` to the displayed name.
          type: boolean
      required:
        - path
        - resource_type
        - is_oauth
        - is_linked
        - is_refreshed

    ResourceType:
      type: object
      properties:
        workspace_id:
          type: string
        name:
          type: string
        schema: {}
        description:
          type: string
        created_by:
          type: string
        edited_at:
          type: string
          format: date-time
        format_extension:
          type: string
        is_fileset:
          type: boolean
      required:
        - name

    EditResourceType:
      type: object
      properties:
        schema: {}
        description:
          type: string
        is_fileset:
          type: boolean

    Schedule:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this schedule. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`.
        edited_by:
          type: string
          description: Username of the last person who edited this schedule
        edited_at:
          type: string
          format: date-time
          description: Timestamp of the last edit
        schedule:
          type: string
          description: Cron expression with 6 fields (seconds, minutes, hours, day of month, month, day of week). Example '0 0 12 * * *' for daily at noon
        timezone:
          type: string
          description: IANA timezone for the schedule (e.g., 'UTC', 'Europe/Paris', 'America/New_York')
        enabled:
          type: boolean
          description: Whether the schedule is currently active and will trigger jobs
        script_path:
          type: string
          description: Path to the script or flow to execute when triggered
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        args:
          $ref: "#/components/schemas/ScriptArgs"
          nullable: true
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
          description: Additional permissions for this schedule
        email:
          type: string
          description: Email of the user who owns this schedule, used for permissioned_as
        permissioned_as:
          type: string
          description: The user or group this schedule runs as (e.g., 'u/admin' or 'g/mygroup')
        error:
          type: string
          nullable: true
          description: Last error message if the schedule failed to trigger
        on_failure:
          type: string
          nullable: true
          description: Path to a script or flow to run when the scheduled job fails
        on_failure_times:
          type: number
          nullable: true
          description: Number of consecutive failures before the on_failure handler is triggered (default 1)
        on_failure_exact:
          type: boolean
          nullable: true
          description: If true, trigger on_failure handler only on exactly N failures, not on every failure after N
        on_failure_extra_args:
          $ref: "#/components/schemas/ScriptArgs"
          nullable: true
        on_recovery:
          type: string
          nullable: true
          description: Path to a script or flow to run when the schedule recovers after failures
        on_recovery_times:
          type: number
          nullable: true
          description: Number of consecutive successes before the on_recovery handler is triggered (default 1)
        on_recovery_extra_args:
          $ref: "#/components/schemas/ScriptArgs"
          nullable: true
        on_success:
          type: string
          nullable: true
          description: Path to a script or flow to run after each successful execution
        on_success_extra_args:
          $ref: "#/components/schemas/ScriptArgs"
          nullable: true
        ws_error_handler_muted:
          type: boolean
          description: If true, the workspace-level error handler will not be triggered for this schedule's failures
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          nullable: true
        summary:
          type: string
          nullable: true
          description: Short summary describing the purpose of this schedule
        description:
          type: string
          nullable: true
          description: Detailed description of what this schedule does
        no_flow_overlap:
          type: boolean
          description: If true, skip this schedule's execution if the previous run is still in progress (prevents concurrent runs)
        tag:
          type: string
          nullable: true
          description: Worker tag to route jobs to specific worker groups
        paused_until:
          type: string
          format: date-time
          nullable: true
          description: ISO 8601 datetime until which the schedule is paused. Schedule resumes automatically after this time
        cron_version:
          type: string
          nullable: true
          description: Cron parser version. Use 'v2' for extended syntax with additional features
        dynamic_skip:
          type: string
          nullable: true
          description: Path to a script that validates scheduled datetimes. Receives scheduled_for datetime and returns boolean to skip (true) or run (false)
        labels:
          type: array
          items:
            type: string
          default: []
        draft_only:
          description: |
            True when this row is a per-user draft with no deployed
            schedule at the same path. Frontend renders a "Draft" badge.
          type: boolean
        is_draft:
          description: |
            True when the authed user has a per-user draft at this path
            (over a deployed row or a synthesized draft-only row).
            Frontend appends a `*` to the displayed name.
          type: boolean
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.
      required:
        - path
        - edited_by
        - edited_at
        - schedule
        - script_path
        - timezone
        - extra_perms
        - is_flow
        - enabled
        - email
        - permissioned_as


    ScheduleWJobs:
      allOf:
        - $ref: "#/components/schemas/Schedule"
        - type: object
          properties:
            jobs:
              type: array
              items:
                type: object
                properties:
                  id:
                    type: string
                  success:
                    type: boolean
                  duration_ms:
                    type: number
                required:
                  - id
                  - success
                  - duration_ms

    ErrorHandler:
      type: string
      enum:
        - custom
        - slack
        - teams
        - email

    NewSchedule:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this schedule. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`.
        schedule:
          type: string
          description: Cron expression with 6 fields (seconds, minutes, hours, day of month, month, day of week). Example '0 0 12 * * *' for daily at noon
        timezone:
          type: string
          description: IANA timezone for the schedule (e.g., 'UTC', 'Europe/Paris', 'America/New_York')
        script_path:
          type: string
          description: Path to the script or flow to execute when triggered
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        enabled:
          type: boolean
          description: Whether the schedule is currently active and will trigger jobs
        on_failure:
          type: string
          nullable: true
          description: Path to a script or flow to run when the scheduled job fails
        on_failure_times:
          type: number
          nullable: true
          description: Number of consecutive failures before the on_failure handler is triggered (default 1)
        on_failure_exact:
          type: boolean
          nullable: true
          description: If true, trigger on_failure handler only on exactly N failures, not on every failure after N
        on_failure_extra_args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        on_recovery:
          type: string
          nullable: true
          description: Path to a script or flow to run when the schedule recovers after failures
        on_recovery_times:
          type: number
          nullable: true
          description: Number of consecutive successes before the on_recovery handler is triggered (default 1)
        on_recovery_extra_args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        on_success:
          type: string
          nullable: true
          description: Path to a script or flow to run after each successful execution
        on_success_extra_args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        ws_error_handler_muted:
          type: boolean
          description: If true, the workspace-level error handler will not be triggered for this schedule's failures
        retry:
          nullable: true
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
        no_flow_overlap:
          type: boolean
          description: If true, skip this schedule's execution if the previous run is still in progress (prevents concurrent runs)
        summary:
          type: string
          nullable: true
          description: Short summary describing the purpose of this schedule
        description:
          type: string
          nullable: true
          description: Detailed description of what this schedule does
        tag:
          type: string
          nullable: true
          description: Worker tag to route jobs to specific worker groups
        paused_until:
          type: string
          nullable: true
          format: date-time
          description: ISO 8601 datetime until which the schedule is paused. Schedule resumes automatically after this time
        cron_version:
          type: string
          nullable: true
          description: Cron parser version. Use 'v2' for extended syntax with additional features
        dynamic_skip:
          type: string
          nullable: true
          description: Path to a script that validates scheduled datetimes. Receives scheduled_for datetime and returns boolean to skip (true) or run (false)
        permissioned_as:
          type: string
          description: The user or group this schedule runs as. Used during deployment to preserve the original schedule owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - schedule
        - timezone
        - script_path
        - is_flow
        - args

    EditSchedule:
      type: object
      properties:
        schedule:
          type: string
          description: Cron expression with 6 fields (seconds, minutes, hours, day of month, month, day of week). Example '0 0 12 * * *' for daily at noon
        timezone:
          type: string
          description: IANA timezone for the schedule (e.g., 'UTC', 'Europe/Paris', 'America/New_York')
        args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        on_failure:
          type: string
          nullable: true
          description: Path to a script or flow to run when the scheduled job fails
        on_failure_times:
          type: number
          nullable: true
          description: Number of consecutive failures before the on_failure handler is triggered (default 1)
        on_failure_exact:
          type: boolean
          nullable: true
          description: If true, trigger on_failure handler only on exactly N failures, not on every failure after N
        on_failure_extra_args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        on_recovery:
          type: string
          nullable: true
          description: Path to a script or flow to run when the schedule recovers after failures
        on_recovery_times:
          type: number
          nullable: true
          description: Number of consecutive successes before the on_recovery handler is triggered (default 1)
        on_recovery_extra_args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        on_success:
          type: string
          nullable: true
          description: Path to a script or flow to run after each successful execution
        on_success_extra_args:
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        ws_error_handler_muted:
          type: boolean
          description: If true, the workspace-level error handler will not be triggered for this schedule's failures
        retry:
          nullable: true
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
        no_flow_overlap:
          type: boolean
          description: If true, skip this schedule's execution if the previous run is still in progress (prevents concurrent runs)
        summary:
          type: string
          nullable: true
          description: Short summary describing the purpose of this schedule
        description:
          type: string
          nullable: true
          description: Detailed description of what this schedule does
        tag:
          type: string
          nullable: true
          description: Worker tag to route jobs to specific worker groups
        paused_until:
          type: string
          nullable: true
          format: date-time
          description: ISO 8601 datetime until which the schedule is paused. Schedule resumes automatically after this time
        cron_version:
          type: string
          nullable: true
          description: Cron parser version. Use 'v2' for extended syntax with additional features
        dynamic_skip:
          type: string
          nullable: true
          description: Path to a script that validates scheduled datetimes. Receives scheduled_for datetime and returns boolean to skip (true) or run (false)
        permissioned_as:
          type: string
          nullable: true
          description: "The user or group this schedule runs as (e.g., 'u/admin' or 'g/mygroup'). Only admins and wm_deployers can set this via preserve_permissioned_as."
        preserve_permissioned_as:
          type: boolean
          nullable: true
          description: "If true and user is admin/wm_deployers, preserve the provided permissioned_as instead of using the deploying user's identity"
        labels:
          type: array
          items:
            type: string
      required:
        - schedule
        - timezone
        - args

    JobTriggerKind:
      description: job trigger kind (schedule, http, websocket...)
      type: string
      enum:
        - webhook
        - default_email
        - email
        - schedule
        - http
        - websocket
        - postgres
        - kafka
        - nats
        - mqtt
        - amqp
        - sqs
        - gcp
        - azure
        - google
        - github
        - asset
        - freshness
        - app

    TriggerMode:
      description: job trigger mode
      type: string
      enum:
        - enabled
        - disabled
        - suspended

    TriggerExtraProperty:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when triggered
        permissioned_as:
          type: string
          description: The user or group this trigger runs as (permissioned_as)
        extra_perms:
          type: object
          description: Additional permissions for this trigger
          additionalProperties:
            type: boolean
        workspace_id:
          type: string
          description: The workspace this trigger belongs to
        edited_by:
          type: string
          description: Username of the last person who edited this trigger
        edited_at:
          type: string
          format: date-time
          description: Timestamp of the last edit
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
          description: Trigger mode (enabled/disabled)
        labels:
          type: array
          items:
            type: string
          default: []
        draft_only:
          description: |
            True when this row is a per-user draft with no deployed
            trigger at the same path. Set by list endpoints when
            `include_draft_only=true` synthesizes the row from the
            draft. Frontend renders a "Draft" badge.
          type: boolean
        is_draft:
          description: |
            True when the authed user has a per-user draft at this path
            (over a deployed row or a synthesized draft-only row).
            Frontend appends a `*` to the displayed name.
          type: boolean
      required:
        - path
        - script_path
        - permissioned_as
        - extra_perms
        - workspace_id
        - edited_by
        - edited_at
        - is_flow
        - mode


    AuthenticationMethod:
      type: string
      enum:
        - none
        - windmill
        - api_key
        - basic_http
        - custom_script
        - signature

    RunnableKind:
      type: string
      enum:
        - script
        - flow

    OpenapiSpecFormat:
      type: string
      enum:
        - yaml
        - json

    OpenapiHttpRouteFilters:
      type: object
      properties:
        folder_regex:
          type: string
        path_regex:
          type: string
        route_path_regex:
          type: string
      required:
        - folder_regex
        - path_regex
        - route_path_regex

    WebhookFilters:
      type: object
      properties:
        user_or_folder_regex:
          type: string
          enum:
            - "*"
            - u
            - f
        user_or_folder_regex_value:
          type: string
        path:
          type: string
        runnable_kind:
          $ref: "#/components/schemas/RunnableKind"
      required:
        - user_or_folder_regex
        - user_or_folder_regex_value
        - path
        - runnable_kind

    OpenapiV3Info:
      type: object
      properties:
        title:
          type: string
        version:
          type: string
        description:
          type: string
        terms_of_service:
          type: string
        contact:
          type: object
          properties:
            name:
              type: string
            url:
              type: string
            email:
              type: string
        license:
          type: object
          properties:
            name:
              type: string
            identifier:
              type: string
            url:
              type: string
          required:
            - name
      required:
        - title
        - version

    GenerateOpenapiSpec:
      type: object
      properties:
        info:
          $ref: "#/components/schemas/OpenapiV3Info"
        url:
          type: string
        openapi_spec_format:
          $ref: "#/components/schemas/OpenapiSpecFormat"
        http_route_filters:
          type: array
          items:
            $ref: "#/components/schemas/OpenapiHttpRouteFilters"
        webhook_filters:
          type: array
          items:
            $ref: "#/components/schemas/WebhookFilters"

    HttpMethod:
      type: string
      enum:
        - get
        - post
        - put
        - delete
        - patch

    HttpRequestType:
      type: string
      enum:
        - sync
        - async
        - sync_sse

    HttpTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        route_path:
          type: string
          description: The URL route path that will trigger this endpoint (e.g., 'api/myendpoint'). Must NOT start with a /.
        static_asset_config:
          type: object
          nullable: true
          description: Configuration for serving static assets (s3 bucket, storage path, filename)
          properties:
            s3:
              type: string
              description: S3 bucket path for static assets
            storage:
              type: string
              description: Storage path for static assets
            filename:
              type: string
              description: Filename for the static asset
          required:
            - s3
        http_method:
          $ref: "#/components/schemas/HttpMethod"
          description: HTTP method (get, post, put, delete, patch) that triggers this endpoint
        authentication_resource_path:
          type: string
          nullable: true
          description: Path to the resource containing authentication configuration (for api_key, basic_http, custom_script, signature methods)
        summary:
          type: string
          nullable: true
          description: Short summary describing the purpose of this trigger
        description:
          type: string
          nullable: true
          description: Detailed description of what this trigger does
        request_type:
          $ref: "#/components/schemas/HttpRequestType"
          description: "How the request is handled - 'sync' waits for result, 'async' returns job ID immediately, 'sync_sse' streams results via Server-Sent Events"
        authentication_method:
          $ref: "#/components/schemas/AuthenticationMethod"
          description: "How requests are authenticated - 'none' (public), 'windmill' (Windmill token), 'api_key', 'basic_http', 'custom_script', 'signature'"
        is_static_website:
          type: boolean
          description: If true, serves static files from S3/storage instead of running a script
        workspaced_route:
          type: boolean
          description: If true, the route includes the workspace ID in the path
        wrap_body:
          type: boolean
          description: If true, wraps the request body in a 'body' parameter
        raw_string:
          type: boolean
          description: If true, passes the request body as a raw string instead of parsing as JSON
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions

      required:
        - route_path
        - request_type
        - authentication_method
        - http_method
        - is_static_website
        - workspaced_route
        - wrap_body
        - raw_string

    NewHttpTrigger:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when triggered
        route_path:
          type: string
          description: The URL route path that will trigger this endpoint (e.g., 'api/myendpoint'). Must NOT start with a /.
        workspaced_route:
          type: boolean
          description: If true, the route includes the workspace ID in the path
        summary:
          type: string
          nullable: true
          description: Short summary describing the purpose of this trigger
        description:
          type: string
          nullable: true
          description: Detailed description of what this trigger does
        static_asset_config:
          type: object
          nullable: true
          description: Configuration for serving static assets (s3 bucket, storage path, filename)
          properties:
            s3:
              type: string
              description: S3 bucket path for static assets
            storage:
              type: string
              description: Storage path for static assets
            filename:
              type: string
              description: Filename for the static asset
          required:
            - s3
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        http_method:
          $ref: "#/components/schemas/HttpMethod"
          description: HTTP method (get, post, put, delete, patch) that triggers this endpoint
        authentication_resource_path:
          type: string
          nullable: true
          description: Path to the resource containing authentication configuration (for api_key, basic_http, custom_script, signature methods)
        is_async:
          type: boolean
          description: Deprecated, use request_type instead
        request_type:
          $ref: "#/components/schemas/HttpRequestType"
          description: "How the request is handled - 'sync' waits for result, 'async' returns job ID immediately, 'sync_sse' streams results via Server-Sent Events"
        authentication_method:
          $ref: "#/components/schemas/AuthenticationMethod"
          description: "How requests are authenticated - 'none' (public), 'windmill' (Windmill token), 'api_key', 'basic_http', 'custom_script', 'signature'"
        is_static_website:
          type: boolean
          description: If true, serves static files from S3/storage instead of running a script
        wrap_body:
          type: boolean
          description: If true, wraps the request body in a 'body' parameter
        mode:
          $ref: "#/components/schemas/TriggerMode"
        raw_string:
          type: boolean
          description: If true, passes the request body as a raw string instead of parsing as JSON
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string

      required:
        - path
        - script_path
        - route_path
        - is_flow
        - authentication_method
        - http_method
        - is_static_website

    EditHttpTrigger:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when triggered
        route_path:
          type: string
          description: The URL route path that will trigger this endpoint (e.g., 'api/myendpoint'). Must NOT start with a /.
        summary:
          type: string
          nullable: true
          description: Short summary describing the purpose of this trigger
        description:
          type: string
          nullable: true
          description: Detailed description of what this trigger does
        workspaced_route:
          type: boolean
          description: If true, the route includes the workspace ID in the path
        static_asset_config:
          type: object
          nullable: true
          description: Configuration for serving static assets (s3 bucket, storage path, filename)
          properties:
            s3:
              type: string
              description: S3 bucket path for static assets
            storage:
              type: string
              description: Storage path for static assets
            filename:
              type: string
              description: Filename for the static asset
          required:
            - s3
        authentication_resource_path:
          type: string
          nullable: true
          description: Path to the resource containing authentication configuration (for api_key, basic_http, custom_script, signature methods)
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        http_method:
          $ref: "#/components/schemas/HttpMethod"
          description: HTTP method (get, post, put, delete, patch) that triggers this endpoint
        is_async:
          type: boolean
          description: Deprecated, use request_type instead
        request_type:
          $ref: "#/components/schemas/HttpRequestType"
          description: "How the request is handled - 'sync' waits for result, 'async' returns job ID immediately, 'sync_sse' streams results via Server-Sent Events"
        authentication_method:
          $ref: "#/components/schemas/AuthenticationMethod"
          description: "How requests are authenticated - 'none' (public), 'windmill' (Windmill token), 'api_key', 'basic_http', 'custom_script', 'signature'"
        is_static_website:
          type: boolean
          description: If true, serves static files from S3/storage instead of running a script
        wrap_body:
          type: boolean
          description: If true, wraps the request body in a 'body' parameter
        raw_string:
          type: boolean
          description: If true, passes the request body as a raw string instead of parsing as JSON
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - kind
        - authentication_method
        - http_method
        - is_static_website

    TriggersCount:
      type: object
      properties:
        primary_schedule:
          type: object
          properties:
            schedule:
              type: string
        schedule_count:
          type: number
        http_routes_count:
          type: number
        webhook_count:
          type: number
        email_count:
          type: number
        default_email_count:
          type: number
        websocket_count:
          type: number
        postgres_count:
          type: number
        kafka_count:
          type: number
        nats_count:
          type: number
        mqtt_count:
          type: number
        amqp_count:
          type: number
        gcp_count:
          type: number
        azure_count:
          type: number
        sqs_count:
          type: number
        nextcloud_count:
          type: number
        google_count:
          type: number
        github_count:
          type: number

    WebsocketHeartbeat:
      type: object
      properties:
        interval_secs:
          type: integer
          minimum: 1
          description: Interval in seconds between heartbeat messages
        message:
          type: string
          description: >-
            Message to send as heartbeat. Use {{state}} as a placeholder
            for a value extracted from incoming messages (see state_field).
        state_field:
          type: string
          description: >-
            Optional. Top-level JSON field to extract from incoming messages.
            The extracted value replaces {{state}} in the heartbeat message.
      required:
        - interval_secs
        - message

    WebsocketTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        url:
          type: string
          description: The WebSocket URL to connect to (can be a static URL or computed by a runnable)
        server_id:
          type: string
          description: ID of the server currently handling this trigger (internal)
        last_server_ping:
          type: string
          format: date-time
          description: Timestamp of last server heartbeat (internal)
        error:
          type: string
          description: Last error message if the trigger failed
        filters:
          type: array
          description: Array of key-value filters to match incoming messages (only matching messages trigger the script)
          items:
            type: object
            properties:
              key:
                type: string
              value: {}
            required:
              - key
              - value
        filter_logic:
          type: string
          enum:
            - and
            - or
          default: and
          description: "Logic to apply when evaluating filters. 'and' requires all filters to match, 'or' requires any filter to match."
        initial_messages:
          type: array
          nullable: true
          description: Messages to send immediately after connecting (can be raw strings or computed by runnables)
          items:
            $ref: "#/components/schemas/WebsocketTriggerInitialMessage"
        url_runnable_args:
          description: Arguments to pass to the script/flow that computes the WebSocket URL
          $ref: "#/components/schemas/ScriptArgs"
          nullable: true
        can_return_message:
          type: boolean
          description: If true, the script can return a message to send back through the WebSocket
        can_return_error_result:
          type: boolean
          description: If true, error results are sent back through the WebSocket
        heartbeat:
          $ref: "#/components/schemas/WebsocketHeartbeat"
          nullable: true
          description: Optional periodic heartbeat message configuration
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          description: Arguments to pass to the error handler
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          description: Retry configuration for failed executions
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"

      required:
        - url
        - filters
        - can_return_message
        - can_return_error_result

    NewWebsocketTrigger:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        url:
          type: string
          description: The WebSocket URL to connect to (can be a static URL or computed by a runnable)
        mode:
          $ref: "#/components/schemas/TriggerMode"
        filters:
          type: array
          description: Array of key-value filters to match incoming messages (only matching messages trigger the script)
          items:
            type: object
            properties:
              key:
                type: string
              value: {}
            required:
              - key
              - value
        filter_logic:
          type: string
          enum:
            - and
            - or
          default: and
          description: "Logic to apply when evaluating filters. 'and' requires all filters to match, 'or' requires any filter to match."
        initial_messages:
          type: array
          nullable: true
          description: Messages to send immediately after connecting (can be raw strings or computed by runnables)
          items:
            $ref: "#/components/schemas/WebsocketTriggerInitialMessage"
        url_runnable_args:
          description: Arguments to pass to the script/flow that computes the WebSocket URL
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        can_return_message:
          type: boolean
          description: If true, the script can return a message to send back through the WebSocket
        can_return_error_result:
          type: boolean
          description: If true, error results are sent back through the WebSocket
        heartbeat:
          $ref: "#/components/schemas/WebsocketHeartbeat"
          nullable: true
          description: Optional periodic heartbeat message configuration
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          description: Arguments to pass to the error handler
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          description: Retry configuration for failed executions
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string

      required:
        - path
        - script_path
        - url
        - is_flow
        - filters
        - can_return_message
        - can_return_error_result

    EditWebsocketTrigger:
      type: object
      properties:
        url:
          type: string
          description: The WebSocket URL to connect to (can be a static URL or computed by a runnable)
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        filters:
          type: array
          description: Array of key-value filters to match incoming messages (only matching messages trigger the script)
          items:
            type: object
            properties:
              key:
                type: string
              value: {}
            required:
              - key
              - value
        filter_logic:
          type: string
          enum:
            - and
            - or
          default: and
          description: "Logic to apply when evaluating filters. 'and' requires all filters to match, 'or' requires any filter to match."
        initial_messages:
          type: array
          nullable: true
          description: Messages to send immediately after connecting (can be raw strings or computed by runnables)
          items:
            $ref: "#/components/schemas/WebsocketTriggerInitialMessage"
        url_runnable_args:
          description: Arguments to pass to the script/flow that computes the WebSocket URL
          nullable: true
          $ref: "#/components/schemas/ScriptArgs"
        can_return_message:
          type: boolean
          description: If true, the script can return a message to send back through the WebSocket
        can_return_error_result:
          type: boolean
          description: If true, error results are sent back through the WebSocket
        heartbeat:
          $ref: "#/components/schemas/WebsocketHeartbeat"
          nullable: true
          description: Optional periodic heartbeat message configuration
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          description: Arguments to pass to the error handler
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          description: Retry configuration for failed executions
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string

      required:
        - path
        - script_path
        - url
        - is_flow
        - filters
        - can_return_message
        - can_return_error_result
    WebsocketTriggerInitialMessage:
      anyOf:
        - type: object
          properties:
            raw_message:
              type: string
          required:
            - raw_message
        - type: object
          properties:
            runnable_result:
              type: object
              properties:
                path:
                  type: string
                args:
                  $ref: "#/components/schemas/ScriptArgs"
                is_flow:
                  type: boolean
              required:
                - path
                - args
                - is_flow
          required:
            - runnable_result

    MqttQoS:
      type: string
      enum: ["qos0", "qos1", "qos2"]

    MqttV3Config:
      type: object
      properties:
        clean_session:
          type: boolean

    MqttV5Config:
      type: object
      properties:
        clean_start:
          type: boolean
        topic_alias_maximum:
          type: number
        session_expiry_interval:
          type: number

    MqttSubscribeTopic:
      type: object
      properties:
        qos:
          $ref: "#/components/schemas/MqttQoS"
        topic:
          type: string
      required:
        - qos
        - topic

    MqttClientVersion:
      type: string
      enum: ["v3", "v5"]

    MqttTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        mqtt_resource_path:
          type: string
          description: Path to the MQTT resource containing broker connection configuration
        subscribe_topics:
          type: array
          items:
            $ref: "#/components/schemas/MqttSubscribeTopic"
          description: Array of MQTT topics to subscribe to, each with topic name and QoS level
        v3_config:
          $ref: "#/components/schemas/MqttV3Config"
          nullable: true
          description: MQTT v3 specific configuration (clean_session)
        v5_config:
          $ref: "#/components/schemas/MqttV5Config"
          nullable: true
          description: MQTT v5 specific configuration (clean_start, topic_alias_maximum, session_expiry_interval)
        client_id:
          type: string
          nullable: true
          description: MQTT client ID for this connection
        client_version:
          $ref: "#/components/schemas/MqttClientVersion"
          nullable: true
          description: MQTT protocol version ('v3' or 'v5')
        server_id:
          type: string
          description: ID of the server currently handling this trigger (internal)
        last_server_ping:
          type: string
          format: date-time
          description: Timestamp of last server heartbeat (internal)
        error:
          type: string
          description: Last error message if the trigger failed
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
      required:
        - subscribe_topics
        - mqtt_resource_path

    NewMqttTrigger:
      type: object
      properties:
        mqtt_resource_path:
          type: string
          description: Path to the MQTT resource containing broker connection configuration
        subscribe_topics:
          type: array
          items:
            $ref: "#/components/schemas/MqttSubscribeTopic"
          description: Array of MQTT topics to subscribe to, each with topic name and QoS level
        client_id:
          type: string
          nullable: true
          description: MQTT client ID for this connection
        v3_config:
          nullable: true
          $ref: "#/components/schemas/MqttV3Config"
          description: MQTT v3 specific configuration (clean_session)
        v5_config:
          nullable: true
          $ref: "#/components/schemas/MqttV5Config"
          description: MQTT v5 specific configuration (clean_start, topic_alias_maximum, session_expiry_interval)
        client_version:
          nullable: true
          $ref: "#/components/schemas/MqttClientVersion"
          description: MQTT protocol version ('v3' or 'v5')
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - subscribe_topics
        - mqtt_resource_path

    EditMqttTrigger:
      type: object
      properties:
        mqtt_resource_path:
          type: string
          description: Path to the MQTT resource containing broker connection configuration
        subscribe_topics:
          type: array
          items:
            $ref: "#/components/schemas/MqttSubscribeTopic"
          description: Array of MQTT topics to subscribe to, each with topic name and QoS level
        client_id:
          type: string
          nullable: true
          description: MQTT client ID for this connection
        v3_config:
          nullable: true
          $ref: "#/components/schemas/MqttV3Config"
          description: MQTT v3 specific configuration (clean_session)
        v5_config:
          nullable: true
          $ref: "#/components/schemas/MqttV5Config"
          description: MQTT v5 specific configuration (clean_start, topic_alias_maximum, session_expiry_interval)
        client_version:
          nullable: true
          $ref: "#/components/schemas/MqttClientVersion"
          description: MQTT protocol version ('v3' or 'v5')
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - enabled
        - subscribe_topics
        - mqtt_resource_path

    AmqpExchange:
      type: object
      properties:
        exchange_name:
          type: string
          description: Name of the exchange to bind the consumed queue to
        routing_keys:
          type: array
          items:
            type: string
          description: Routing keys used to bind the queue to the exchange
      required:
        - exchange_name

    AmqpOptions:
      type: object
      properties:
        declare_queue:
          type: boolean
          description: Declare the queue (durable) before consuming; when false the queue is declared passively and must already exist
        prefetch_count:
          type: integer
          format: int32
          minimum: 1
          maximum: 65535
          description: Maximum number of unacknowledged messages the broker delivers at once (1-65535)

    AmqpTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        amqp_resource_path:
          type: string
          description: Path to the AMQP resource containing broker connection configuration
        queue_name:
          type: string
          description: Name of the queue to consume messages from
        exchange:
          $ref: "#/components/schemas/AmqpExchange"
          nullable: true
          description: Optional exchange binding for the consumed queue
        options:
          $ref: "#/components/schemas/AmqpOptions"
          nullable: true
          description: Optional consumer options (queue declaration, prefetch)
        server_id:
          type: string
          description: ID of the server currently handling this trigger (internal)
        last_server_ping:
          type: string
          format: date-time
          description: Timestamp of last server heartbeat (internal)
        error:
          type: string
          description: Last error message if the trigger failed
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
      required:
        - amqp_resource_path
        - queue_name

    NewAmqpTrigger:
      type: object
      properties:
        amqp_resource_path:
          type: string
          description: Path to the AMQP resource containing broker connection configuration
        queue_name:
          type: string
          description: Name of the queue to consume messages from
        exchange:
          nullable: true
          $ref: "#/components/schemas/AmqpExchange"
          description: Optional exchange binding for the consumed queue
        options:
          nullable: true
          $ref: "#/components/schemas/AmqpOptions"
          description: Optional consumer options (queue declaration, prefetch)
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - amqp_resource_path
        - queue_name

    EditAmqpTrigger:
      type: object
      properties:
        amqp_resource_path:
          type: string
          description: Path to the AMQP resource containing broker connection configuration
        queue_name:
          type: string
          description: Name of the queue to consume messages from
        exchange:
          nullable: true
          $ref: "#/components/schemas/AmqpExchange"
          description: Optional exchange binding for the consumed queue
        options:
          nullable: true
          $ref: "#/components/schemas/AmqpOptions"
          description: Optional consumer options (queue declaration, prefetch)
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - amqp_resource_path
        - queue_name

    DeliveryType:
      type: string
      enum:
        - push
        - pull
      description: "Delivery mode for messages. 'push' for HTTP push delivery where messages are sent to a webhook endpoint, 'pull' for polling where the trigger actively fetches messages."

    PushConfig:
      type: object
      description: "Configuration for push delivery mode."
      properties:
        audience:
          type: string
          description: "The audience claim for OIDC tokens used in push authentication."
        authenticate:
          type: boolean
          description: "If true, push messages will include OIDC authentication tokens."
      required:
        - authenticate
        - base_endpoint

    GcpTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      description: "A Google Cloud Pub/Sub trigger that executes a script or flow when messages are received."
      properties:
        gcp_resource_path:
          type: string
          description: "Path to the GCP resource containing service account credentials for authentication."
        topic_id:
          type: string
          description: "Google Cloud Pub/Sub topic ID to subscribe to."
        subscription_id:
          type: string
          description: "Google Cloud Pub/Sub subscription ID."
        server_id:
          type: string
          description: "ID of the server currently handling this trigger (internal use)."
        delivery_type:
          $ref: "#/components/schemas/DeliveryType"
        delivery_config:
          $ref: "#/components/schemas/PushConfig"
          nullable: true
        subscription_mode:
          $ref: "#/components/schemas/SubscriptionMode"
        last_server_ping:
          type: string
          format: date-time
          description: "Timestamp of last server heartbeat (internal use)."
        error:
          type: string
          description: "Last error message if the trigger failed."
        error_handler_path:
          type: string
          description: "Path to a script or flow to run when the triggered job fails."
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: "Arguments to pass to the error handler."
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: "Retry configuration for failed executions."
      required:
        - gcp_resource_path
        - topic_id
        - subscription_id
        - delivery_type
        - subscription_mode

    SubscriptionMode:
      type: string
      enum:
        - existing
        - create_update
      description: "The mode of subscription. 'existing' means using an existing GCP subscription, while 'create_update' involves creating or updating a new subscription."

    GcpTriggerData:
      type: object
      description: "Data for creating or updating a Google Cloud Pub/Sub trigger."
      properties:
        gcp_resource_path:
          type: string
          description: "Path to the GCP resource containing service account credentials for authentication."
        subscription_mode:
          $ref: "#/components/schemas/SubscriptionMode"
        topic_id:
          type: string
          description: "Google Cloud Pub/Sub topic ID to subscribe to."
        subscription_id:
          type: string
          description: "Google Cloud Pub/Sub subscription ID."
        base_endpoint:
          type: string
          description: "Base URL for push delivery endpoint."
        delivery_type:
          $ref: "#/components/schemas/DeliveryType"
        delivery_config:
          nullable: true
          $ref: "#/components/schemas/PushConfig"
        path:
          type: string
          description: "The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path."
        script_path:
          type: string
          description: "Path to the script or flow to execute when a message is received."
        is_flow:
          type: boolean
          description: "True if script_path points to a flow, false if it points to a script."
        mode:
          $ref: "#/components/schemas/TriggerMode"
        auto_acknowledge_msg:
          type: boolean
          description: "If true, automatically acknowledge messages after processing."
        ack_deadline:
          type: integer
          format: int32
          minimum: 10
          maximum: 600
          description: "Time in seconds within which the message must be acknowledged. If not provided, defaults to the subscription's acknowledgment deadline (600 seconds)."
        error_handler_path:
          type: string
          description: "Path to a script or flow to run when the triggered job fails."
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: "Arguments to pass to the error handler."
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: "Retry configuration for failed executions."
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - gcp_resource_path
        - topic_id
        - subscription_mode

    GetAllTopicSubscription:
      type: object
      properties:
        topic_id:
          type: string
      required:
        - topic_id

    DeleteGcpSubscription:
      type: object
      properties:
        subscription_id:
          type: string
      required:
        - subscription_id

    AzureMode:
      type: string
      enum:
        - basic_push
        - namespace_push
        - namespace_pull
      description: "Azure Event Grid trigger mode."

    AzureArmResource:
      type: object
      description: "An ARM resource the service principal can see."
      properties:
        id:
          type: string
        name:
          type: string
        location:
          type: string
        type:
          type: string
      required:
        - id
        - name
        - type

    AzureDeleteSubscription:
      type: object
      properties:
        azure_mode:
          $ref: "#/components/schemas/AzureMode"
        scope_resource_id:
          type: string
        topic_name:
          type: string
          nullable: true
        subscription_name:
          type: string
      required:
        - azure_mode
        - scope_resource_id
        - subscription_name

    AzureTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      description: "An Azure Event Grid trigger that executes a script or flow when events arrive."
      properties:
        azure_resource_path:
          type: string
        azure_mode:
          $ref: "#/components/schemas/AzureMode"
        scope_resource_id:
          type: string
          description: "ARM resource ID of the topic (basic) or namespace (namespace modes)."
        topic_name:
          type: string
          nullable: true
          description: "Topic name within the namespace (namespace modes only)."
        subscription_name:
          type: string
        event_type_filters:
          type: array
          items:
            type: string
          nullable: true
        server_id:
          type: string
        last_server_ping:
          type: string
          format: date-time
        error:
          type: string
        error_handler_path:
          type: string
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
      required:
        - azure_resource_path
        - azure_mode
        - scope_resource_id
        - subscription_name

    AzureTriggerData:
      type: object
      description: "Data for creating or updating an Azure Event Grid trigger."
      properties:
        azure_resource_path:
          type: string
        azure_mode:
          $ref: "#/components/schemas/AzureMode"
        scope_resource_id:
          type: string
        topic_name:
          type: string
          nullable: true
        subscription_name:
          type: string
        base_endpoint:
          type: string
          description: "Base URL for push delivery endpoints (push modes only)."
        event_type_filters:
          type: array
          items:
            type: string
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
        is_flow:
          type: boolean
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
        permissioned_as:
          type: string
        preserve_permissioned_as:
          type: boolean
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - azure_resource_path
        - azure_mode
        - scope_resource_id
        - subscription_name

    TestAzureConnection:
      type: object
      properties:
        azure_resource_path:
          type: string
      required:
        - azure_resource_path

    AzureListTopics:
      type: object
      properties:
        scope_resource_id:
          type: string
      required:
        - scope_resource_id

    AzureListSubscriptions:
      type: object
      properties:
        scope_resource_id:
          type: string
        topic_name:
          type: string
      required:
        - scope_resource_id
        - topic_name

    AwsAuthResourceType:
      type: string
      enum:
        - oidc
        - credentials

    SqsTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        queue_url:
          type: string
          description: The full URL of the AWS SQS queue to poll for messages
        aws_auth_resource_type:
          $ref: "#/components/schemas/AwsAuthResourceType"
          description: Authentication type - 'credentials' for access key/secret, 'oidc' for OpenID Connect
        aws_resource_path:
          type: string
          description: Path to the AWS resource containing credentials or OIDC configuration
        message_attributes:
          type: array
          nullable: true
          items:
            type: string
          description: Array of SQS message attribute names to include with each message
        server_id:
          type: string
          description: ID of the server currently handling this trigger (internal)
        last_server_ping:
          type: string
          format: date-time
          description: Timestamp of last server heartbeat (internal)
        error:
          type: string
          description: Last error message if the trigger failed
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions

      required:
        - queue_url
        - aws_resource_path
        - aws_auth_resource_type

    LoggedWizardStatus:
      type: string
      enum:
        - OK
        - SKIP
        - FAIL

    CustomInstanceDbLogs:
      type: object
      properties:
        super_admin:
          $ref: "#/components/schemas/LoggedWizardStatus"
        database_credentials:
          $ref: "#/components/schemas/LoggedWizardStatus"
        valid_dbname:
          $ref: "#/components/schemas/LoggedWizardStatus"
        created_database:
          $ref: "#/components/schemas/LoggedWizardStatus"
        db_connect:
          $ref: "#/components/schemas/LoggedWizardStatus"
        grant_permissions:
          $ref: "#/components/schemas/LoggedWizardStatus"

    CustomInstanceDbTag:
      type: string
      enum:
        - ducklake
        - datatable

    CustomInstanceDb:
      type: object
      required:
        - logs
        - success
      properties:
        logs:
          $ref: "#/components/schemas/CustomInstanceDbLogs"
        success:
          type: boolean
          description: Whether the operation completed successfully
          example: true
        error:
          type: string
          nullable: true
          description: Error message if the operation failed
          example: "Connection timeout"
        tag:
          $ref: "#/components/schemas/CustomInstanceDbTag"
        used_by_workspaces:
          type: array
          items:
            type: string
          description: Workspaces that reference this database via a ducklake catalog or datatable database with resource_type 'instance'. Computed at request time, not persisted.

    NewSqsTrigger:
      type: object
      properties:
        queue_url:
          type: string
          description: The full URL of the AWS SQS queue to poll for messages
        aws_auth_resource_type:
          $ref: "#/components/schemas/AwsAuthResourceType"
          description: Authentication type - 'credentials' for access key/secret, 'oidc' for OpenID Connect
        aws_resource_path:
          type: string
          description: Path to the AWS resource containing credentials or OIDC configuration
        message_attributes:
          type: array
          nullable: true
          items:
            type: string
          description: Array of SQS message attribute names to include with each message
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - queue_url
        - aws_resource_path
        - path
        - script_path
        - is_flow
        - aws_auth_resource_type

    EditSqsTrigger:
      type: object
      properties:
        queue_url:
          type: string
          description: The full URL of the AWS SQS queue to poll for messages
        aws_auth_resource_type:
          $ref: "#/components/schemas/AwsAuthResourceType"
          description: Authentication type - 'credentials' for access key/secret, 'oidc' for OpenID Connect
        aws_resource_path:
          type: string
          description: Path to the AWS resource containing credentials or OIDC configuration
        message_attributes:
          type: array
          nullable: true
          items:
            type: string
          description: Array of SQS message attribute names to include with each message
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - queue_url
        - aws_resource_path
        - path
        - script_path
        - is_flow
        - enabled
        - aws_auth_resource_type

    Slot:
      type: object
      properties:
        name:
          type: string

    SlotList:
      type: object
      properties:
        slot_name:
          type: string
        active:
          type: boolean

    PublicationData:
      type: object
      properties:
        table_to_track:
          type: array
          items:
            $ref: "#/components/schemas/Relations"
        transaction_to_track:
          type: array
          items:
            type: string
      required:
        - transaction_to_track

    TableToTrack:
      type: array
      items:
        type: object
        properties:
          table_name:
            type: string
          columns_name:
            type: array
            items:
              type: string
          where_clause:
            type: string
        required:
          - table_name

    Relations:
      type: object
      properties:
        schema_name:
          type: string
        table_to_track:
          $ref: "#/components/schemas/TableToTrack"
      required:
        - schema_name
        - table_to_track

    Language:
      type: string
      enum:
        - Typescript

    TemplateScript:
      type: object
      properties:
        postgres_resource_path:
          type: string
        relations:
          type: array
          items:
            $ref: "#/components/schemas/Relations"
        language:
          $ref: "#/components/schemas/Language"
      required:
        - postgres_resource_path
        - relations
        - language

    PostgresTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        postgres_resource_path:
          type: string
          description: Path to the PostgreSQL resource containing connection configuration
        publication_name:
          type: string
          description: Name of the PostgreSQL publication to subscribe to for change data capture
        server_id:
          type: string
          description: ID of the server currently handling this trigger (internal)
        replication_slot_name:
          type: string
          description: Name of the PostgreSQL logical replication slot to use
        error:
          type: string
          description: Last error message if the trigger failed
        last_server_ping:
          type: string
          format: date-time
          description: Timestamp of last server heartbeat (internal)
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
      required:
        - postgres_resource_path
        - replication_slot_name
        - publication_name

    NewPostgresTrigger:
      type: object
      properties:
        replication_slot_name:
          type: string
          description: Name of the PostgreSQL logical replication slot to use
        publication_name:
          type: string
          description: Name of the PostgreSQL publication to subscribe to for change data capture
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when database changes are detected
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        postgres_resource_path:
          type: string
          description: Path to the PostgreSQL resource containing connection configuration
        publication:
          $ref: "#/components/schemas/PublicationData"
          description: Configuration for creating/managing the publication (tables, operations)
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - enabled
        - postgres_resource_path

    EditPostgresTrigger:
      type: object
      properties:
        replication_slot_name:
          type: string
          description: Name of the PostgreSQL logical replication slot to use
        publication_name:
          type: string
          description: Name of the PostgreSQL publication to subscribe to for change data capture
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when database changes are detected
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        mode:
          $ref: "#/components/schemas/TriggerMode"
        postgres_resource_path:
          type: string
          description: Path to the PostgreSQL resource containing connection configuration
        publication:
          $ref: "#/components/schemas/PublicationData"
          description: Configuration for creating/managing the publication (tables, operations)
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow
        - enabled
        - postgres_resource_path
        - publication_name
        - replication_slot_name

    KafkaTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        kafka_resource_path:
          type: string
          description: Path to the Kafka resource containing connection configuration
        group_id:
          type: string
          description: Kafka consumer group ID for this trigger
        topics:
          type: array
          items:
            type: string
          description: Array of Kafka topic names to subscribe to
        filters:
          type: array
          items:
            type: object
            properties:
              key:
                type: string
              value: {}
            required:
              - key
              - value
        filter_logic:
          type: string
          enum:
            - and
            - or
          default: and
          description: "Logic to apply when evaluating filters. 'and' requires all filters to match, 'or' requires any filter to match."
        auto_offset_reset:
          type: string
          enum:
            - latest
            - earliest
          default: latest
          description: "Initial offset behavior when consumer group has no committed offset. 'latest' starts from new messages only, 'earliest' starts from the beginning."
        auto_commit:
          type: boolean
          default: true
          description: "When true (default), offsets are committed automatically after receiving each message. When false, you must manually commit offsets using the commit_offsets endpoint."
        server_id:
          type: string
          description: ID of the server currently handling this trigger (internal)
        last_server_ping:
          type: string
          format: date-time
          description: Timestamp of last server heartbeat (internal)
        error:
          type: string
          description: Last error message if the trigger failed
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions

      required:
        - kafka_resource_path
        - group_id
        - topics
        - filters

    NewKafkaTrigger:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        kafka_resource_path:
          type: string
          description: Path to the Kafka resource containing connection configuration
        group_id:
          type: string
          description: Kafka consumer group ID for this trigger
        topics:
          type: array
          items:
            type: string
          description: Array of Kafka topic names to subscribe to
        filters:
          type: array
          items:
            type: object
            properties:
              key:
                type: string
              value: {}
            required:
              - key
              - value
        filter_logic:
          type: string
          enum:
            - and
            - or
          default: and
          description: "Logic to apply when evaluating filters. 'and' requires all filters to match, 'or' requires any filter to match."
        auto_offset_reset:
          type: string
          enum:
            - latest
            - earliest
          default: latest
          description: "Initial offset behavior when consumer group has no committed offset."
        auto_commit:
          type: boolean
          default: true
          description: "When true (default), offsets are committed automatically after receiving each message. When false, you must manually commit offsets using the commit_offsets endpoint."
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string

      required:
        - path
        - script_path
        - is_flow
        - kafka_resource_path
        - group_id
        - topics
        - filters

    EditKafkaTrigger:
      type: object
      properties:
        kafka_resource_path:
          type: string
          description: Path to the Kafka resource containing connection configuration
        group_id:
          type: string
          description: Kafka consumer group ID for this trigger
        topics:
          type: array
          items:
            type: string
          description: Array of Kafka topic names to subscribe to
        filters:
          type: array
          items:
            type: object
            properties:
              key:
                type: string
              value: {}
            required:
              - key
              - value
        filter_logic:
          type: string
          enum:
            - and
            - or
          default: and
          description: "Logic to apply when evaluating filters. 'and' requires all filters to match, 'or' requires any filter to match."
        auto_offset_reset:
          type: string
          enum:
            - latest
            - earliest
          default: latest
          description: "Initial offset behavior when consumer group has no committed offset."
        auto_commit:
          type: boolean
          default: true
          description: "When true (default), offsets are committed automatically after receiving each message. When false, you must manually commit offsets using the commit_offsets endpoint."
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string

      required:
        - path
        - script_path
        - kafka_resource_path
        - group_id
        - topics
        - filters
        - is_flow

    NatsTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        nats_resource_path:
          type: string
          description: Path to the NATS resource containing connection configuration
        use_jetstream:
          type: boolean
          description: If true, uses NATS JetStream for durable message delivery
        stream_name:
          type: string
          nullable: true
          description: JetStream stream name (required when use_jetstream is true)
        consumer_name:
          type: string
          nullable: true
          description: JetStream consumer name (required when use_jetstream is true)
        subjects:
          type: array
          items:
            type: string
          description: Array of NATS subjects to subscribe to
        server_id:
          type: string
          description: ID of the server currently handling this trigger (internal)
        last_server_ping:
          type: string
          format: date-time
          description: Timestamp of last server heartbeat (internal)
        error:
          type: string
          description: Last error message if the trigger failed
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions

      required:
        - nats_resource_path
        - use_jetstream
        - subjects

    NewNatsTrigger:
      type: object
      properties:
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        nats_resource_path:
          type: string
          description: Path to the NATS resource containing connection configuration
        use_jetstream:
          type: boolean
          description: If true, uses NATS JetStream for durable message delivery
        stream_name:
          type: string
          nullable: true
          description: JetStream stream name (required when use_jetstream is true)
        consumer_name:
          type: string
          nullable: true
          description: JetStream consumer name (required when use_jetstream is true)
        subjects:
          type: array
          items:
            type: string
          description: Array of NATS subjects to subscribe to
        mode:
          $ref: "#/components/schemas/TriggerMode"
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string

      required:
        - path
        - script_path
        - is_flow
        - nats_resource_path
        - use_jetstream
        - subjects

    EditNatsTrigger:
      type: object
      properties:
        nats_resource_path:
          type: string
          description: Path to the NATS resource containing connection configuration
        use_jetstream:
          type: boolean
          description: If true, uses NATS JetStream for durable message delivery
        stream_name:
          type: string
          nullable: true
          description: JetStream stream name (required when use_jetstream is true)
        consumer_name:
          type: string
          nullable: true
          description: JetStream consumer name (required when use_jetstream is true)
        subjects:
          type: array
          items:
            type: string
          description: Array of NATS subjects to subscribe to
        path:
          type: string
          description: The unique Windmill path for this trigger. Must be of the form `u/<user>/<path>` or `f/<folder>/<path>`. This is the trigger object path, not the HTTP route path.
        script_path:
          type: string
          description: Path to the script or flow to execute when a message is received
        is_flow:
          type: boolean
          description: True if script_path points to a flow, false if it points to a script
        error_handler_path:
          type: string
          description: Path to a script or flow to run when the triggered job fails
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
          description: Arguments to pass to the error handler
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
          description: Retry configuration for failed executions
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - nats_resource_path
        - use_jetstream
        - subjects
        - is_flow

    EmailTrigger:
      allOf:
        - $ref: "#/components/schemas/TriggerExtraProperty"
      type: object
      properties:
        local_part:
          type: string
        workspaced_local_part:
          type: boolean
        error_handler_path:
          type: string
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"

      required:
        - local_part

    NewEmailTrigger:
      type: object
      properties:
        path:
          type: string
        script_path:
          type: string
        local_part:
          type: string
        workspaced_local_part:
          type: boolean
        is_flow:
          type: boolean
        error_handler_path:
          type: string
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
        mode:
          $ref: "#/components/schemas/TriggerMode"
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string

      required:
        - path
        - script_path
        - local_part
        - is_flow

    EditEmailTrigger:
      type: object
      properties:
        path:
          type: string
        script_path:
          type: string
        local_part:
          type: string
        workspaced_local_part:
          type: boolean
        is_flow:
          type: boolean
        error_handler_path:
          type: string
        error_handler_args:
          $ref: "#/components/schemas/ScriptArgs"
        retry:
          $ref: "../../openflow.openapi.yaml#/components/schemas/Retry"
        permissioned_as:
          type: string
          description: The user or group this trigger runs as. Used during deployment to preserve the original trigger owner.
        preserve_permissioned_as:
          type: boolean
          description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
        labels:
          type: array
          items:
            type: string
      required:
        - path
        - script_path
        - is_flow

    Group:
      type: object
      properties:
        name:
          type: string
        summary:
          type: string
        members:
          type: array
          items:
            type: string
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
      required:
        - name

    InstanceGroup:
      type: object
      required:
        - name
      properties:
        name:
          type: string
        summary:
          type: string
        emails:
          type: array
          items:
            type: string
        instance_role:
          type: string
          nullable: true
          enum:
            - superadmin
            - devops

    InstanceGroupWithWorkspaces:
      type: object
      required:
        - name
      properties:
        name:
          type: string
        summary:
          type: string
        emails:
          type: array
          items:
            type: string
        instance_role:
          type: string
          nullable: true
          enum:
            - superadmin
            - devops
        workspaces:
          type: array
          items:
            $ref: "#/components/schemas/WorkspaceInfo"

    WorkspaceInfo:
      type: object
      properties:
        workspace_id:
          type: string
        workspace_name:
          type: string
        role:
          type: string
      required:
        - name

    Folder:
      type: object
      properties:
        name:
          type: string
        owners:
          type: array
          items:
            type: string
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        summary:
          type: string
        created_by:
          type: string
        edited_at:
          type: string
          format: date-time
        default_permissioned_as:
          $ref: '#/components/schemas/FolderDefaultPermissionedAs'
        labels:
          type: array
          items:
            type: string
          description: >
            Labels set on the folder. Items inside the folder inherit them,
            exposed as `inherited_labels` on scripts and flows and stamped
            into job labels at run time.
      required:
        - name
        - owners
        - extra_perms

    FolderDefaultPermissionedAs:
      description: >
        Ordered list of rules applied at create-time when admins or `wm_deployers`
        members deploy items in this folder. The first rule whose `path_glob`
        matches the item path (relative to the folder root) wins, and its
        `permissioned_as` is used as the default.
      type: array
      items:
        type: object
        required:
          - path_glob
          - permissioned_as
        properties:
          path_glob:
            type: string
            description: >
              Glob pattern evaluated against the item path *relative* to the
              folder root (e.g. "jobs/**" matches every item whose full path is
              `f/<folder>/jobs/...`). Supports `*`, `**`, `?`, `[abc]`, `{a,b}`.
          permissioned_as:
            type: string
            description: >
              Target identity the matched item should be permissioned as. Must be
              `u/<username>`, `g/<groupname>`, or an email that exists in this
              workspace.

    WorkerPing:
      type: object
      properties:
        worker:
          type: string
        worker_instance:
          type: string
        last_ping:
          type: number
        started_at:
          type: string
          format: date-time
        ip:
          type: string
        jobs_executed:
          type: integer
        custom_tags:
          type: array
          items:
            type: string
        worker_group:
          type: string
        wm_version:
          type: string
        last_job_id:
          type: string
        last_job_workspace_id:
          type: string
        occupancy_rate:
          type: number
        occupancy_rate_15s:
          type: number
        occupancy_rate_5m:
          type: number
        occupancy_rate_30m:
          type: number
        memory:
          type: number
        vcpus:
          type: number
        memory_usage:
          type: number
        wm_memory_usage:
          type: number
        job_isolation:
          type: string
        native_mode:
          type: boolean
      required:
        - worker
        - worker_instance
        - ping_at
        - started_at
        - ip
        - jobs_executed
        - worker_group
        - wm_version
    UserWorkspaceList:
      type: object
      properties:
        email:
          type: string
        workspaces:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              name:
                type: string
              username:
                type: string
              color:
                type: string
              operator_settings:
                $ref: "#/components/schemas/OperatorSettings"
              parent_workspace_id:
                type: string
                nullable: true
              is_dev_workspace:
                type: boolean
              dev_workspace_label:
                type: string
                nullable: true
                description: "Cosmetic display label of the dev workspace ('dev' | 'staging'); null defaults to 'dev'"
              created_by:
                type: string
                nullable: true
              disabled:
                type: boolean
            required:
              - id
              - name
              - username
              - color
              - is_dev_workspace
              - disabled
      required:
        - email
        - workspaces

    CreateWorkspace:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        username:
          type: string
        color:
          type: string
      required:
        - id
        - name

    CreateWorkspaceFork:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        color:
          type: string
        forked_datatables:
          type: array
          items:
            type: object
            required: [name, new_dbname]
            properties:
              name:
                type: string
                description: "Datatable name"
              new_dbname:
                type: string
                description: "New database name for the fork"
        shared_ducklakes:
          type: array
          items:
            type: string
          description: "Lake names the fork SHARES with the parent (reads and writes the parent's lake directly). Every lake not listed gets the default isolated fork namespace with read-defer to the parent."
        is_dev_workspace:
          type: boolean
          description: "Create the fork as a persistent dev workspace (id not required to carry the wm-fork- prefix; at most one per parent)"
        lock_prod_deploy:
          type: boolean
          description: "When creating a dev workspace, lock the parent (prod) against direct deployment"
        lock_prod_forking:
          type: boolean
          description: "When creating a dev workspace, prevent forking the parent (prod)"
        copy_members:
          type: boolean
          description: "Copy the parent's members (users + group memberships) into the fork so the team can work in it"
        dev_workspace_label:
          type: string
          enum: [dev, staging]
          description: "Cosmetic display label for the dev workspace (badge text + wording only); ignored for non-dev forks"
      required:
        - id
        - name
        - parent_workspace_id

    Workspace:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        owner:
          type: string
        domain:
          type: string
        color:
          type: string
        parent_workspace_id:
          type: string
          nullable: true
      required:
        - id
        - name
        - owner
        - created_at

    DependencyMap:
      type: object
      properties:
        workspace_id:
          type: string
          nullable: true
        importer_path:
          type: string
          nullable: true
        importer_kind:
          type: string
          nullable: true
        imported_path:
          type: string
          nullable: true
        importer_node_id:
          type: string
          nullable: true

    DependencyDependent:
      type: object
      properties:
        importer_path:
          type: string
        importer_kind:
          type: string
          enum:
            - script
            - flow
            - app
        importer_node_ids:
          type: array
          items:
            type: string
          nullable: true
      required:
        - importer_path
        - importer_kind

    DependentsAmount:
      type: object
      properties:
        imported_path:
          type: string
        count:
          type: integer
          format: int64
      required:
        - imported_path
        - count

    WorkspaceInvite:
      type: object
      properties:
        workspace_id:
          type: string
        email:
          type: string
        is_admin:
          type: boolean
        operator:
          type: boolean
        parent_workspace_id:
          type: string
          nullable: true
      required:
        - workspace_id
        - email
        - is_admin
        - operator

    GlobalUserInfo:
      type: object
      properties:
        email:
          type: string
        login_type:
          type: string
          enum: ["password", "github", "service_account"]
        super_admin:
          type: boolean
        devops:
          type: boolean
        verified:
          type: boolean
        name:
          type: string
        company:
          type: string
        username:
          type: string
        operator_only:
          type: boolean
        is_workspace_admin:
          type: boolean
          description: Populated only for service accounts. True if the service account has workspace admin in its (single) workspace.
        first_time_user:
          type: boolean
        role_source:
          type: string
          enum: ["manual", "instance_group", "service_account"]
        disabled:
          type: boolean
        workspace_id:
          type: string

      required:
        - email
        - login_type
        - super_admin
        - verified
        - first_time_user
        - role_source
        - disabled

    Flow:
      allOf:
        - $ref: "../../openflow.openapi.yaml#/components/schemas/OpenFlow"
        - $ref: "#/components/schemas/FlowMetadata"
        - type: object
          properties:
            lock_error_logs:
              type: string
            version_id:
              type: number

    ExtraPerms:
      type: object
      additionalProperties:
        type: boolean

    FlowMetadata:
      type: object
      properties:
        workspace_id:
          type: string
        path:
          type: string
        edited_by:
          type: string
        edited_at:
          type: string
          format: date-time
        archived:
          type: boolean
        extra_perms:
          $ref: "#/components/schemas/ExtraPerms"
        starred:
          type: boolean
        draft_only:
          type: boolean
        tag:
          type: string
        ws_error_handler_muted:
          type: boolean
        priority:
          type: integer
        dedicated_worker:
          type: boolean
        timeout:
          type: number
        visible_to_runner_only:
          type: boolean
        on_behalf_of_email:
          type: string
        labels:
          type: array
          items:
            type: string
          default: []
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.
      required:
        - path
        - edited_by
        - edited_at
        - archived
        - extra_perms


    OpenFlowWPath:
      allOf:
        - $ref: "../../openflow.openapi.yaml#/components/schemas/OpenFlow"
        - type: object
          properties:
            path:
              type: string
            tag:
              type: string
            ws_error_handler_muted:
              type: boolean
            priority:
              type: integer
            dedicated_worker:
              type: boolean
            timeout:
              type: number
            visible_to_runner_only:
              type: boolean
            on_behalf_of_email:
              type: string
            preserve_on_behalf_of:
              type: boolean
              description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original on_behalf_of_email value instead of overwriting it."
            labels:
              type: array
              items:
                type: string
          required:
            - path
    # Like OpenFlowWPath but `path` is optional: on update the flow is identified by
    # the URL, so the body path is only needed to rename it. Kept as a separate schema
    # (rather than making OpenFlowWPath.path optional) so createFlow still requires path.
    EditFlow:
      allOf:
        - $ref: "../../openflow.openapi.yaml#/components/schemas/OpenFlow"
        - type: object
          properties:
            path:
              type: string
            tag:
              type: string
            ws_error_handler_muted:
              type: boolean
            priority:
              type: integer
            dedicated_worker:
              type: boolean
            timeout:
              type: number
            visible_to_runner_only:
              type: boolean
            on_behalf_of_email:
              type: string
            preserve_on_behalf_of:
              type: boolean
              description: "When true and the caller is a member of the 'wm_deployers' group, preserves the original on_behalf_of_email value instead of overwriting it."
            labels:
              type: array
              items:
                type: string

    FlowPreview:
      type: object
      properties:
        value:
          $ref: "../../openflow.openapi.yaml#/components/schemas/FlowValue"
        path:
          type: string
        args:
          $ref: "#/components/schemas/ScriptArgs"
        tag:
          type: string
        restarted_from:
          $ref: "#/components/schemas/RestartedFrom"
        temp_script_refs:
          type: object
          nullable: true
          description: "Map of relative-import script path -> temp storage hash, propagated to each flow step so inline-script relative imports resolve from not-yet-deployed local content instead of the deployed script"
          additionalProperties:
            type: string

      required:
        - value
        - content
        - args

    RestartedFrom:
      type: object
      properties:
        flow_job_id:
          type: string
          format: uuid
        step_id:
          type: string
        branch_or_iteration_n:
          type: integer
          description: 0-based iteration index for ForLoop / branch index for BranchAll. Iterations 0..n-1 are preserved; iteration n is restarted.
        flow_version:
          type: integer
        branch_chosen:
          description: For BranchOne nested restart — the branch that was originally chosen, used to lock branch evaluation.
          type: object
          properties:
            type:
              type: string
              enum: [default, branch]
            branch:
              type: integer
        nested:
          $ref: "#/components/schemas/RestartedFrom"
          description: When set, the worker spawns the child for `step_id` as a `RestartedFlow` against `nested.flow_job_id` instead of fresh-launching it.

    Policy:
      type: object
      properties:
        triggerables:
          type: object
          additionalProperties:
            type: object
        triggerables_v2:
          type: object
          additionalProperties:
            type: object
        s3_inputs:
          type: array
          items:
            type: object
        allowed_s3_keys:
          type: array
          items:
            type: object
            properties:
              s3_path:
                type: string
              resource:
                type: string
        execution_mode:
          type: string
          enum: [viewer, publisher, anonymous]
        on_behalf_of:
          type: string
        on_behalf_of_email:
          type: string
        sandbox:
          type: boolean
          description: >
            Publisher opt-in to app sandbox isolation (alpha). When true the app
            is isolated from each viewer's Windmill session. When false/absent
            the app runs same-origin with the viewer's full session (the
            default, pre-isolation behavior).

    ListableApp:
      type: object
      properties:
        id:
          type: integer
        workspace_id:
          type: string
        path:
          type: string
        summary:
          type: string
        version:
          type: integer
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        starred:
          type: boolean
        edited_at:
          type: string
          format: date-time
        execution_mode:
          type: string
          enum: [viewer, publisher, anonymous]
        raw_app:
          type: boolean
        labels:
          type: array
          items:
            type: string
          default: []
        is_draft:
          type: boolean
          description: |
            True when the authed user has a draft for this app — either no
            deployed row exists at this path (draft-only) or the user has
            saved a per-user draft on top of the deployed row.
        draft_path:
          type: string
          description: |
            User-typed path the editor has staged but not yet deployed.
            Sourced from the draft JSON's `draft_path` field (the editor
            only writes it when the typed path differs from the deployed
            one). Lets the home list render the meaningful name instead of
            the autogenerated `u/{user}/draft_{uuid}` URL path. Omitted
            when unchanged.
        draft_users:
          description: |
            Workspace users (including the authed user, and the legacy
            NULL-email row if any) who have a per-user draft at this
            path. Drives the home page's user-avatar circles inside the
            Draft badge. Omitted when no drafts exist.
          type: array
          items:
            type: object
            properties:
              username:
                type: string
                nullable: true
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.
      required:
        - id
        - workspace_id
        - path
        - summary
        - version
        - extra_perms
        - edited_at
        - execution_mode


    ScopeDefinition:
      type: object
      properties:
        value:
          type: string
        label:
          type: string
        description:
          type: string
          nullable: true
        requires_resource_path:
          type: boolean
      required:
        - value
        - label
        - requires_resource_path

    ScopeDomain:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
          nullable: true
        scopes:
          type: array
          items:
            $ref: "#/components/schemas/ScopeDefinition"
      required:
        - name
        - scopes

    ListableRawApp:
      type: object
      properties:
        workspace_id:
          type: string
        path:
          type: string
        summary:
          type: string
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        starred:
          type: boolean
        version:
          type: number
        edited_at:
          type: string
          format: date-time
        labels:
          type: array
          items:
            type: string
          default: []
        inherited_labels:
          type: array
          items:
            type: string
          description: >
            Labels inherited from the parent folder, computed at read time.
            Read-only — edit them on the folder.
      required:
        - workspace_id
        - path
        - summary
        - extra_perms
        - version
        - edited_at


    AppWithLastVersion:
      type: object
      properties:
        id:
          type: integer
        workspace_id:
          type: string
        path:
          type: string
        summary:
          type: string
        versions:
          type: array
          items:
            type: integer
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        value: {}
        policy:
          $ref: "#/components/schemas/Policy"
        execution_mode:
          type: string
          enum: [viewer, publisher, anonymous]
        extra_perms:
          type: object
          additionalProperties:
            type: boolean
        custom_path:
          type: string
        raw_app:
          type: boolean
        bundle_secret:
          type: string
        labels:
          type: array
          items:
            type: string
          default: []
      required:
        - id
        - workspace_id
        - path
        - summary
        - versions
        - created_by
        - created_at
        - value
        - policy
        - execution_mode
        - extra_perms
        - raw_app


    AppHistory:
      type: object
      properties:
        version:
          type: integer
        deployment_msg:
          type: string
      required:
        - version

    EmbedTokenResponse:
      type: object
      properties:
        token:
          type: string
          nullable: true
          description: Narrowly-scoped embed token for the iframe. Absent for fully anonymous or raw apps, which load without a scoped token.
        expiration:
          type: string
          format: date-time
          nullable: true
          description: Expiration of the embed token.
        raw_app:
          type: boolean
          description: Raw apps render single-iframe and skip the opaque-viewer indirection and the embed token entirely.
        sandbox:
          type: boolean
          description: Publisher opted this app into sandbox isolation. When false the viewer runs the app same-origin with its full session.
        app_path:
          type: string
          nullable: true
          description: The resolved app path; the embedder uses it to scope the app's backing localStorage per app.
        workspace_id:
          type: string
          nullable: true
          description: The resolved workspace; pairs with app_path so apps at the same path in different workspaces don't share a localStorage store.
      required:
        - raw_app
        - sandbox

    FlowVersion:
      type: object
      properties:
        id:
          type: integer
        created_at:
          type: string
          format: date-time
        deployment_msg:
          type: string
      required:
        - id
        - created_at

    SlackToken:
      type: object
      properties:
        access_token:
          type: string
        team:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
          required:
            - id
            - name
      required:
        - access_token

    TokenResponse:
      type: object
      properties:
        access_token:
          type: string
        expires_in:
          type: integer
        refresh_token:
          type: string
        scope:
          type: array
          items:
            type: string
        grant_type:
          type: string

      required:
        - access_token

    HubScriptKind:
      type: string
      enum: [script, failure, trigger, approval]

    PolarsClientKwargs:
      type: object
      properties:
        region_name:
          type: string
      required:
        - region_name

    LargeFileStorage:
      type: object
      properties:
        type:
          type: string
          enum:
            [
              "S3Storage",
              "AzureBlobStorage",
              "AzureWorkloadIdentity",
              "S3AwsOidc",
              "GoogleCloudStorage",
            ]
        s3_resource_path:
          type: string
        azure_blob_resource_path:
          type: string
        gcs_resource_path:
          type: string
        public_resource:
          type: boolean
        advanced_permissions:
          type: array
          items:
            $ref: "#/components/schemas/S3PermissionRule"
        secondary_storage:
          type: object
          additionalProperties:
            type: object
            properties:
              type:
                type: string
                enum:
                  [
                    "S3Storage",
                    "AzureBlobStorage",
                    "AzureWorkloadIdentity",
                    "S3AwsOidc",
                    "GoogleCloudStorage",
                  ]
              s3_resource_path:
                type: string
              azure_blob_resource_path:
                type: string
              gcs_resource_path:
                type: string
              public_resource:
                type: boolean

    DucklakeSettings:
      type: object
      required: [ducklakes]
      properties:
        ducklakes:
          type: object
          additionalProperties:
            type: object
            required: [catalog, storage]
            properties:
              catalog:
                type: object
                properties:
                  resource_type:
                    type: string
                    enum:
                      - postgresql
                      - mysql
                      - instance
                  resource_path:
                    type: string
                required:
                  - resource_type
              storage:
                type: object
                properties:
                  storage:
                    type: string
                  path:
                    type: string
                required:
                  - path
              extra_args:
                type: string
              fork_behavior:
                type: string
                enum: [isolated, shared]
                description:
                  Fork workspaces only - how this lake behaves in the fork, stamped at fork
                  creation. Absent = isolated (fork-scoped namespace + read-defer to parent).
              maintenance:
                type: object
                description:
                  Scheduled maintenance (enterprise) - snapshot expiry, adjacent-file
                  compaction and orphaned-file cleanup, run as a managed per-lake schedule
                required: [enabled]
                properties:
                  enabled:
                    type: boolean
                  schedule:
                    type: string
                    description: cron cadence (v2, UTC); defaults to daily at 03h with a per-lake minute offset
                  retention_days:
                    type: integer
                    description: snapshot retention window in days (default 7); time-travel older than this stops working
                  compaction:
                    type: boolean
                    description: merge adjacent small parquet files (default true)
                  orphan_cleanup:
                    type: boolean
                    description: delete orphaned files older than max(retention, 1 day) (default true)

    DataTableSettings:
      type: object
      required: [datatables]
      properties:
        datatables:
          type: object
          additionalProperties:
            type: object
            required: [database]
            properties:
              database:
                type: object
                properties:
                  resource_type:
                    type: string
                    enum:
                      - postgresql
                      - instance
                  resource_path:
                    type: string
                required:
                  - resource_type
              migrations_enabled:
                type: boolean
                description: Whether the SQL migrations feature is opted in for this data table
              forked_from:
                type: object
                description: Fork origin info with schema snapshot
                properties:
                  schema:
                    type: object
                    description: Schema snapshot at fork time
                    additionalProperties: true
    DatatableMigration:
      type: object
      required: [datatable, timestamp, name, code_up]
      properties:
        datatable:
          type: string
        timestamp:
          type: integer
          format: int64
        name:
          type: string
        code_up:
          type: string
        code_down:
          type: string
    DatatableMigrationWithStatus:
      type: object
      required: [timestamp, name, code_up, status]
      properties:
        timestamp:
          type: integer
          format: int64
        name:
          type: string
        code_up:
          type: string
        code_down:
          type: string
        status:
          type: string
          enum:
            - ran
            - not_run
            - unknown
    DataTableSchema:
      type: object
      required: [datatable_name, schemas]
      properties:
        datatable_name:
          type: string
        schemas:
          type: object
          description: "Hierarchical schema: schema_name -> table_name -> column_name -> compact_type (e.g. 'int4', 'text?', 'int4?=0')"
          additionalProperties:
            type: object
            description: "Tables in this schema"
            additionalProperties:
              type: object
              description: "Columns in this table"
              additionalProperties:
                type: string
                description: "Compact type: 'type[?][=default]' where ? means nullable"
        error:
          type: string

    DataTableTables:
      type: object
      required: [datatable_name, schemas]
      properties:
        datatable_name:
          type: string
        schemas:
          type: object
          description: "Hierarchical metadata: schema_name -> table_names"
          additionalProperties:
            type: array
            items:
              type: string
        error:
          type: string

    DataTableTableSchema:
      type: object
      required: [datatable_name, schema_name, table_name, columns]
      properties:
        datatable_name:
          type: string
        schema_name:
          type: string
        table_name:
          type: string
        columns:
          type: object
          description: "Columns in this table: column_name -> compact_type"
          additionalProperties:
            type: string
            description: "Compact type: 'type[?][=default]' where ? means nullable"

    DynamicInputData:
      type: object
      properties:
        entrypoint_function:
          type: string
          description: Name of the function to execute for dynamic select
        args:
          type: object
          description: Arguments to pass to the function
        runnable_ref:
          type: object
          oneOf:
            - type: object
              properties:
                source:
                  type: string
                  enum: [deployed]
                path:
                  type: string
                  description: Path to the deployed script or flow
                runnable_kind:
                  $ref: "#/components/schemas/RunnableKind"
              required:
                - source
                - path
                - runnable_kind
            - type: object
              properties:
                source:
                  type: string
                  enum: [inline]
                code:
                  type: string
                  description: Code content for inline execution
                language:
                  $ref: "#/components/schemas/ScriptLang"
              required:
                - source
                - code
      required:
        - entrypoint_function
        - runnable_ref

    WindmillLargeFile:
      type: object
      properties:
        s3:
          type: string
      required:
        - s3

    WindmillFileMetadata:
      type: object
      properties:
        mime_type:
          type: string
        size_in_bytes:
          type: integer
        last_modified:
          type: string
          format: date-time
        expires:
          type: string
          format: date-time
        version_id:
          type: string

    WindmillFilePreview:
      type: object
      properties:
        msg:
          type: string
        content:
          type: string
        content_type:
          type: string
          enum: ["RawText", "Csv", "Parquet", "Unknown"]
      required:
        - content_type

    S3Resource:
      type: object
      properties:
        bucket:
          type: string
        region:
          type: string
        endPoint:
          type: string
        useSSL:
          type: boolean
        accessKey:
          type: string
        secretKey:
          type: string
        pathStyle:
          type: boolean
      required:
        - bucket
        - region
        - endPoint
        - useSSL
        - pathStyle

    WorkspaceGitSyncSettings:
      type: object
      properties:
        repositories:
          type: array
          items:
            $ref: "#/components/schemas/GitRepositorySettings"

    WorkspaceDeployUISettings:
      type: object
      properties:
        include_path:
          type: array
          items:
            type: string
        include_type:
          type: array
          items:
            $ref: "#/components/schemas/GitSyncObjectType"

    WorkspaceDefaultScripts:
      type: object
      properties:
        order:
          type: array
          items:
            type: string
        hidden:
          type: array
          items:
            type: string
        default_script_content:
          additionalProperties:
            type: string

    S3PermissionRule:
      type: object
      properties:
        pattern:
          type: string
        allow:
          type: string # comma separated permissions : "read,write,delete,list"
      required: ["pattern", "allow"]

    GitRepositorySettings:
      type: object
      properties:
        script_path:
          type: string
        git_repo_resource_path:
          type: string
        use_individual_branch:
          type: boolean
        group_by_folder:
          type: boolean
        collapsed:
          type: boolean
        settings:
          type: object
          properties:
            include_path:
              type: array
              items:
                type: string
            include_type:
              type: array
              items:
                $ref: "#/components/schemas/GitSyncObjectType"
            exclude_path:
              type: array
              items:
                type: string
            extra_include_path:
              type: array
              items:
                type: string
        exclude_types_override:
          type: array
          items:
            $ref: "#/components/schemas/GitSyncObjectType"
        auto_pull:
          $ref: "#/components/schemas/AutoPullSettings"
        promotion_open_prs:
          type: boolean
        fork_open_prs:
          type: boolean
        open_pr_error:
          type: string
          description: server-owned, last failure opening a PR for a deploy branch of this repo
      required:
        - git_repo_resource_path

    AutoPullMode:
      type: string
      enum:
        - auto
        - webhook
        - polling

    AutoPullStatus:
      type: object
      properties:
        synced_sha:
          type: string
        at:
          type: integer
          format: int64
        job_id:
          type: string
          format: uuid
        success:
          type: boolean
        error:
          type: string
      required:
        - at
        - success

    AutoPullSettings:
      type: object
      properties:
        enabled:
          type: boolean
        mode:
          $ref: "#/components/schemas/AutoPullMode"
        poll_interval_s:
          type: integer
        sync_forks:
          type: boolean
        webhook_id:
          type: integer
          format: int64
        webhook_secret:
          type: string
        webhook_error:
          type: string
        last_synced_sha:
          type: object
          additionalProperties:
            type: string
        last_pull_status:
          $ref: "#/components/schemas/AutoPullStatus"
      required:
        - enabled

    MetricMetadata:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id

    ScalarMetric:
      type: object
      properties:
        metric_id:
          type: string
        value:
          type: number
      required:
        - id
        - value

    TimeseriesMetric:
      type: object
      properties:
        metric_id:
          type: string
        values:
          type: array
          items:
            $ref: "#/components/schemas/MetricDataPoint"
      required:
        - id
        - values

    MetricDataPoint:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        value:
          type: number
      required:
        - timestamp
        - value

    RawScriptForDependencies:
      type: object
      properties:
        raw_code:
          type: string
        path:
          type: string
        language:
          $ref: "#/components/schemas/ScriptLang"
      required:
        - raw_code
        - path
        - language

    ConcurrencyGroup:
      type: object
      properties:
        concurrency_key:
          type: string
        total_running:
          type: number
      required:
        - concurrency_key
        - total_running

    ExtendedJobs:
      type: object
      properties:
        jobs:
          type: array
          items:
            $ref: "#/components/schemas/Job"
        obscured_jobs:
          type: array
          items:
            $ref: "#/components/schemas/ObscuredJob"
        omitted_obscured_jobs:
          description: "Obscured jobs omitted for security because of too specific filtering"
          type: boolean
      required:
        - jobs
        - obscured_jobs

    ExportedUser:
      type: object
      properties:
        email:
          type: string
        password_hash:
          type: string
        super_admin:
          type: boolean
        verified:
          type: boolean
        name:
          type: string
        company:
          type: string
        first_time_user:
          type: boolean
        username:
          type: string
      required:
        - email
        - super_admin
        - verified
        - first_time_user

    GlobalSetting:
      type: object
      properties:
        name:
          type: string
        value: {}
      required:
        - name
        - value

    InstanceConfig:
      type: object
      description: Unified instance configuration combining global settings and worker group configs
      properties:
        global_settings:
          type: object
          description: >
            Global settings keyed by setting name. Known fields include base_url,
            license_key, retention_period_secs, smtp_settings, otel, etc.
            Unknown fields are preserved as-is.
          additionalProperties: true
        worker_configs:
          type: object
          description: >
            Worker group configurations keyed by group name (e.g. "default", "gpu").
            Each value contains worker_tags, init_bash, autoscaling, etc.
          additionalProperties:
            type: object
            additionalProperties: true

    Config:
      type: object
      properties:
        name:
          type: string
        config:
          type: object
      required:
        - name

    ExportedInstanceGroup:
      type: object
      properties:
        name:
          type: string
        summary:
          type: string
        emails:
          type: array
          items:
            type: string
        id:
          type: string
        scim_display_name:
          type: string
        external_id:
          type: string
        instance_role:
          type: string
          nullable: true
          enum:
            - superadmin
            - devops
      required:
        - name

    JobSearchHit:
      type: object
      properties:
        dancer:
          type: string

    LogSearchHit:
      type: object
      properties:
        dancer:
          type: string

    AutoscalingEvent:
      type: object
      properties:
        id:
          type: integer
          format: int64
        worker_group:
          type: string
        event_type:
          type: string
        desired_workers:
          type: integer
        reason:
          type: string
        applied_at:
          type: string
          format: date-time

    CriticalAlert:
      type: object
      properties:
        id:
          type: integer
          description: Unique identifier for the alert
        alert_type:
          type: string
          description: Type of alert (e.g., critical_error)
        message:
          type: string
          description: The message content of the alert
        created_at:
          type: string
          format: date-time
          description: Time when the alert was created
        acknowledged:
          type: boolean
          nullable: true
          description: Acknowledgment status of the alert, can be true, false, or null if not set
        workspace_id:
          type: string
          nullable: true
          description: Workspace id if the alert is in the scope of a workspace

    CaptureTriggerKind:
      type: string
      enum:
        [
          webhook,
          http,
          websocket,
          kafka,
          default_email,
          nats,
          postgres,
          sqs,
          mqtt,
          amqp,
          gcp,
          azure,
          email,
        ]

    Capture:
      type: object
      properties:
        trigger_kind:
          $ref: "#/components/schemas/CaptureTriggerKind"
        main_args: {}
        preprocessor_args: {}
        id:
          type: integer
        created_at:
          type: string
          format: date-time
      required:
        - trigger_kind
        - main_args
        - preprocessor_args
        - id
        - created_at
    CaptureConfig:
      type: object
      properties:
        trigger_config: {}
        trigger_kind:
          $ref: "#/components/schemas/CaptureTriggerKind"
        error:
          type: string
        last_server_ping:
          type: string
          format: date-time
      required:
        - trigger_kind

    OperatorSettings:
      nullable: true
      type: object
      required:
        - runs
        - schedules
        - resources
        - assets
        - variables
        - triggers
        - audit_logs
        - groups
        - folders
        - workers
      properties:
        runs:
          type: boolean
          description: Whether operators can view runs
        schedules:
          type: boolean
          description: Whether operators can view schedules
        resources:
          type: boolean
          description: Whether operators can view resources
        variables:
          type: boolean
          description: Whether operators can view variables
        assets:
          type: boolean
          description: Whether operators can view assets
        audit_logs:
          type: boolean
          description: Whether operators can view audit logs
        triggers:
          type: boolean
          description: Whether operators can view triggers
        groups:
          type: boolean
          description: Whether operators can view groups page
        folders:
          type: boolean
          description: Whether operators can view folders page
        workers:
          type: boolean
          description: Whether operators can view workers page

    WorkspaceComparison:
      type: object
      required:
        - all_ahead_items_visible
        - all_behind_items_visible
        - skipped_comparison
        - diffs
        - summary
        - hidden_ahead
        - hidden_behind
      properties:
        all_ahead_items_visible:
          type: boolean
          description: All items with changes ahead are visible by the user of the request.
        all_behind_items_visible:
          type: boolean
          description: All items with changes behind are visible by the user of the request.
        skipped_comparison:
          type: boolean
          description: Whether the comparison was skipped. This happens with old forks that where not being kept track of
        diffs:
          type: array
          description: List of differences found between workspaces
          items:
            $ref: "#/components/schemas/WorkspaceItemDiff"
        summary:
          $ref: "#/components/schemas/CompareSummary"
          description: Summary statistics of the comparison
        hidden_ahead:
          $ref: "#/components/schemas/HiddenItemsSummary"
          description: Ahead items excluded from `diffs` because they are not visible to the caller
        hidden_behind:
          $ref: "#/components/schemas/HiddenItemsSummary"
          description: Behind items excluded from `diffs` because they are not visible to the caller

    HiddenItemsSummary:
      type: object
      required:
        - total
        - by_kind
        - items
      properties:
        total:
          type: integer
          description: Total number of hidden items on this side
        by_kind:
          type: object
          additionalProperties:
            type: integer
          description: Count of hidden items keyed by item kind (always populated)
        items:
          type: array
          description: Kind and path of each hidden item; only populated when the caller is an admin of the relevant side (empty otherwise)
          items:
            $ref: "#/components/schemas/HiddenItem"

    HiddenItem:
      type: object
      required:
        - kind
        - path
      properties:
        kind:
          type: string
          description: Type of the hidden item
        path:
          type: string
          description: Path of the hidden item

    WorkspaceItemDiff:
      type: object
      required:
        - kind
        - path
        - ahead
        - behind
        - has_changes
        - exists_in_source
        - exists_in_fork
      properties:
        kind:
          type: string
          enum:
            [
              "script",
              "flow",
              "app",
              "raw_app",
              "resource",
              "variable",
              "resource_type",
              "folder",
              "schedule",
              "http_trigger",
              "websocket_trigger",
              "kafka_trigger",
              "nats_trigger",
              "postgres_trigger",
              "mqtt_trigger",
              "amqp_trigger",
              "sqs_trigger",
              "gcp_trigger",
              "azure_trigger",
              "email_trigger",
            ]
          description: Type of the item
        path:
          type: string
          description: Path of the item in the workspace
        ahead:
          type: integer
          description: Number of versions source is ahead of target
        behind:
          type: integer
          description: Number of versions source is behind target
        has_changes:
          type: boolean
          description: Whether the item has any differences
        exists_in_source:
          type: boolean
          description: If the item exists in the source workspace
        exists_in_fork:
          type: boolean
          description: If the item exists in the fork workspace

    CompareSummary:
      type: object
      required:
        - total_diffs
        - total_ahead
        - total_behind
        - scripts_changed
        - flows_changed
        - apps_changed
        - resources_changed
        - variables_changed
        - resource_types_changed
        - folders_changed
        - schedules_changed
        - triggers_changed
        - datatable_migrations_changed
        - conflicts
      properties:
        total_diffs:
          type: integer
          description: Total number of items with differences
        total_ahead:
          type: integer
          description: Total number of ahead changes
        total_behind:
          type: integer
          description: Total number of behind changes
        scripts_changed:
          type: integer
          description: Number of scripts with differences
        flows_changed:
          type: integer
          description: Number of flows with differences
        apps_changed:
          type: integer
          description: Number of apps with differences
        resources_changed:
          type: integer
          description: Number of resources with differences
        variables_changed:
          type: integer
          description: Number of variables with differences
        resource_types_changed:
          type: integer
          description: Number of resource types with differences
        folders_changed:
          type: integer
          description: Number of folders with differences
        schedules_changed:
          type: integer
          description: Number of schedules with differences
        triggers_changed:
          type: integer
          description: Number of triggers with differences (sum across all trigger kinds)
        datatable_migrations_changed:
          type: integer
          description: Number of data table migrations with differences
        conflicts:
          type: integer
          description: Number of items that are both ahead and behind (conflicts)

    TeamInfo:
      type: object
      required:
        - team_id
        - team_name
        - channels
      properties:
        team_id:
          type: string
          description: The unique identifier of the Microsoft Teams team
          example: "19:abc123def456@thread.tacv2"
        team_name:
          type: string
          description: The display name of the Microsoft Teams team
          example: "Engineering Team"
        channels:
          type: array
          description: List of channels within the team
          items:
            $ref: "#/components/schemas/ChannelInfo"

    ChannelInfo:
      type: object
      required:
        - channel_id
        - channel_name
        - tenant_id
        - service_url
      properties:
        channel_id:
          type: string
          description: The unique identifier of the channel
          example: "19:channel123@thread.tacv2"
        channel_name:
          type: string
          description: The display name of the channel
          example: "General"
        tenant_id:
          type: string
          description: The Microsoft Teams tenant identifier
          example: "12345678-1234-1234-1234-123456789012"
        service_url:
          type: string
          description: The service URL for the channel
          example: "https://smba.trafficmanager.net/amer/12345678-1234-1234-1234-123456789012/"

    GithubInstallations:
      type: array
      items:
        type: object
        properties:
          workspace_id:
            type: string
          installation_id:
            type: number
          account_id:
            type: string
          repositories:
            type: array
            items:
              type: object
              properties:
                name:
                  type: string
                url:
                  type: string
              required:
                - name
                - url
          total_count:
            type: number
            description: Total number of repositories available for this installation
          per_page:
            type: number
            description: Number of repositories loaded per page
          error:
            type: string
            description: Error message if token retrieval failed
          github_base_url:
            type: string
            nullable: true
            description: Set for self-managed (GHES) installs. Cloud installs omit this field.
          provisioned_by_admin:
            type: boolean
            description: True when the installation was assigned by the instance super-admin from instance settings. Workspace admins cannot remove these.
        required:
          - installation_id
          - account_id
          - repositories
          - total_count
          - per_page

    WorkspaceGithubInstallation:
      type: object
      properties:
        account_id:
          type: string
        installation_id:
          type: number
      required:
        - account_id
        - installation_id

    S3Object:
      type: object
      properties:
        s3:
          type: string
        filename:
          type: string
        storage:
          type: string
        presigned:
          type: string
      required:
        - s3
    TeamsChannel:
      type: object
      required:
        - team_id
        - team_name
        - channel_id
        - channel_name
      properties:
        team_id:
          type: string
          description: Microsoft Teams team ID
          minLength: 1
        team_name:
          type: string
          description: Microsoft Teams team name
          minLength: 1
        channel_id:
          type: string
          description: Microsoft Teams channel ID
          minLength: 1
        channel_name:
          type: string
          description: Microsoft Teams channel name
          minLength: 1
    AssetUsageKind:
      type: string
      enum:
        - script
        - flow
        - job
    AssetUsageAccessType:
      type: string
      enum: [r, w, rw]
      nullable: true
    AssetKind:
      type: string
      enum:
        - s3object
        - resource
        - ducklake
        - datatable
        - volume
    MaterializedPartition:
      type: object
      required: [asset_kind, asset_path, partition, status, materialized_at]
      properties:
        asset_kind:
          $ref: "#/components/schemas/AssetKind"
        asset_path:
          type: string
        partition:
          type: string
        status:
          type: string
          enum: [running, materialized, failed]
        snapshot_id:
          type: integer
          format: int64
          nullable: true
        row_count:
          type: integer
          format: int64
          nullable: true
        job_id:
          type: string
          format: uuid
          nullable: true
        materialized_at:
          type: string
          format: date-time
        error:
          type: string
          nullable: true
    PartitionsInRange:
      type: object
      required: [producer_path, partition_kind, partitions]
      properties:
        producer_path:
          type: string
          description: the pipeline script that materializes the asset (managed `// materialize` target, or a partitioned writer using the SDK helpers) — the runnable a backfill launches
        partition_kind:
          type: string
          enum: [daily, hourly, weekly, monthly, dynamic]
        partitions:
          type: array
          items:
            type: object
            required: [partition, status]
            properties:
              partition:
                type: string
              status:
                type: string
                enum: [missing, running, materialized, failed]
    AssetSchemaVersion:
      type: object
      required: [version, columns, captured_at]
      properties:
        version:
          type: integer
          format: int64
        columns:
          type: array
          items:
            type: object
            required: [name, type]
            properties:
              name:
                type: string
              type:
                type: string
        snapshot_id:
          type: integer
          format: int64
          nullable: true
        job_id:
          type: string
          format: uuid
          nullable: true
        captured_at:
          type: string
          format: date-time
    Asset:
      type: object
      properties:
        path:
          type: string
        kind:
          $ref: "#/components/schemas/AssetKind"
      required: [path, kind]
    DataMetric:
      description: |
        One `// measure` or `// dimension` declaration, as catalogued from the
        script that materializes the table. `expr` and `filter` are the author's
        own SQL: a reader renders a measure as `expr` plus, when `filter` is set,
        a trailing `FILTER (WHERE filter)`.
      type: object
      required: [script_path, table_path, kind, name, expr]
      properties:
        script_path:
          type: string
          description: The declaring script, and the path reads are authorized against
        table_path:
          type: string
          description: Canonical scheme-less DuckLake path, `<lake>/<schema>.<table>` (schema defaults to `main`)
        kind:
          type: string
          enum:
            - measure
            - dimension
        name:
          type: string
        expr:
          type: string
        filter:
          type: string
          description: Row predicate from a measure's trailing `where`
    ContractWarning:
      description: |
        One save-time schema-contract warning: a consumer reference that does
        not match the referenced asset's latest captured schema.
        `schema_version`/`captured_at` identify the capture the check ran
        against (as-of the producer's last run, not its latest save).
      type: object
      required: [kind, asset_path, message]
      properties:
        kind:
          type: string
          enum:
            - missing_column
            - missing_lineage_source
            - missing_relationship_column
            - relationship_type_mismatch
            - missing_measure_column
            - missing_dimension_column
            - non_aggregate_measure
            - suppressed
        asset_path:
          type: string
        column:
          type: string
        expected_type:
          type: string
        found_type:
          type: string
        schema_version:
          type: integer
          format: int64
        captured_at:
          type: string
          format: date-time
        message:
          type: string
    Volume:
      type: object
      required:
        - name
        - size_bytes
        - file_count
        - created_at
        - created_by
      properties:
        name:
          type: string
        size_bytes:
          type: integer
          format: int64
        file_count:
          type: integer
        created_at:
          type: string
          format: date-time
        created_by:
          type: string
        updated_at:
          type: string
          format: date-time
          nullable: true
        last_used_at:
          type: string
          format: date-time
          nullable: true
        extra_perms:
          type: object
          additionalProperties: true
    ProtectionRuleset:
      type: object
      description: A workspace protection rule defining restrictions and bypass permissions
      required:
        - name
        - rules
        - bypass_groups
        - bypass_users
      properties:
        name:
          type: string
          description: Unique name for the protection rule
          example: "Production Protection"
        workspace_id:
          type: string
        rules:
          $ref: "#/components/schemas/ProtectionRules"
        bypass_groups:
          $ref: "#/components/schemas/RuleBypasserGroups"
        bypass_users:
          $ref: "#/components/schemas/RuleBypasserUsers"
    ProtectionRules:
      type: array
      description: Configuration of protection restrictions
      items:
        $ref: "#/components/schemas/ProtectionRuleKind"
    ProtectionRuleKind:
      type: string
      enum:
        - DisableDirectDeployment
        - DisableWorkspaceForking
        - RestrictDeployToDeployers
        - RestrictAnonymousAppDeployment
    RuleBypasserGroups:
      type: array
      description: Groups that can bypass this ruleset
      items:
        type: string
    RuleBypasserUsers:
      type: array
      description: Users that can bypass this ruleset
      items:
        type: string
    DeploymentRequestEligibleDeployer:
      type: object
      required:
        - username
        - email
        - is_admin
      properties:
        username:
          type: string
        email:
          type: string
        is_admin:
          type: boolean
    DeploymentRequestAssignee:
      type: object
      required:
        - username
        - email
      properties:
        username:
          type: string
        email:
          type: string
    DeploymentRequestComment:
      type: object
      required:
        - id
        - author
        - author_email
        - body
        - obsolete
        - created_at
      properties:
        id:
          type: integer
          format: int64
        parent_id:
          type: integer
          format: int64
          nullable: true
        author:
          type: string
        author_email:
          type: string
        body:
          type: string
        anchor_kind:
          type: string
          nullable: true
        anchor_path:
          type: string
          nullable: true
        obsolete:
          type: boolean
        created_at:
          type: string
          format: date-time
    DeploymentRequest:
      type: object
      required:
        - id
        - source_workspace_id
        - fork_workspace_id
        - requested_by
        - requested_by_email
        - requested_at
        - assignees
        - comments
      properties:
        id:
          type: integer
          format: int64
        source_workspace_id:
          type: string
        fork_workspace_id:
          type: string
        requested_by:
          type: string
        requested_by_email:
          type: string
        requested_at:
          type: string
          format: date-time
        assignees:
          type: array
          items:
            $ref: "#/components/schemas/DeploymentRequestAssignee"
        comments:
          type: array
          items:
            $ref: "#/components/schemas/DeploymentRequestComment"
    QuotaInfo:
      type: object
      properties:
        used:
          type: integer
        limit:
          type: integer
        prunable:
          type: integer
      required:
        - used
        - limit
        - prunable
    NativeServiceName:
      type: string
      enum:
        - nextcloud
        - google
        - github

    NativeTrigger:
      type: object
      description: A native trigger stored in Windmill
      properties:
        external_id:
          type: string
          description: The unique identifier from the external service
        workspace_id:
          type: string
          description: The workspace this trigger belongs to
        service_name:
          $ref: "#/components/schemas/NativeServiceName"
        script_path:
          type: string
          description: The path to the script or flow that will be triggered
        is_flow:
          type: boolean
          description: Whether the trigger targets a flow (true) or a script (false)
        service_config:
          type: object
          description: Configuration for the trigger including event_type and service_config
          additionalProperties: true
        error:
          type: string
          nullable: true
          description: Error message if the trigger is in an error state
        summary:
          type: string
          nullable: true
          description: Short summary to be displayed when listed
      required:
        - external_id
        - workspace_id
        - service_name
        - script_path
        - is_flow
        - service_config

    NativeTriggerWithExternal:
      type: object
      description: Full trigger response containing both Windmill data and external service data
      properties:
        external_id:
          type: string
          description: The unique identifier from the external service
        workspace_id:
          type: string
          description: The workspace this trigger belongs to
        service_name:
          $ref: "#/components/schemas/NativeServiceName"
        script_path:
          type: string
          description: The path to the script or flow that will be triggered
        is_flow:
          type: boolean
          description: Whether the trigger targets a flow (true) or a script (false)
        service_config:
          type: object
          description: Configuration for the trigger including event_type and service_config
          additionalProperties: true
        error:
          type: string
          nullable: true
          description: Error message if the trigger is in an error state
        summary:
          type: string
          nullable: true
          description: Short summary to be displayed when listed
        external_data:
          type: object
          description: Configuration data from the external service
          additionalProperties: true
      required:
        - external_id
        - workspace_id
        - service_name
        - script_path
        - is_flow
        - service_config
        - external_data

    WorkspaceIntegrations:
      type: object
      properties:
        service_name:
          $ref: "#/components/schemas/NativeServiceName"
        oauth_data:
          nullable: true
          $ref: "#/components/schemas/WorkspaceOAuthConfig"
        resource_path:
          type: string
          nullable: true
          description: Path to the resource storing the OAuth token
      required:
        - service_name

    WorkspaceOAuthConfig:
      type: object
      properties:
        client_id:
          type: string
          description: The OAuth client ID for the workspace
        client_secret:
          type: string
          description: The OAuth client secret for the workspace
        base_url:
          type: string
          format: uri
          description: The base URL of the workspace
        redirect_uri:
          type: string
          format: uri
          description: The OAuth redirect URI
      required:
        - client_id
        - client_secret
        - base_url
        - redirect_uri

    WebhookEvent:
      type: object
      properties:
        type:
          type: string
          enum: [webhook]
        request_type:
          $ref: "#/components/schemas/WebhookRequestType"
      required:
        - type
        - request_type

    WebhookRequestType:
      type: string
      description: The type of webhook request (define possible values here)
      enum:
        - async
        - sync

    RedirectUri:
      type: object
      properties:
        redirect_uri:
          type: string
      required:
        - redirect_uri

    NativeTriggerData:
      type: object
      description: Data for creating or updating a native trigger
      properties:
        script_path:
          type: string
          description: The path to the script or flow that will be triggered
        is_flow:
          type: boolean
          description: Whether the trigger targets a flow (true) or a script (false)
        service_config:
          type: object
          description: Service-specific configuration (e.g., event types, filters)
          additionalProperties: true
        summary:
          type: string
          nullable: true
          description: Short summary to be displayed when listed
      required:
        - script_path
        - is_flow
        - service_config

    CreateTriggerResponse:
      type: object
      description: Response returned when a native trigger is created
      properties:
        external_id:
          type: string
          description: The external ID of the created trigger from the external service
      required:
        - external_id

    SyncResult:
      type: object
      properties:
        already_in_sync:
          type: boolean
        added_count:
          type: integer
        added_triggers:
          type: array
          items:
            type: string
        total_external:
          type: integer
        total_windmill:
          type: integer
      required:
        - already_in_sync
        - added_count
        - added_triggers
        - total_external
        - total_windmill

    NextCloudEventType:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        category:
          type: string
        path:
          type: string
      required:
        - id
        - name
        - path

    GoogleCalendarEntry:
      type: object
      properties:
        id:
          type: string
        summary:
          type: string
        primary:
          type: boolean
          default: false
      required:
        - id
        - summary

    GoogleDriveFile:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        mime_type:
          type: string
        is_folder:
          type: boolean
          default: false
      required:
        - id
        - name
        - mime_type

    GoogleDriveFilesResponse:
      type: object
      properties:
        files:
          type: array
          items:
            $ref: "#/components/schemas/GoogleDriveFile"
        next_page_token:
          type: string
      required:
        - files

    SharedDriveEntry:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id
        - name

    GithubRepoEntry:
      type: object
      properties:
        full_name:
          type: string
        name:
          type: string
        owner:
          type: string
        private:
          type: boolean
      required:
        - full_name
        - name
        - owner
        - private
