openapi: 3.1.0
info:
  title: Cube Platform API
  version: 1.0.0
  description: |-
    Programmatically manage Cube: deployments and everything scoped to them
    (environments, folders, reports, workbooks, notifications, workspace, and agents),
    plus account-level users, groups, policies, embedding, and AI settings. Data-model
    authoring, dev mode, branches, and uploads live under /build/api/v1 — same host and
    token, routed to the build pods.
servers:
  - url: https://{tenant}.cubecloud.dev
    description: Your tenant host. Replace the whole host if you use a custom domain.
    variables:
      tenant:
        default: your-tenant
        description: Your Cube tenant subdomain
security:
  - bearerAuth: []
tags:
  - name: Deployments
  - name: Deployment Creation
  - name: Environments
  - name: Env Variables
  - name: Regions
  - name: Data Model
  - name: Data Model Uploads
  - name: GitHub
  - name: GitHub Connection
  - name: dbt Sync
  - name: Folders
  - name: Reports
  - name: Workbooks
  - name: Notifications
  - name: Workspace
  - name: Users
  - name: Users Admin
  - name: User Attributes
  - name: User Attribute Values
  - name: Tenant Settings
  - name: OAuth Integrations
  - name: User OAuth Tokens
  - name: OIDC Token Configs
  - name: App Theme
  - name: Embed
  - name: Embed Tenants
  - name: Dashboard Embed Access
  - name: Usage Analytics
  - name: OpenAPI Spec
paths:
  /api/v1/app-config:
    get:
      operationId: getAppConfig
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AppConfigResponse'
          description: ''
      summary: Get app config
      tags:
        - App Theme
  /api/v1/deployments:
    get:
      operationId: getDeployments
      parameters:
        - in: query
          name: creationStep
          required: false
          schema:
            oneOf:
              - items:
                  enum:
                    - project
                    - upload
                    - schema
                    - github
                    - ssh
                    - databases
                    - ready
                    - demo
                  type: string
                type: array
                $ref: '#/components/schemas/CreationStep'
              - type: array
                items:
                  $ref: '#/components/schemas/CreationStep'
        - in: query
          name: offset
          required: false
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
            type: integer
            minimum: 0
        - in: query
          name: limit
          required: false
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
            type: integer
            minimum: 0
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentsListResponse'
          description: ''
      summary: Get deployments
      tags:
        - Deployments
  /api/v1/deployments/{deploymentId}:
    delete:
      operationId: deleteDeployment
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentDeleteResponse'
          description: ''
      summary: Delete deployment
      tags:
        - Deployments
    get:
      operationId: getDeployment
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
          description: ''
      summary: Get deployment
      tags:
        - Deployments
    put:
      operationId: updateDeployment
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDeploymentInput'
        description: UpdateDeploymentInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentSettings'
          description: ''
      summary: Update a deployment
      tags:
        - Deployments
      x-mint:
        content: >-
          Update any subset of a deployment’s settings — everything the console’s Settings pages own
          — and read the full settings back. Fields you omit are left alone, and `templateVariables`
          is merged key-by-key rather than replaced, so setting one configuration flag never clears
          the others. `releaseChannelVersion` must be one of the versions `GET
          /:deploymentId/versions` lists for the target channel (in any of the forms it reports) —
          anything else is a 400, and the container image is resolved from the version rather than
          sent. Choosing a version that is not the channel’s latest also sets
          `releaseChannelVersionHold` unless you send it explicitly, so auto-upgrade does not undo
          the pin.
  /api/v1/deployments/{deploymentId}/build-status:
    get:
      operationId: buildStatus
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: branchName
          schema:
            oneOf:
              - type: string
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BuildStatusResponse'
          description: ''
      summary: Latest build/compile status for a branch (production build or dev-mode)
      tags:
        - Deployments
  /api/v1/deployments/{deploymentId}/creation-step/advance:
    post:
      operationId: advanceCreationStep
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdvanceCreationStepInput'
        description: AdvanceCreationStepInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
          description: ''
      summary: Advance a deployment to a given onboarding step (e.g. after connecting a source)
      tags:
        - Deployments
  /api/v1/deployments/{deploymentId}/creation-step/reset:
    post:
      operationId: resetCreationStep
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
          description: ''
      summary: Reset a deployment to the first onboarding step (project)
      tags:
        - Deployments
  /api/v1/deployments/{deploymentId}/dbt-sync:
    get:
      operationId: listDbtSyncs
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: status
          schema:
            oneOf:
              - $ref: '#/components/schemas/DbtSyncRunsQueryStatus'
              - type: 'null'
        - in: query
          name: trigger
          schema:
            oneOf:
              - $ref: '#/components/schemas/DbtSyncRunsQueryTrigger'
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DbtSyncRunListResponse'
          description: ''
      summary: List dbt syncs for a deployment
      tags:
        - dbt Sync
    post:
      operationId: startDbtSync
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartDbtSyncInput'
        description: StartDbtSyncInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DbtSyncResponse'
          description: ''
      summary: Start a dbt sync for a deployment
      tags:
        - dbt Sync
  /api/v1/deployments/{deploymentId}/dbt-sync/{syncJobId}:
    delete:
      operationId: cancelDbtSync
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: path
          name: syncJobId
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DbtSyncCancelResponse'
          description: ''
      summary: Cancel a running dbt sync
      tags:
        - dbt Sync
    get:
      operationId: getDbtSyncStatus
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: path
          name: syncJobId
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DbtSyncStatusResponse'
          description: ''
      summary: Get the status of a dbt sync
      tags:
        - dbt Sync
  /api/v1/deployments/{deploymentId}/dbt-sync/{syncJobId}/logs:
    get:
      operationId: getDbtSyncLogs
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: path
          name: syncJobId
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DbtSyncLogEntriesListResponse'
          description: ''
      summary: Get the log of a dbt sync
      tags:
        - dbt Sync
  /api/v1/deployments/{deploymentId}/dbt-sync/{syncJobId}/result:
    get:
      operationId: getDbtSyncResult
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: path
          name: syncJobId
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DbtSyncResultResponse'
          description: ''
      summary: Get the result of a completed dbt sync
      tags:
        - dbt Sync
  /api/v1/deployments/{deploymentId}/env-vars:
    get:
      operationId: getEnvVariables
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnvVariablesListResponse'
          description: ''
      summary: Get env variables
      tags:
        - Env Variables
      x-mint:
        content: >-
          Lists the deployment environment variables, cursor-paginated via `first`/`after`. Values
          of secret-named variables (containing PASS, SECRET, TOKEN, KEY, or CREDENTIAL) are
          returned as `[ENCRYPTED]`.
    put:
      operationId: setEnvVariables
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetEnvVariablesInput'
        description: SetEnvVariablesInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnvVariablesListResponse'
          description: ''
      summary: Set env variables
      tags:
        - Env Variables
      x-mint:
        content: >-
          Upserts deployment environment variables by name; variables not included keep their
          existing values. Passing the `[ENCRYPTED]` placeholder (the masked read value) is rejected
          — omit variables you do not intend to change. New variable names must be POSIX identifiers
          (`^[A-Za-z_][A-Za-z0-9_]*$`); names already stored on the deployment may be resent
          unchanged so a legacy name can still be updated or removed.
  /api/v1/deployments/{deploymentId}/environments:
    get:
      operationId: getDeploymentEnvironments
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: type
          required: false
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetDeploymentEnvironmentsQueryType'
              - type: 'null'
            type: string
            enum:
              - production
              - staging
              - development
        - in: query
          name: offset
          required: false
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
            type: integer
            minimum: 0
        - in: query
          name: limit
          required: false
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
            type: integer
            minimum: 0
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentEnvironmentsListResponse'
          description: ''
      summary: Get deployment environments
      tags:
        - Environments
  /api/v1/deployments/{deploymentId}/environments/{environmentId}/tokens:
    get:
      operationId: getDeploymentEnvironmentTokens
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: path
          name: environmentId
          required: true
          schema:
            type: integer
        - in: query
          name: offset
          required: false
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
            type: integer
            minimum: 0
        - in: query
          name: limit
          required: false
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
            type: integer
            minimum: 0
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentEnvironmentTokensListResponse'
          description: ''
      summary: Get deployment environment tokens
      tags:
        - Environments
    post:
      operationId: createDeploymentEnvironmentToken
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: path
          name: environmentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDeploymentEnvironmentTokenInput'
        description: CreateDeploymentEnvironmentTokenInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentEnvironmentTokenResponse'
          description: ''
      summary: Create deployment environment token
      tags:
        - Environments
  /api/v1/deployments/{deploymentId}/environments/{environmentId}/tokens-for-meta-sync:
    post:
      operationId: createDeploymentEnvironmentTokenForMetaSync
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: path
          name: environmentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDeploymentEnvironmentTokenInput'
        description: CreateDeploymentEnvironmentTokenInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentEnvironmentTokenResponse'
          description: ''
      summary: Create deployment environment token for meta sync
      tags:
        - Environments
  /api/v1/deployments/{deploymentId}/folders:
    get:
      operationId: getFolders
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: query
          name: parentId
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FoldersListResponse'
          description: ''
      summary: List folders
      tags:
        - Folders
      x-mint:
        content: >-
          List the folders in a deployment's workspace.


          By default this returns the folders at the workspace root. Pass the `parentId` query
          parameter to list the direct children of a specific folder instead.


          Results are scoped to the calling user: only folders the user can see are returned. A
          folder is visible when the user owns it, has been granted access to it directly, or has
          access to something inside it (a sub-folder, workbook, or dashboard), in which case the
          ancestor folders are surfaced as navigation.


          This endpoint is not recursive — it returns a single level of the folder tree per call.
          Use `parentId` to walk deeper, or `GET /folders/{folderId}/ancestors` to resolve a
          breadcrumb path.


          Results are returned in pages using cursor-based pagination: pass `first` to set the page
          size and `after` (the previous response's `pageInfo.endCursor`) to fetch the next page.
          The legacy `data` and `count` fields are still populated for backwards compatibility but
          are deprecated in favour of `items` and `pageInfo`.
    post:
      operationId: createFolder
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateFolderInput'
        description: CreateFolderInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Folder'
          description: ''
      summary: Create a folder
      tags:
        - Folders
      x-mint:
        content: >-
          Create a new folder in a deployment's workspace.


          Provide a `name`, and optionally a `parentId` to nest the folder inside an existing one
          (omit it to create the folder at the workspace root). An optional `position` controls the
          folder's ordering among its siblings.


          Requires the **AI BI User** role (or higher). When `parentId` is set, the caller must
          additionally have **edit** or **manage** access to that parent folder.


          Folders can be nested up to a fixed maximum depth; exceeding it returns `400`.
  /api/v1/deployments/{deploymentId}/folders/{folderId}:
    delete:
      operationId: deleteFolder
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: folderId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Delete a folder
      tags:
        - Folders
      x-mint:
        content: >-
          Delete a folder from a deployment's workspace. Responds with `204 No Content` on success.


          The folder must be empty of sub-folders: if it still has child folders, the request is
          rejected with `400` — delete or move the sub-folders first.


          Content directly inside the folder (workbooks, dashboards, reports) is **not** deleted. It
          is detached and returned to the workspace root.


          Requires **manage** access to the folder. Returns `404` if the folder does not exist or
          belongs to a different deployment.
    put:
      operationId: updateFolder
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: folderId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateFolderInput'
        description: UpdateFolderInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Folder'
          description: ''
      summary: Update a folder
      tags:
        - Folders
      x-mint:
        content: >-
          Update a folder's metadata — its `name` and/or its `position` among its siblings. Both
          fields are optional; only the fields you send are changed.


          This endpoint does **not** move a folder to a different parent. To re-parent a folder, use
          `POST /workspace/move` with `type: FOLDER`.


          Requires **edit** access to the folder. Returns `404` if the folder does not exist or
          belongs to a different deployment.
  /api/v1/deployments/{deploymentId}/folders/{folderId}/ancestors:
    get:
      operationId: getFolderAncestors
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: folderId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Folder'
                type: array
          description: ''
      summary: List folder ancestors
      tags:
        - Folders
      x-mint:
        content: >-
          Return the ancestor chain of a folder, ordered from the workspace root down to (and
          including) the folder itself.


          Use this to render a breadcrumb path for a nested folder. For example, for `Root / Sales /
          Q1` requested on the `Q1` folder, the response is `[Root, Sales, Q1]`.


          Requires visibility access to the target folder. Returns `404` if the folder does not
          exist or belongs to a different deployment.
  /api/v1/deployments/{deploymentId}/logs:
    get:
      operationId: logs
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: source
          schema:
            oneOf:
              - $ref: '#/components/schemas/DeploymentLogsQuerySource'
              - type: 'null'
        - in: query
          name: pod
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: container
          schema:
            oneOf:
              - $ref: '#/components/schemas/DeploymentLogsQueryContainer'
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentLogsResponse'
          description: ''
      summary: >-
        Recent runtime logs (tail) for a deployment. With no `source`, reads both the production API
        / worker pods and the dev-mode worker, merged chronologically; scope with
        `?source=production` or `?source=dev`.
      tags:
        - Deployments
  /api/v1/deployments/{deploymentId}/notifications:
    get:
      operationId: getNotifications
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
        - in: query
          name: dashboardId
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
            description: >-
              Optional filter: only return notifications for this numeric dashboard id. Provide this
              OR dashboardPublicId, not both.
        - in: query
          name: dashboardPublicId
          schema:
            oneOf:
              - type: string
              - type: 'null'
            description: >-
              Optional filter: only return notifications for this dashboard public id. Provide this
              OR dashboardId, not both.
        - in: query
          name: recipientUserId
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
            description: >-
              Optional filter: only return notifications received by this user, by user id. Mutually
              exclusive with recipientEmail and the embed-user filter.
        - in: query
          name: recipientEmail
          schema:
            oneOf:
              - type: string
              - type: 'null'
            description: >-
              Optional filter: only return notifications received by this user, by email. Mutually
              exclusive with recipientUserId and the embed-user filter.
        - in: query
          name: recipientEmbedTenantName
          schema:
            oneOf:
              - type: string
              - type: 'null'
            description: >-
              Optional filter: only return notifications received by this embed user. Required
              together with recipientExternalId; mutually exclusive with the user filters.
        - in: query
          name: recipientExternalId
          schema:
            oneOf:
              - type: string
              - type: 'null'
            description: >-
              Optional filter: only return notifications received by this embed user. Required
              together with recipientEmbedTenantName; mutually exclusive with the user filters.
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationsListResponse'
          description: ''
      summary: List scheduled notifications
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Returns the deployment’s scheduled notifications (recurring dashboard runs), ordered by
          creation time (newest first) and cursor-paginated. Optionally filter to a single dashboard
          with either `dashboardId` (numeric) or `dashboardPublicId` (string), and/or to the
          notifications a single recipient receives — a user (`recipientUserId` or `recipientEmail`)
          or an embed user (`recipientEmbedTenantName` + `recipientExternalId`). At most one
          identifier per dashboard/recipient dimension. Each item describes the schedule only;
          recipients are managed through the `/recipients` sub-resource.
    post:
      operationId: createNotification
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateNotificationInput'
        description: CreateNotificationInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationDto'
          description: ''
      summary: Create a scheduled notification
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Creates a scheduled notification — a recurring run of a dashboard whose rendered result is
          delivered to its recipients. The cadence is set by `scheduleType` plus the relevant time
          fields (`minute`, `hour`, `dayOfWeek`, `dayOfMonth`) or a raw `customCron` expression when
          `scheduleType` is `CUSTOM`; `timezone` defaults to UTC. Identify the target dashboard with
          either `dashboardId` (numeric) or `dashboardPublicId` (string) — supply exactly one; it
          must belong to this deployment, otherwise `404` is returned. The created notification has
          no recipients — add them via `POST /notifications/{id}/recipients`.
  /api/v1/deployments/{deploymentId}/notifications/{id}:
    delete:
      operationId: deleteNotification
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the notification (scheduled run).
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
        '204':
          description: Notification deleted.
      summary: Delete a scheduled notification
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Permanently deletes a scheduled notification and all of its recipients (main, embed, and
          Slack) in a single cascade. Returns `204 No Content` on success, or `404` if the
          notification does not belong to this deployment.
    get:
      operationId: getNotification
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the notification (scheduled run).
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationDto'
          description: ''
      summary: Get a scheduled notification
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Returns a single scheduled notification by id, including its cron expression, timezone,
          enabled state, notification format, and a human-readable schedule summary. Returns `404`
          if the notification does not exist or does not belong to this deployment.
    put:
      operationId: updateNotification
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the notification (scheduled run).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateNotificationInput'
        description: UpdateNotificationInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationDto'
          description: ''
      summary: Update a scheduled notification
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Updates a notification’s schedule definition. Any subset of the schedule fields may be
          supplied (`scheduleType` + time fields or `customCron`, `timezone`), along with
          `isEnabled`, `notificationEnabled`, and `notificationFormat`. Omitted fields are left
          unchanged. This endpoint never modifies recipients — manage those through the
          `/recipients` sub-resource. Returns `404` if the notification is not part of this
          deployment.
  /api/v1/deployments/{deploymentId}/notifications/{id}/recipients:
    delete:
      operationId: removeRecipients
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the notification (scheduled run).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RemoveNotificationRecipientsInput'
        description: RemoveNotificationRecipientsInput
        required: false
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
        '204':
          description: Recipients removed.
      summary: Remove notification recipients
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Unsubscribes one or more recipients (1–1000 per request) from a notification. Each entry
          is identified by `type` plus the `id` returned by the API — `userId` for `USER`,
          `embedUserId` for `EMBED_USER`, or `channelId` for `SLACK`. `EMBED_USER` entries must also
          include `embedTenantName`, which locates the recipient’s storage partition. Removals are
          idempotent (deleting a recipient that isn’t subscribed is a no-op). Returns `204 No
          Content`, or `404` if the notification is not part of this deployment.
    get:
      operationId: getRecipients
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the notification (scheduled run).
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationRecipientsListResponse'
          description: ''
      summary: List notification recipients
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Returns the recipients subscribed to a notification, cursor-paginated and ordered by
          creation time (newest first). Recipients span three kinds, distinguished by `type`: `USER`
          (a main console user, with `userId` + `email`), `EMBED_USER` (an embed user, with
          `embedUserId`, `embedTenantName`, `externalId`, and `email`), and `SLACK` (a channel, with
          `channelId` + `channelName`). Returns `404` if the notification is not part of this
          deployment.
    post:
      operationId: addRecipients
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
          description: Numeric id of the deployment that owns the notification.
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the notification (scheduled run).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddNotificationRecipientsInput'
        description: AddNotificationRecipientsInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotificationRecipientsMutationResponse'
          description: ''
      summary: Add notification recipients
      tags:
        - Notifications
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Subscribes one or more recipients (1–1000 per request) to a notification. Each recipient
          is one of: a main console `USER` (identified by `userId` or `email`); an `EMBED_USER`
          (identified by `embedTenantName` + `externalId`, auto-provisioned if it does not yet
          exist, and optionally given `securityContext`, `userAttributes`, and `groups` that drive
          per-recipient rendering); or `SLACK` — **not yet supported**, a request containing a Slack
          recipient is rejected with `400`. Every recipient must resolve to a valid email (an embed
          user’s `email`, or an email-shaped `externalId`); otherwise the whole request fails with
          `400` before anything is written. The operation is idempotent: the response buckets each
          recipient into `createdRecipients`, `updatedRecipients` (an existing recipient whose embed
          properties changed), or `unchangedRecipients`.
  /api/v1/deployments/{deploymentId}/pods:
    get:
      operationId: pods
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentPodsResponse'
          description: ''
      summary: List the pods currently scheduled for a deployment
      tags:
        - Deployments
  /api/v1/deployments/{deploymentId}/reports:
    get:
      operationId: getReports
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: query
          name: workbookId
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: folderId
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: externalWorkbookId
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: search
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: limit
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: page
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: sortBy
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetReportsQuerySortBy'
              - type: 'null'
        - in: query
          name: sortDirection
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetReportsQuerySortDirection'
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportsListResponse'
          description: ''
      summary: List reports
      tags:
        - Reports
      x-mint:
        content: >-
          List the reports in a deployment, scoped to the reports the calling user can access.


          Results are returned in pages using cursor-based pagination: pass `first` to set the page
          size and `after` (the previous response's `pageInfo.endCursor`) to fetch the next page.


          Cursor pagination is not supported when sorting by `lastViewedAt` (a per-viewer sort with
          no stable cursor column).
    post:
      operationId: createReport
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateReportInput'
        description: CreateReportInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
          description: ''
      summary: Create a report
      tags:
        - Reports
      x-mint:
        content: >-
          Create a report in a deployment.


          You may supply your own `publicId` (a 12-character `[0-9A-Za-z]` id) to key the report for
          as-code management; omit it to have one generated. It must be an id you chose — the
          auto-generated placeholder ids shown for reports that have no stable id yet are a
          reserved, non-unique shape and are rejected with `400`.
  /api/v1/deployments/{deploymentId}/reports/by-public-id/{publicId}:
    put:
      operationId: upsertReportByPublicId
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: publicId
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateReportInput'
        description: CreateReportInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
          description: ''
      summary: Create or update a report by publicId
      tags:
        - Reports
      x-mint:
        content: >-
          Idempotent create-or-update ("upsert") of a report keyed by its portable `publicId` — the
          stable identity for managing dashboards as code (CI/CD pipelines re-applying the same
          definition against any environment).


          If a report with this `publicId` exists in the deployment, it is updated with the fields
          you send (same semantics as `PUT /reports/:reportId`); otherwise a new report is created
          with this `publicId`. Re-applying the same request is a no-op. The `publicId` must be a
          12-character alphanumeric id (`[0-9A-Za-z]`); mint one client-side when authoring the
          definition.


          This endpoint returns `409` for three different reasons, distinguished by the response
          body's `code` — handle them differently:


          - **No `code`** — the `publicId` already belongs to a report in a **different**
          deployment. Because `publicId` is unique across the account, it is rejected rather than
          silently updating across deployments (reported regardless of whether you have access to
          that report). This is **permanent**: retrying will not help; use a different `publicId`.

          - **`code: "upsert_branch_changed"`** — whether this request creates or updates is
          decided, and access-checked, before it is applied; another writer changed that in between
          (created or deleted the report with this `publicId`). The request was rejected rather than
          applied under the wrong permission check. This is **transient: retry the request**. It
          only happens when two writers target the same `publicId` concurrently, e.g. two pipeline
          runs applying the same bundle at once.

          - **`code: "ambiguous_legacy_id"`** — the id given is one of the ids synthesized for
          reports that predate stable ids (see below), and it matches more than one of them, so it
          cannot identify a single report. Nothing was changed. This is **permanent**, and the fix
          is different from the case above: assign the report you mean a `publicId` of your own with
          `PUT /deployments/{deploymentId}/reports/{reportId}`, then key on that.


          **Reports created before stable ids** do not store a `publicId`; the API synthesizes one
          for them from the report's internal id. Those synthesized ids are **not unique** — several
          reports can share one, and in practice most do. This endpoint resolves such an id only
          when it is unambiguous, adopting it as the report's real `publicId` at that point;
          otherwise it returns the `ambiguous_legacy_id` conflict above.


          For anything you intend to manage as code, do not rely on a synthesized id: give the
          report a `publicId` you chose. `PUT /deployments/{deploymentId}/reports/{reportId}`
          accepts `publicId` for exactly this, on any report that does not have one yet (it is
          write-once — a report's existing `publicId` cannot be changed, since clients may already
          have stored it).


          `source` is **create-only**: it is recorded when the report is first created and ignored
          on subsequent updates (it describes where the report originated, not its current
          definition).


          Access: updating requires **edit** access to the existing report; creating requires the
          same access as `POST /reports`.
  /api/v1/deployments/{deploymentId}/reports/{reportId}:
    delete:
      operationId: deleteReport
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: reportId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Delete report
      tags:
        - Reports
    get:
      operationId: getReport
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: reportId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
          description: ''
      summary: Get report
      tags:
        - Reports
    put:
      operationId: updateReport
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: string
        - in: path
          name: reportId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateReportInput'
        description: UpdateReportInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
          description: ''
      summary: Update a report
      tags:
        - Reports
      x-mint:
        content: >-
          Update a report. All fields are optional; only the fields you send are changed.


          `publicId` is **write-once**: you may assign one to a report that does not have one yet —
          which is how a report created before stable ids is adopted into as-code management, so
          `PUT /reports/by-public-id/{publicId}` can key on it — but a report's existing `publicId`
          cannot be changed, since clients may already have stored it. Attempting to change it
          returns `400`; a `publicId` already used by another report returns `409`.


          The id you assign must be one you chose (any distinct 12-character `[0-9A-Za-z]` id). The
          auto-generated placeholder id shown for a report that has no stable id yet cannot be
          assigned — it is not unique — and is rejected with `400`.


          Requires **edit** access to the report.
  /api/v1/deployments/{deploymentId}/reports/{reportId}/connect-workbook:
    delete:
      operationId: disconnectReportFromWorkbook
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: reportId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DisconnectReportFromWorkbookInput'
        description: DisconnectReportFromWorkbookInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
          description: ''
      summary: Disconnect a report from one spot in a spreadsheet
      tags:
        - Reports
      x-mint:
        content: |-
          Remove a single placement of a report — one sheet + anchor in one
          spreadsheet — leaving every other placement, in this workbook and in others, alone.

          Address the placement by `placementId`, or (for placements recorded before ids
          existed) by `externalWorkbookId` plus `sheetName` and `anchorCell` — or a
          `resultLocation` naming both. Neither the sheet name nor the anchor is optional in
          that form: matching is by sheet + anchor, and a target missing either addresses
          nothing.

          `sheetId` is an optional extra, not a substitute for `sheetName`: a placement
          written before that field existed has only a name, and no id the server could
          resolve to it, so an id-only address would match nothing while looking correct.

          Send a `sheetId` only when you know it is the one the placement was stored with.
          It NARROWS the target — a placement recorded under a different id is not matched,
          even when the sheet name and anchor agree, because the stored name may belong to a
          tab that has since been renamed and the id is the only stable identity. If your id
          may have moved on (a tab deleted and recreated under the same name reports a new
          one), address the placement by `placementId`, or by sheet name with no
          `sheetId` at all.

          A target that matches no placement succeeds and changes nothing, so retrying is
          safe.

          Like connecting, this records nothing about the report's definition and so requires
          only read access: unplacing a report from your own sheet is not an edit to the report.
    put:
      operationId: connectReportToWorkbook
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: reportId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectReportToWorkbookInput'
        description: ConnectReportToWorkbookInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
          description: ''
      summary: Connect a report to the calling spreadsheet
      tags:
        - Reports
      x-mint:
        content: |-
          Link a report to the caller's own spreadsheet by recording its placement
          (workbook id + result location) so the add-in can list and refresh it there.

          This upserts only the placement for the given workbook and never changes the
          report's query, name, or other definition — so, like refresh, it requires only
          read access to the report. A user who can view a report can place its data into
          their own sheet without being its creator or having edit rights.
  /api/v1/deployments/{deploymentId}/reports/{reportId}/refresh:
    put:
      operationId: refreshReport
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: reportId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshReportInput'
        description: RefreshReportInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
          description: ''
      summary: Refresh report
      tags:
        - Reports
  /api/v1/deployments/{deploymentId}/settings:
    get:
      operationId: getDeploymentSettings
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentSettings'
          description: ''
      summary: Get deployment settings
      tags:
        - Deployments
      x-mint:
        content: >-
          Every setting of a deployment in one payload — the full contents of the console Settings
          pages (general, configuration flags, deploy, launchpad, Cube Store private storage), plus
          the read-only values displayed alongside them. Secrets are excluded; read environment
          variables through `/env-vars` instead. Writes go to `PUT /:deploymentId`, which accepts
          the same fields and returns this payload.
  /api/v1/deployments/{deploymentId}/shared-workspace:
    get:
      operationId: sharedWorkspaceObjects
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: query
          name: folderId
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: types
          schema:
            oneOf:
              - items:
                  enum:
                    - FOLDER
                    - WORKBOOK
                    - REPORT
                  type: string
                type: array
              - type: 'null'
        - in: query
          name: orderByField
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetWorkspaceObjectsQueryOrderByField'
              - type: 'null'
        - in: query
          name: orderByDirection
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetWorkspaceObjectsQueryOrderByDirection'
              - type: 'null'
        - in: query
          name: search
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkspaceConnectionResponse'
          description: ''
      summary: List shared workspace items
      tags:
        - Workspace
      x-mint:
        content: >-
          List the workspace items (folders, workbooks, reports) that have been shared with embed
          users via the built-in "All embed users" group or the caller's per-embed-tenant
          `system:tenant:{embedTenantName}` group.


          Unlike `GET /workspace`, this feed is not per-user: every valid embed caller from the same
          embed tenant sees the same set, scoped to what those groups have been granted. Owner
          identities are blanked out so they are not exposed to embed users.


          Accepts the same `folderId`, `types`, `search`, sorting, and cursor-pagination parameters
          as `GET /workspace`. Folders reachable only because a nested item inside them was shared
          are surfaced as navigation, but their unshared siblings stay hidden.
  /api/v1/deployments/{deploymentId}/token:
    post:
      operationId: deploymentToken
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDeploymentTokenInput'
        description: CreateDeploymentTokenInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentTokenResponse'
          description: ''
      summary: Deployment token
      tags:
        - Deployments
  /api/v1/deployments/{deploymentId}/versions:
    get:
      operationId: listDeploymentVersions
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeploymentVersionsResponse'
          description: ''
      summary: List available Cube versions
      tags:
        - Deployments
      x-mint:
        content: >-
          Every Cube version this deployment can be switched to — the same set the console’s version
          picker offers: the head of each release channel, plus the older versions the tenant has
          run before (its release history). Pass a listed `releaseChannelVersion` to `PUT
          /:deploymentId`; anything else is rejected. The container image is resolved server-side
          and is not part of the write surface.
  /api/v1/deployments/{deploymentId}/workbooks:
    get:
      operationId: getWorkbooks
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: query
          name: folderId
          schema:
            oneOf:
              - minimum: 0
                type: integer
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkbooksListResponse'
          description: ''
      summary: Get workbooks
      tags:
        - Workbooks
    post:
      operationId: createWorkbook
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWorkbookInput'
        description: CreateWorkbookInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workbook'
          description: ''
      summary: Create workbook
      tags:
        - Workbooks
  /api/v1/deployments/{deploymentId}/workbooks/by-slug/{slug}:
    put:
      operationId: upsertWorkbookBySlug
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: slug
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWorkbookInput'
        description: CreateWorkbookInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workbook'
          description: ''
      summary: Create or update a workbook by slug
      tags:
        - Workbooks
      x-mint:
        content: >-
          Idempotent create-or-update ("upsert") of a workbook keyed by its deployment-scoped slug —
          the portable identity for managing dashboards as code (CI/CD pipelines re-applying the
          same definition against any environment).


          If a workbook with this slug exists in the deployment, it is updated: only the fields you
          send are changed, and `meta` is merged into the existing metadata (a `meta.dashboardDraft`
          is validated like everywhere else). Otherwise a new workbook is created with this slug.
          The slug is normalized (trimmed, lowercased) before matching. Re-applying the same request
          is a no-op.


          Access: updating requires **edit** access to the workbook holding the slug (requests that
          include `folderId` require **manage** access, plus **edit** access to the destination
          folder); creating requires the same access as `POST /workbooks` (AI BI User role or
          higher).


          Whether this request creates or updates is decided — and access-checked — before it is
          applied. If another writer changes that in between (creates or deletes the workbook
          holding this slug), the request is rejected with `409` and `code: "upsert_branch_changed"`
          rather than applied under the wrong permission check. This is **transient: retry the
          request**. It only happens when two writers target the same slug concurrently — for
          example two pipeline runs applying the same bundle at once, where one creates the workbook
          and the other must then retry into the update path.


          Returns `404` if the deployment does not exist.
  /api/v1/deployments/{deploymentId}/workbooks/{workbookId}:
    delete:
      operationId: deleteWorkbook
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Delete workbook
      tags:
        - Workbooks
    get:
      operationId: getWorkbook
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workbook'
          description: ''
      summary: Get workbook
      tags:
        - Workbooks
    put:
      operationId: updateWorkbook
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWorkbookInput'
        description: UpdateWorkbookInput
        required: false
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Update a workbook
      tags:
        - Workbooks
      x-mint:
        content: >-
          Update a workbook's properties. All fields are optional; only the fields you send are
          changed.


          - `name` — rename the workbook.

          - `meta` — replace the workbook's metadata object.

          - `folderId` — move the workbook between folders. Set it to a folder id to move the
          workbook into that folder, or to `null` to move it back to the workspace root.


          Access depends on what you change. Renaming or editing metadata requires **edit** access
          to the workbook. Moving the workbook (any request that includes `folderId`) requires
          **manage** access to the workbook, plus **edit** access to the destination folder when
          moving into one.


          To move a workbook you can use either this endpoint or the unified `POST /workspace/move`.
          Returns `404` if the workbook does not exist or belongs to a different deployment.
  /api/v1/deployments/{deploymentId}/workbooks/{workbookId}/dashboard:
    put:
      operationId: updateWorkbookDashboard
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkbookDashboardInput'
        description: WorkbookDashboardInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkbookDashboard'
          description: ''
      summary: Update workbook dashboard
      tags:
        - Workbooks
  /api/v1/deployments/{deploymentId}/workbooks/{workbookId}/dashboard/ai-widget-thread:
    post:
      operationId: updatePublishedDashboardAiWidgetThread
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePublishedAiWidgetThreadInput'
        description: UpdatePublishedAiWidgetThreadInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard'
          description: ''
      summary: Update published dashboard AI widget thread
      tags:
        - Workbooks
  /api/v1/deployments/{deploymentId}/workbooks/{workbookId}/duplicate:
    post:
      operationId: duplicateWorkbook
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DuplicateWorkbookInput'
        description: DuplicateWorkbookInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workbook'
          description: ''
      summary: Clone a workbook
      tags:
        - Workbooks
      x-mint:
        content: >-
          Create a full copy of a workbook, including its reports and its published dashboard, and
          return the new workbook.


          The clone is named "Copy of \{original name\}". All report references inside the dashboard
          (and the dashboard draft) are re-pointed at the copied reports, so the duplicate is fully
          self-contained and independent of the original. Per-user view history (last-viewed
          timestamps) is **not** carried over.


          The clone does **not** inherit the source's sharing: no user or group policies are copied,
          and signed embedding (`allowEmbed`) starts disabled on the cloned dashboard even when it
          is enabled on the source.


          Placement follows the caller's access to the source's folder. With **edit** access to that
          folder the clone (and its reports) is created alongside the original, and therefore
          inherits the access that folder grants. With only **read** access — or when the source is
          at the root — the clone is created at the workspace root instead, so a viewer never writes
          into a folder they don't control.


          Requires **read** access to the source workbook and the **AI BI User** role (or higher).
          The new workbook is owned by the calling user.


          Creator-mode embed sessions can also clone a workbook from the **shared workspace** (the
          items listed by `GET /shared-workspace`) by passing `{ "shared": true }` in the request
          body — `workbookId` is then resolved against the shared workspace instead of the caller's
          own. Such a clone is built from the workbook's **published dashboard**: a fresh report is
          created per report snapshot, the dashboard is re-published onto the new workbook, and the
          same config seeds the workbook's draft — the source's live reports and unpublished draft
          are not copied. The clone is placed at the workspace root. Requires the workbook to have a
          published dashboard (`400` otherwise); `403` for non-creator-mode callers.


          If the deployment's plan enforces a workbook limit and it has been reached, the request is
          rejected with `400`. Returns `404` if the workbook does not exist or belongs to a
          different deployment.
  /api/v1/deployments/{deploymentId}/workbooks/{workbookId}/embed-access:
    get:
      operationId: getEmbedAccess
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedAccessResponse'
          description: ''
      summary: List a dashboard's embed access
      tags:
        - Dashboard Embed Access
      x-mint:
        content: >-
          Return the embed audience of a workbook's published dashboard: the global `allowEmbed`
          (signed-embedding) flag, whether it is shared with **all embed users**, and the list of
          individual embed **tenants** it is shared with.


          Embed access is a read-only share of the workbook with a system sharing group, so this is
          scoped to the workbook that owns the dashboard. Requires **read** access to the workbook.
          Returns `404` if the workbook does not exist or belongs to a different deployment.
    put:
      operationId: updateEmbedAccess
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateEmbedAccessInput'
        description: UpdateEmbedAccessInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedAccessResponse'
          description: ''
      summary: Update a dashboard's embed access
      tags:
        - Dashboard Embed Access
      x-mint:
        content: >-
          Add, update, or remove one embed audience from a workbook's published dashboard, and/or
          toggle signed embedding. Returns the updated embed-access view.


          Provide exactly one target — `embedTenantName` (a single embed tenant) or `allEmbedUsers:
          true` (every embed tenant) — together with `action`: `"read"` grants access, `"none"`
          removes it. Include `allowEmbed` to also flip "Allow signed embedding" in the same
          request; omit both targets to change only `allowEmbed`.


          Requires **manage** access to the workbook. Returns `404` if the workbook or the named
          embed tenant does not exist, and `400` if the request specifies no change or sets
          `allowEmbed` on a workbook that has no published dashboard.
  /api/v1/deployments/{deploymentId}/workbooks/{workbookId}/publish:
    post:
      operationId: publishDashboard
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: path
          name: workbookId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishDashboardInput'
        description: PublishDashboardInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard'
          description: ''
      summary: Publish dashboard
      tags:
        - Workbooks
  /api/v1/deployments/{deploymentId}/workspace:
    get:
      operationId: workspaceObjects
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
        - in: query
          name: folderId
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: types
          schema:
            oneOf:
              - items:
                  enum:
                    - FOLDER
                    - WORKBOOK
                    - REPORT
                  type: string
                type: array
              - type: 'null'
        - in: query
          name: orderByField
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetWorkspaceObjectsQueryOrderByField'
              - type: 'null'
        - in: query
          name: orderByDirection
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetWorkspaceObjectsQueryOrderByDirection'
              - type: 'null'
        - in: query
          name: search
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkspaceConnectionResponse'
          description: ''
      summary: List workspace items
      tags:
        - Workspace
      x-mint:
        content: >-
          List the items in a deployment's workspace — folders, workbooks, and reports — in a single
          unified, paginated feed.


          By default this returns the items at the workspace root. Pass `folderId` to list the
          contents of a specific folder instead. Folders are always returned ahead of other item
          types so they render at the top of a listing.


          Supported query parameters:

          - `folderId` — list the contents of this folder (omit for the root).

          - `types` — restrict the results to one or more item types (`FOLDER`, `WORKBOOK`,
          `REPORT`). Repeat the parameter to pass several.

          - `search` — case-insensitive substring match on item names; searches across all folders,
          not just the current level.

          - `orderByField` / `orderByDirection` — sort the non-folder items (e.g. by `name`,
          `updated_at`, `created_at`, or `viewer_last_viewed_at`).

          - `first` / `after` — cursor-based pagination.


          Results are scoped to the calling user: only items the user can access are returned.
  /api/v1/deployments/{deploymentId}/workspace/bulk-delete:
    post:
      operationId: bulkDeleteWorkspaceObjects
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkDeleteWorkspaceObjectsInput'
        description: BulkDeleteWorkspaceObjectsInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkDeleteWorkspaceObjectsPayload'
          description: ''
      summary: Delete workspace items in bulk
      tags:
        - Workspace
      x-mint:
        content: >-
          Delete up to 100 workspace items — workbooks, reports, and folders, mixed freely — in a
          single request.


          Request body:

          - `items` — the items to delete, each `{ type, id }` with `type` one of `WORKBOOK`,
          `REPORT`, `FOLDER`. Repeated references to the same item are collapsed, so the response
          holds exactly one entry per distinct item requested.


          **This endpoint is partially successful.** It returns `200` whenever the request itself is
          well formed, and reports each item's outcome separately:

          - `deleted` — the `(type, id)` of each item that was deleted.

          - `failed` — the items that were not deleted, each with the `(type, id)` requested and an
          `error` carrying the `status` and `message` the per-type delete endpoint would have
          returned for it (`403` when the caller lacks access, `404` when the item does not exist or
          belongs to another deployment, `400` when a folder still has sub-folders).


          An empty `failed` array means the whole batch applied. Items are deleted one at a time in
          the order given, each in its own transaction, so **deletions are not rolled back** when a
          later item fails — the response is the record of what was applied. Deleting a folder does
          not delete the workbooks, dashboards, and reports directly inside it: they are detached
          and returned to the workspace root, matching `DELETE /folders/:folderId`.


          Access is checked per item with the same rules as the per-type delete endpoints:
          **manage** access for a workbook or folder, and **edit** access plus the report-manage
          permission for a report.
  /api/v1/deployments/{deploymentId}/workspace/bulk-move:
    post:
      operationId: bulkMoveWorkspaceObjects
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkMoveWorkspaceObjectsInput'
        description: BulkMoveWorkspaceObjectsInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkMoveWorkspaceObjectsResponse'
          description: ''
      summary: Move workspace items in bulk
      tags:
        - Workspace
      x-mint:
        content: >-
          Move up to 100 workspace items — workbooks, reports, and folders, mixed freely — into one
          destination folder in a single request.


          Request body:

          - `items` — the items to move, each `{ type, id }` with `type` one of `WORKBOOK`,
          `REPORT`, `FOLDER`. Repeated references to the same item are collapsed, so the response
          holds exactly one entry per distinct item requested.

          - `folderId` — the destination folder id for the whole batch, or `null` to move the items
          to the workspace root. For a folder item this becomes its new parent.


          **This endpoint is partially successful.** It returns `200` whenever the request itself is
          well formed, and reports each item's outcome separately:

          - `moved` — the items that were moved, serialized exactly as `POST /workspace/move`
          returns them.

          - `failed` — the items that were not moved, each with the `(type, id)` requested and an
          `error` carrying the `status` and `message` the single-item move would have returned for
          it (`403` when the caller lacks access, `404` when the item does not exist or belongs to
          another deployment, `400` for an invalid move such as a folder into its own descendant).


          An empty `failed` array means the whole batch applied. Items are applied one at a time in
          the order given, each in its own transaction, so earlier moves are **not** rolled back
          when a later item fails — the response is the record of what was applied.


          Access is checked per item with the same rules as the single-item move, so a batch mixing
          items the caller may and may not move applies the permitted ones and reports the rest.
  /api/v1/deployments/{deploymentId}/workspace/move:
    post:
      operationId: moveWorkspaceObject
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MoveWorkspaceObjectInput'
        description: MoveWorkspaceObjectInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workbook'
          description: ''
      summary: Move a workspace item
      tags:
        - Workspace
      x-mint:
        content: >-
          Move any workspace item — a workbook, report, or folder — into a folder, in one unified
          endpoint. Returns the moved item.


          Request body:

          - `type` — the item type: `WORKBOOK`, `REPORT`, or `FOLDER`.

          - `id` — the id of the item to move.

          - `folderId` — the destination folder id, or `null` to move the item to the workspace
          root. For a folder, this becomes its new parent.


          Access requirements depend on the item type and mirror the per-type rules:

          - **Workbook** — manage access to the workbook, plus edit access to the destination folder
          when moving into one.

          - **Report** — edit access to the report (with the report-manage permission).

          - **Folder** — manage access to the folder being moved, plus manage or edit access to the
          destination parent folder.


          Moving a folder into one of its own descendants, or exceeding the maximum folder depth, is
          rejected with `400`. Returns `404` if the item does not exist or belongs to a different
          deployment.
  /api/v1/embed-tenants:
    get:
      operationId: listEmbedTenants
      parameters:
        - in: query
          name: search
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedTenantsPublicResponse'
          description: ''
      summary: List embed tenants
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          List the account's embed tenants, cursor-paginated. Supports `first`/`after` pagination
          and a case-insensitive `search` substring match on the tenant name. Requires an admin API
          key.
  /api/v1/embed-tenants/{embedTenantName}:
    delete:
      operationId: deleteEmbedTenant
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
        '204':
          description: Embed tenant deleted, or did not exist.
      summary: Delete embed tenant
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Deletes an embed tenant and everything inside it — users, groups, memberships, attributes,
          policies, and content — plus the tenant's `system:tenant:*` sharing group. Idempotent:
          deleting a tenant that does not exist succeeds. The name must already be in canonical form
          (lowercase, per the `embedTenantName` rule); unlike the routes below, a name that differs
          only in case is rejected with `400` rather than being lowercased, so a typo can never
          cascade-delete a tenant the caller did not name exactly.
  /api/v1/embed-tenants/{embedTenantName}/groups:
    get:
      operationId: getGroups
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupsConnectionResponse'
          description: ''
      summary: List embed groups
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Lists the embed tenant's own groups (`embed_user_groups`), cursor-paginated, newest first,
          each with its member count. These are the groups an embed session references through
          `tenantGroups`; the implicit `system:tenant:*` sharing group is not included.
    post:
      operationId: createGroup
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateEmbedGroupInput'
        description: CreateEmbedGroupInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupDTO'
          description: ''
      summary: Create an embed group
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Creates a group inside the embed tenant. The name must be unique within the tenant and may
          not start with `system:` (that prefix is reserved for platform-managed groups). The group
          is immediately usable as a `tenantGroups` entry when generating a creator-mode embed
          session, and reaches the data model as `system:tenant:{embedTenantName}:{name}`. Returns
          `400` if the name is taken or reserved.
  /api/v1/embed-tenants/{embedTenantName}/groups/{id}:
    delete:
      operationId: deleteGroup
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the group, as returned by the groups endpoints.
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
        '204':
          description: Group deleted.
      summary: Delete an embed group
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Deletes one of the embed tenant’s groups. Returns `400` while the group still has members
          — remove them first — and `404` if the group does not exist in this tenant.
    get:
      operationId: getGroup
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the group, as returned by the groups endpoints.
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupDTO'
          description: ''
      summary: Get an embed group
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Returns one of the embed tenant’s groups with its member count, or `404` if no such group
          exists in this tenant.
    patch:
      operationId: updateGroup
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the group, as returned by the groups endpoints.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateEmbedGroupInput'
        description: UpdateEmbedGroupInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserGroupDTO'
          description: ''
      summary: Update an embed group
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Updates a group’s description. The name is deliberately immutable: it is part of the
          security context an embed session carries (`system:tenant:{embedTenantName}:{name}`), so
          renaming would silently detach the data-model access policies written against it — create
          a new group instead. Pass an empty `description` to clear it.
  /api/v1/embed-tenants/{embedTenantName}/groups/{id}/users:
    delete:
      operationId: removeGroupMembers
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the group, as returned by the groups endpoints.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmbedGroupMembersInput'
        description: EmbedGroupMembersInput
        required: false
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
        '204':
          description: Members removed.
      summary: Remove embed group members
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Removes one or more embed users (1–1000 per request) from a group, identified the same way
          as when adding them — exactly one of `externalId` or `embedUserId` each. Only this group’s
          membership is dropped; the users themselves and their other groups are left alone, and
          unlike adding, an unknown `externalId` is never provisioned. Idempotent: removing a user
          who is not a member is a no-op. Returns `204 No Content`, or `404` if the group does not
          exist in this tenant.
    get:
      operationId: getGroupMembers
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the group, as returned by the groups endpoints.
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedUsersPublicResponse'
          description: ''
      summary: List embed group members
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Lists the embed users that belong to a group, cursor-paginated, most recently added first.
          Each member carries both its numeric `id` and its `externalId`. Returns `404` if the group
          does not exist in this tenant.
    post:
      operationId: addGroupMembers
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: path
          name: id
          required: true
          schema:
            type: integer
          description: Numeric id of the group, as returned by the groups endpoints.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmbedGroupMembersInput'
        description: EmbedGroupMembersInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedGroupMembersMutationResponse'
          description: ''
      summary: Add embed group members
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Adds one or more embed users (1–1000 per request) to a group. Each member is identified by
          exactly one of `externalId` (the id passed to `generate-session`) or `embedUserId` (the
          numeric id this API returns). An `externalId` that has never signed in is provisioned as
          an embed user, so groups can be populated ahead of a user’s first session; an unknown
          `embedUserId` is a `404` instead. Memberships are added, never replaced: the user’s other
          groups — including the account-wide `groups` that drive data-model access — are left
          untouched. Idempotent: the response buckets every requested member into `addedMembers` or
          `unchangedMembers`.
  /api/v1/embed-tenants/{embedTenantName}/user:
    post:
      operationId: provisionEmbedUser
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProvisionEmbedUserInput'
        description: ProvisionEmbedUserInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedUser'
          description: ''
      summary: Provision an embed user
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Creates or updates one embed user from the identity your own system knows. An embed user
          is otherwise created the first time they generate a session, so this is how an integration
          puts its own directory into Cube up front: a user provisioned here is immediately
          addressable — listable, searchable, assignable to groups, and selectable wherever the
          product offers a choice of users — before they have ever opened the embed.


          Idempotent, and the body is the desired state: provisioning an `externalId` that already
          exists updates it rather than failing. `email`, `userProfile.displayName` and
          `userProfile.picture` are overwritten when supplied and preserved when omitted; each group
          lane is REPLACED when supplied, preserved when omitted, and cleared by `[]`. The embed
          tenant itself is created on demand, so it need not exist yet.


          Everything set here is exactly what `generate-session` would have set, and a later session
          for the same `externalId` re-applies whatever it carries — so provisioning changes when a
          user exists, never what their session grants them.
  /api/v1/embed-tenants/{embedTenantName}/users:
    get:
      operationId: listEmbedUsers
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
        - in: query
          name: search
          schema:
            oneOf:
              - type: string
              - type: 'null'
            description: Case-insensitive substring match against the embed user’s email or external id.
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedUsersPublicResponse'
          description: ''
      summary: List embed users
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Lists the embed users belonging to one embed tenant, cursor-paginated and ordered by
          email. Alongside the numeric `id` this API uses, a user carries the `externalId` your
          integration knows it by (the id passed to `generate-session`) whenever it was recorded on
          the account — users provisioned before it was recorded come back without an `externalId`,
          though they stay addressable by it everywhere it is accepted as input. Use `search` to
          match a substring of the email or external id, or a complete external id, which resolves a
          user even when the response cannot echo it back.
    post:
      operationId: provisionEmbedUsers
      parameters:
        - in: path
          name: embedTenantName
          required: true
          schema:
            type: string
          description: Name of the embed tenant (the `embedTenantName` used to generate embed sessions).
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProvisionEmbedUsersInput'
        description: ProvisionEmbedUsersInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProvisionEmbedUsersResponse'
          description: ''
      summary: Provision embed users in bulk
      tags:
        - Embed Tenants
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Provisions up to 100 embed users in one request, each exactly as `POST
          /embed-tenants/{embedTenantName}/user` would. Use it to load a user directory into an
          embed tenant, and send further requests to cover a directory larger than one batch.


          **This endpoint is partially successful.** It returns `200` whenever the request itself is
          well formed, and reports each user separately:

          - `succeeded` — the users that were provisioned, in the order requested.

          - `failed` — the entries that were not, each with the `externalId` and an `error` carrying
          the `status` and `message` the single-user endpoint would have returned (`400` for a group
          name that does not exist, `429` once the tenant is at its embed-user limit).


          Users are applied one at a time in the order given, and earlier ones are not rolled back
          when a later one fails. Since provisioning is idempotent, resending the whole batch after
          fixing the failures is safe. A repeated `externalId` within one batch is applied once per
          entry, so the last one wins.
  /api/v1/embed/dashboard/{publicId}:
    get:
      operationId: getDashboard
      parameters:
        - in: path
          name: publicId
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Dashboard'
          description: ''
      summary: Get an embeddable dashboard
      tags:
        - Embed
      x-mint:
        content: >-
          Returns the dashboard identified by its `publicId` — including its reports/widgets —
          resolved within the caller's embed session scope, for rendering inside an embedded view.


          Access is authorized against the embed user: the dashboard is returned when the user owns
          its workbook, has been granted workbook access (folder-based or direct), holds
          `EmbedDashboardRead` on the dashboard, or when it has been shared with all embed users
          (creator-mode flow). Returns `404` if the dashboard does not exist or is not visible to
          the caller.


          Signed embedding additionally requires the dashboard to have "Allow signed embedding"
          enabled; the trusted screenshoter and creator-mode session flows are exempt. Returns `403`
          when embedding is not permitted for the dashboard.
    patch:
      operationId: updateDashboardEmbedding
      parameters:
        - in: path
          name: publicId
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDashboardEmbeddingInput'
        description: UpdateDashboardEmbeddingInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DashboardEmbeddingResponse'
          description: ''
      summary: Enable or disable signed embedding for a dashboard
      tags:
        - Embed
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Sets the dashboard's "Allow signed embedding" flag (`allowEmbed`), which gates the
          customer-signed embedding path: with the flag off, embed sessions fetching `GET
          /api/v1/embed/dashboard/{publicId}` receive `403`. Trusted cube-cloud session flows
          (screenshoter, creator mode) and dashboards shared with all embed users are not affected
          by this flag.


          Note that the flag alone does not make a dashboard embeddable — it must also be published
          and shared with the embed tenant. Returns `404` if the dashboard does not exist.
  /api/v1/embed/dashboard/{publicId}/python-run:
    post:
      operationId: postDashboardPythonRun
      parameters:
        - in: path
          name: publicId
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmbedPythonFilteredRunInput'
        description: EmbedPythonFilteredRunInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PythonAnalysisFilteredRun'
          description: ''
      summary: Run a python report over dashboard-filtered SQL
      tags:
        - Embed
      x-mint:
        content: >-
          Re-runs the Python analysis attached to one of this dashboard's reports over `sqlQuery` —
          the report's own query with the dashboard's filters and time grains already applied — and
          returns the result **without persisting it**.


          Authorized against the dashboard, exactly as `GET /api/v1/embed/dashboard/{publicId}` is.
          The `reportVersionId` must be one of that dashboard's published report snapshots and must
          belong to `reportId`; anything else returns `403`. The Python itself is read server-side
          from that snapshot — it is never supplied by the caller.


          The analysis runs under the calling embed user's own security context, so row-level
          security applies to the viewer, and the stored result other viewers see is left untouched.
          Results are cached briefly per (report, code, SQL, user); failures are not cached. Returns
          `403` when Python analysis is not enabled for the account.
  /api/v1/embed/generate-session:
    post:
      operationId: generateSession
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateSession'
        description: GenerateSessionDTO
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateSessionResponse'
          description: ''
      summary: Generate an embed session
      tags:
        - Embed
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Creates a one-time embed session for a deployment and returns its `sessionId`.


          The session captures the embed context that will be baked into the embed token once
          redeemed — the target `deploymentId`, the end user's identity (`externalId` / `email` /
          `userProfile`), their group memberships, `userAttributes`, and an optional
          `securityContext`. Exchange the returned `sessionId` for a signed embed JWT via `POST
          /api/v1/embed/session/token` (single use).


          The end user can be assigned to two independent kinds of group, which serve different
          purposes:


          - **`groups`** — global, tenant-wide groups for **data-model access control**. Their names
          are passed verbatim into the Cube security context (`cubeCloud.groups`), where your data
          model's `access_policy` rules use them to gate cubes, views, members, and
          row-/column-level filters. They must already exist in the tenant.

          - **`tenantGroups`** — per-embed-tenant groups for **sharing and organizing content within
          a single embed tenant** (e.g. sharing a workbook or dashboard with a group in Creator
          Mode). Requires `creatorMode: true` and `embedTenantName`; create them inline via
          `tenantGroupDefinitions`. In the security context they are namespaced as
          `system:tenant:{embedTenantName}:group:{group}`, so they never collide with a same-named
          global group.


          See the individual request-body fields for the full contract.


          `deploymentId` is required and the caller must have read access to it. Embedding must be
          enabled for the tenant, otherwise `403` is returned.
  /api/v1/embed/session/token:
    post:
      operationId: postTokenBySessionId
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostTokenBySessionIdInput'
        description: PostTokenBySessionIdInputDTO
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateEmbedTokenResponse'
          description: ''
      summary: Exchange a session for an embed token
      tags:
        - Embed
      x-mint:
        content: >-
          Exchanges a one-time embed session id (created via `POST /api/v1/embed/generate-session`)
          for a signed, short-lived embed JWT used to authenticate the embedded analytics in the
          browser.


          The session is **single-use**: it is consumed (deleted) on the first successful exchange,
          so a given `sessionId` can be redeemed only once. The returned token is signed with the
          tenant's embed secret, issued by `cubecloud`, and expires after 24 hours.


          This endpoint is unauthenticated — it is called from the embedding client and the session
          id itself is the credential. Returns `401` if the session id is unknown or has already
          been redeemed.
  /api/v1/github/installations:
    get:
      operationId: installations
      parameters:
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitHubInstallationsListResponse'
          description: ''
      summary: List the user's GitHub App installations (orgs/accounts)
      tags:
        - GitHub
  /api/v1/github/installations/{installationId}/repositories:
    get:
      operationId: repositories
      parameters:
        - in: path
          name: installationId
          required: true
          schema:
            type: integer
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitHubReposListResponse'
          description: ''
      summary: List repositories accessible to a GitHub App installation
      tags:
        - GitHub
  /api/v1/github/repositories/{owner}/{repo}/branches:
    get:
      operationId: branches
      parameters:
        - in: path
          name: owner
          required: true
          schema:
            type: string
        - in: path
          name: repo
          required: true
          schema:
            type: string
        - in: query
          name: installationId
          required: true
          schema:
            type: integer
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitHubBranchesListResponse'
          description: ''
      summary: List branches of a repository
      tags:
        - GitHub
  /api/v1/github/status:
    get:
      operationId: status
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitHubConnectStatusResponse'
          description: ''
      summary: Whether GitHub is linked, plus the link/install URLs
      tags:
        - GitHub
  /api/v1/oauth-integrations:
    get:
      operationId: listOAuthIntegrations
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/OAuthIntegration'
                type: array
          description: ''
      summary: List OAuth integrations
      tags:
        - OAuth Integrations
    post:
      operationId: createOAuthIntegration
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOAuthIntegrationInput'
        description: CreateOAuthIntegrationInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthIntegration'
          description: ''
      summary: Create OAuth integration
      tags:
        - OAuth Integrations
  /api/v1/oauth-integrations/{id}:
    delete:
      operationId: deleteOAuthIntegration
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Delete OAuth integration
      tags:
        - OAuth Integrations
    get:
      operationId: getOAuthIntegration
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthIntegration'
          description: ''
      summary: Get OAuth integration
      tags:
        - OAuth Integrations
    put:
      operationId: updateOAuthIntegration
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOAuthIntegrationInput'
        description: UpdateOAuthIntegrationInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthIntegration'
          description: ''
      summary: Update OAuth integration
      tags:
        - OAuth Integrations
  /api/v1/oidc-token-configs:
    get:
      operationId: listOidcTokenConfigs
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/OidcTokenConfig'
                type: array
          description: ''
      summary: List OIDC token configs
      tags:
        - OIDC Token Configs
    post:
      operationId: createOidcTokenConfig
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOidcTokenConfigInput'
        description: CreateOidcTokenConfigInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OidcTokenConfig'
          description: ''
      summary: Create OIDC token config
      tags:
        - OIDC Token Configs
  /api/v1/oidc-token-configs/{id}:
    delete:
      operationId: deleteOidcTokenConfig
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Delete OIDC token config
      tags:
        - OIDC Token Configs
    get:
      operationId: getOidcTokenConfig
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OidcTokenConfig'
          description: ''
      summary: Get OIDC token config
      tags:
        - OIDC Token Configs
    put:
      operationId: updateOidcTokenConfig
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOidcTokenConfigInput'
        description: UpdateOidcTokenConfigInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OidcTokenConfig'
          description: ''
      summary: Update OIDC token config
      tags:
        - OIDC Token Configs
  /api/v1/regions:
    get:
      operationId: listRegions
      parameters:
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegionsListResponse'
          description: ''
      summary: List regions
      tags:
        - Regions
      x-mint:
        content: >-
          Lists the regions available to the account, cursor-paginated via `first`/`after`. The
          legacy `data` field returns the full, unpaginated list and is deprecated — use `items` +
          `pageInfo` instead.
  /api/v1/spec:
    get:
      operationId: getSpec
      responses:
        '200':
          content:
            application/json:
              schema:
                additionalProperties: true
                type: object
          description: The OpenAPI 3.1 document
      summary: Get the OpenAPI specification
      tags:
        - OpenAPI Spec
      x-mint:
        content: >-
          The full OpenAPI 3.1 document for this API, as served by the build handling the request —
          every path, parameter, request body and schema. Intended for runtime discovery by clients
          and agents; `cube spec` wraps it with filtering.
  /api/v1/tenant/settings:
    get:
      operationId: getTenantSettings
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantSettings'
          description: ''
      summary: Get tenant settings
      tags:
        - Tenant Settings
    put:
      operationId: updateTenantSettings
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TenantSettingsInput'
        description: TenantSettingsInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantSettings'
          description: ''
      summary: Update tenant settings
      tags:
        - Tenant Settings
  /api/v1/usage-analytics/token:
    post:
      operationId: createToken
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UsageAnalyticsTokenResponse'
          description: ''
      summary: Issue a Cube API token for Usage Analytics
      tags:
        - Usage Analytics
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Issues a short-lived Cube API token for Cube's internal **Usage Analytics** deployment —
          the data shown on **Admin → Usage Analytics** — so you can query your own usage and
          billing data programmatically (REST API, BI tools, scripts) instead of only through the
          embedded page.


          The token is scoped to your account: it carries the same server-resolved security context
          as the embedded Usage Analytics page, so queries only ever see your own data. Send it as
          `Authorization: Bearer <token>` on requests to the returned `apiUrl` (the deployment's
          [Cube REST API](https://cube.dev/docs/product/apis-integrations/rest-api)).


          Tokens expire after 1 hour (see `expiresAt`). Issue a fresh one per session or scheduled
          refresh — issuing is idempotent and cheap.


          Requires Usage Analytics to be enabled for the account, otherwise `404` is returned.
  /api/v1/user-attribute-values:
    post:
      operationId: upsertUserAttributeValue
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserAttributeValueCreateInput'
        description: UserAttributeValueCreateInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAttributeValue'
          description: ''
      summary: Upsert user attribute value
      tags:
        - User Attribute Values
  /api/v1/user-attribute-values/{userId}:
    get:
      operationId: getUserAttributeValues
      parameters:
        - in: path
          name: userId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/UserAttributeValue'
                type: array
          description: ''
      summary: Get user attribute values
      tags:
        - User Attribute Values
  /api/v1/user-attributes:
    get:
      operationId: getUserAttributes
      parameters:
        - in: query
          name: offset
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: limit
          schema:
            oneOf:
              - type: integer
              - type: 'null'
        - in: query
          name: name
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: type
          schema:
            oneOf:
              - $ref: '#/components/schemas/GetUserAttributesQueryType'
              - type: 'null'
        - in: query
          name: after
          schema:
            type: string
        - in: query
          name: first
          schema:
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAttributesListResponse'
          description: ''
      summary: Get user attributes
      tags:
        - User Attributes
      x-mint:
        content: >-
          List user attributes, newest first, cursor-paginated via `first`/`after`. The legacy
          `offset`/`limit` query params and the `data`/`count` response fields are deprecated — use
          `items` + `pageInfo` instead.
    post:
      operationId: createUserAttribute
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserAttributeCreateInput'
        description: UserAttributeCreateInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAttribute'
          description: ''
      summary: Create user attribute
      tags:
        - User Attributes
  /api/v1/user-attributes/{id}:
    put:
      operationId: updateUserAttribute
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserAttributeUpdateInput'
        description: UserAttributeUpdateInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAttribute'
          description: ''
      summary: Update user attribute
      tags:
        - User Attributes
  /api/v1/user-oauth-tokens:
    get:
      operationId: listUserOAuthTokens
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/UserOAuthToken'
                type: array
          description: ''
      summary: List user OAuth tokens
      tags:
        - User OAuth Tokens
  /api/v1/user-oauth-tokens/{integrationId}:
    delete:
      operationId: revokeUserOAuthToken
      parameters:
        - in: path
          name: integrationId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Revoke user OAuth token
      tags:
        - User OAuth Tokens
    get:
      operationId: getUserOAuthToken
      parameters:
        - in: path
          name: integrationId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserOAuthToken'
          description: ''
      summary: Get user OAuth token
      tags:
        - User OAuth Tokens
  /api/v1/user-oauth-tokens/{integrationId}/initiate:
    post:
      operationId: initiateOAuthFlow
      parameters:
        - in: path
          name: integrationId
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Initiate OAuth flow
      tags:
        - User OAuth Tokens
  /api/v1/users:
    post:
      operationId: createUser
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserCreateInput'
        description: UserCreateInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: ''
      summary: Create user
      tags:
        - Users Admin
  /api/v1/users/bulk:
    post:
      operationId: bulkUserAction
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkUserActionInput'
        description: BulkUserActionInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkUserActionPayload'
          description: ''
      summary: Apply an action to many users
      tags:
        - Users Admin
      x-mint:
        content: >-
          **🔒 Admin only.** Requires administrator privileges — the authenticated principal (API
          key, embed JWT, or any bearer token) must belong to a user with the admin role.


          Apply one action to up to 100 users in a single request.


          Request body:

          - `action` — `DEACTIVATE` (revoke access and end the users' sessions), `ACTIVATE` (restore
          access to deactivated users), or `DELETE` (remove the users outright).

          - `userIds` — the users to act on. Repeated ids are collapsed, so the response holds
          exactly one entry per distinct user requested.


          **This endpoint is partially successful.** It returns `200` whenever the request itself is
          well formed, and reports each user's outcome separately:

          - `succeeded` — ids of the users the action was applied to.

          - `failed` — the users it was not applied to, each with an `error` carrying the `status`
          and `message` the single-user endpoint would have returned (`404` for an unknown id, `403`
          when a guard refuses the change).


          An empty `failed` array means the whole batch applied. Users are processed one at a time
          in the order given, each in its own transaction, so earlier changes are **not** rolled
          back when a later user fails — the response is the record of what was applied.


          Every guard of the single-user endpoints still applies, per user:

          - The caller's own id fails rather than the request: `DEACTIVATE` on self is `403`,
          `DELETE` on self is `400`.

          - A tenant must always keep at least one active, direct admin, so the action that would
          remove the last one fails with `403` while the rest of the batch still applies.


          Reapplying an action a user is already in (deactivating a deactivated user) succeeds as a
          no-op.
  /api/v1/users/me/settings:
    patch:
      operationId: updateMySettings
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserSettingsInput'
        description: UserSettings
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: ''
      summary: Update my settings
      tags:
        - Users
      x-mint:
        content: >-
          Merge a partial patch into the authenticated user's own settings. Omitted fields are left
          as they are; `sheets` merges field-by-field, and an explicit `null` clears it.
  /api/v1/users/{id}:
    delete:
      operationId: deleteUser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Delete user
      tags:
        - Users Admin
    put:
      operationId: updateUser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserUpdateInput'
        description: UserUpdateInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
          description: ''
      summary: Update user
      tags:
        - Users Admin
  /build/api/v1/deployments:
    post:
      operationId: createDeployment
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateDeploymentInput'
        description: CreateDeploymentInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
          description: ''
      summary: Create a deployment with an empty starter project and trigger its first build
      tags:
        - Deployment Creation
      x-mint:
        content: >-
          Scaffolds an empty starter project and triggers the first build. When `creationMethod` is
          `github`, no starter project is scaffolded — connect a repository afterwards via POST
          /build/api/v1/deployments/:deploymentId/github/connect.
  /build/api/v1/deployments/{deploymentId}/branches:
    delete:
      operationId: removeBranch
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: branchName
          required: true
          schema:
            type: string
        - in: query
          name: removeOnUpstream
          required: false
          schema:
            type: boolean
            default: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModelWriteResponse'
          description: ''
      summary: Delete a branch
      tags:
        - Data Model
      x-mint:
        content: >-
          Deletes the branch and its git ref — the API-side counterpart of pruning a branch in Cube
          Cloud, for callers that create branches per run (a CI job syncing dbt on every pull
          request, say) and would otherwise accumulate them forever. Child branches are re-parented
          onto the deleted branch’s own parent, and anyone viewing the branch in dev mode is moved
          back to the default branch, so a branch that is currently open is deleted rather than
          refused. The deploy branch cannot be deleted (400) and an unknown branch is a 404.


          `removeOnUpstream=true` additionally deletes the branch on the connected git provider
          (GitHub/GitLab). It defaults to `false`, so by default the branch is removed from Cube
          Cloud only and the ref on your own remote is left alone — a CI job cleaning up branches it
          created itself should opt in explicitly.


          `branchName` is a query parameter rather than a path segment because branch names contain
          slashes (`dbt-sync/main-20260817120000-a1b2c3d4`).
    get:
      operationId: listBranches
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BranchesListResponse'
          description: ''
      summary: List a deployment's branches
      tags:
        - Data Model
    post:
      operationId: createBranch
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBranchRequest'
        description: CreateBranchRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DevBranchResponse'
          description: ''
      summary: Create a branch (optionally entering dev mode on it)
      tags:
        - Data Model
  /build/api/v1/deployments/{deploymentId}/branches/staging-environment:
    put:
      operationId: setBranchStagingEnvironment
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetBranchStagingEnvironmentRequest'
        description: SetBranchStagingEnvironmentRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetBranchStagingEnvironmentResponse'
          description: ''
      summary: Enable or disable a branch's staging environment
      tags:
        - Data Model
      x-mint:
        content: >-
          Enabling a branch keeps its staging environment always active and accessible at
          `<deploymentUrl>/dev-mode/{branchName}/cubejs-api/v1`; disabled (the default) it is only
          active while the branch is viewed in Cube Cloud. Enabled branches are the ones listed by
          `GET /api/v1/deployments/{deploymentId}/environments?type=staging`. Only shared branches
          qualify — personal dev branches and the deploy branch are rejected.
  /build/api/v1/deployments/{deploymentId}/commit:
    post:
      operationId: commitChanges
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CommitChangesRequest'
        description: CommitChangesRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModelWriteResponse'
          description: ''
      summary: Commit (and push) the active branch's pending changes
      tags:
        - Data Model
  /build/api/v1/deployments/{deploymentId}/data-model/file-hashes:
    get:
      operationId: fileHashes
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: live
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
        - in: query
          name: branchName
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: useDeployProjectRoot
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                additionalProperties:
                  $ref: '#/components/schemas/FileHash'
                type: object
          description: Map of project-relative file path to its content hash
      summary: Content hashes of the current data-model files (for upload diffing)
      tags:
        - Data Model Uploads
  /build/api/v1/deployments/{deploymentId}/data-model/files:
    delete:
      operationId: removeFiles
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RemoveDataModelFilesInput'
        description: RemoveDataModelFilesInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModelWriteResponse'
          description: ''
      summary: Delete data-model source files
      tags:
        - Data Model
    get:
      operationId: listFiles
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: withContent
          required: false
          schema:
            type: boolean
        - in: query
          name: branchName
          required: false
          schema:
            type: string
        - in: query
          name: showLastCLIUpload
          required: false
          schema:
            type: boolean
        - in: query
          name: after
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: first
          schema:
            oneOf:
              - minimum: 1
                type: integer
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SourceTreeResponse'
          description: ''
      summary: List the data-model source files for a deployment
      tags:
        - Data Model
      x-mint:
        content: >-
          Returns the data-model file tree. `first`/`after` (from the shared cursor params) paginate
          the **top-level** tree nodes only — a single node can carry a large subtree, so this
          bounds the number of roots returned, not the total file count. Omit `first` to get the
          whole tree.
    put:
      operationId: updateFiles
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDataModelFilesInput'
        description: UpdateDataModelFilesInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModelWriteResponse'
          description: ''
      summary: Create or overwrite data-model source files
      tags:
        - Data Model
  /build/api/v1/deployments/{deploymentId}/data-model/files/rename:
    post:
      operationId: renameFiles
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenameDataModelFilesInput'
        description: RenameDataModelFilesInput
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModelWriteResponse'
          description: ''
      summary: Rename data-model source files
      tags:
        - Data Model
  /build/api/v1/deployments/{deploymentId}/data-model/upload/file:
    post:
      operationId: uploadFile
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: live
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
        - in: query
          name: branchName
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: useDeployProjectRoot
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
      requestBody:
        content:
          multipart/form-data:
            schema:
              allOf:
                - $ref: '#/components/schemas/UploadFileBody'
                - type: object
                  properties:
                    file:
                      type: string
                      format: binary
      responses:
        '200':
          content:
            application/json: {}
          description: Successful response
      summary: Upload a single file into an open transaction
      tags:
        - Data Model Uploads
  /build/api/v1/deployments/{deploymentId}/data-model/upload/finish:
    post:
      operationId: finishUpload
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: live
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
        - in: query
          name: branchName
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: useDeployProjectRoot
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinishUploadBody'
        description: FinishUploadBody
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinishUploadResponse'
          description: ''
      summary: Finish the upload transaction (prune removed files) and trigger a build
      tags:
        - Data Model Uploads
  /build/api/v1/deployments/{deploymentId}/data-model/upload/start:
    post:
      operationId: startUpload
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: live
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
        - in: query
          name: branchName
          schema:
            oneOf:
              - type: string
              - type: 'null'
        - in: query
          name: useDeployProjectRoot
          schema:
            oneOf:
              - type: boolean
              - type: 'null'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StartUploadResponse'
          description: ''
      summary: Start a data-model upload transaction
      tags:
        - Data Model Uploads
  /build/api/v1/deployments/{deploymentId}/data-model/validate:
    get:
      operationId: validateDataModel
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
        - in: query
          name: branchName
          required: false
          schema:
            type: string
        - in: query
          name: devMode
          required: false
          schema:
            type: boolean
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModelValidationResponse'
          description: ''
      summary: Compile a deployment's data model and report compilation errors
      tags:
        - Data Model
      x-mint:
        content: >-
          Asks the branch's own Cube runtime for `GET /cubejs-api/v1/meta` — the same call the
          console makes in dev mode — so the verdict is the one that branch's API would give. With
          neither parameter it validates the deploy branch (production). `branchName` validates a
          named branch, and `devMode=true` validates the caller's active dev-mode branch; the two
          are mutually exclusive. Answers 200 with `valid: false` and the compiler's errors when the
          model doesn't compile — a broken model is a result, not a request error.
  /build/api/v1/deployments/{deploymentId}/dev-mode:
    delete:
      operationId: stopDevMode
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModelWriteResponse'
          description: ''
      summary: Exit dev mode
      tags:
        - Data Model
    post:
      operationId: startDevMode
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartDevModeRequest'
        description: StartDevModeRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DevBranchResponse'
          description: ''
      summary: Enter dev mode (switch to a branch)
      tags:
        - Data Model
  /build/api/v1/deployments/{deploymentId}/github/connect:
    post:
      operationId: connect
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectGitHubRequest'
        description: ConnectGitHubRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Deployment'
          description: ''
      summary: Connect a deployment to a GitHub repository and trigger a build
      tags:
        - GitHub Connection
  /build/api/v1/deployments/{deploymentId}/merge:
    post:
      operationId: mergeIntoParentBranch
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MergeIntoParentBranchRequest'
        description: MergeIntoParentBranchRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MergeResponse'
          description: ''
      summary: Merge a branch into its parent branch (git-flow merge)
      tags:
        - Data Model
  /build/api/v1/deployments/{deploymentId}/merge-to-default:
    post:
      operationId: mergeToDefaultBranch
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MergeToDefaultBranchRequest'
        description: MergeToDefaultBranchRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MergeResponse'
          description: ''
      summary: Merge a branch straight into the deploy (default) branch
      tags:
        - Data Model
  /build/api/v1/deployments/{deploymentId}/pull:
    post:
      operationId: pull
      parameters:
        - in: path
          name: deploymentId
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PullRequest'
        description: PullRequest
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PullResponse'
          description: ''
      summary: Pull the latest for a branch from its remote and rebuild if changed
      tags:
        - Data Model
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Token authentication. Send `Authorization: Bearer <YOUR_TOKEN>`.'
  schemas:
    AddNotificationRecipientsInput:
      properties:
        recipients:
          description: Recipients to subscribe (1–1000 per request)
          items:
            $ref: '#/components/schemas/NotificationRecipientInput'
          maxItems: 1000
          minItems: 1
          type: array
      required:
        - recipients
      type: object
    AdvanceCreationStepInput:
      properties:
        creationStep:
          $ref: '#/components/schemas/CreationStep'
      required:
        - creationStep
      type: object
    AppConfigResponse:
      properties:
        appTheme:
          oneOf:
            - $ref: '#/components/schemas/AppTheme'
            - type: 'null'
        applyThemeGlobally:
          type: boolean
        creatorMode:
          oneOf:
            - $ref: '#/components/schemas/CreatorMode'
            - type: 'null'
        embedding:
          oneOf:
            - $ref: '#/components/schemas/EmbedSettings'
            - type: 'null'
        sheetsUi:
          oneOf:
            - $ref: '#/components/schemas/SheetsUiSettings'
            - type: 'null'
        timezoneSettings:
          oneOf:
            - $ref: '#/components/schemas/TimezoneSettings'
            - type: 'null'
      required:
        - applyThemeGlobally
      type: object
    AppTheme:
      properties:
        dark:
          $ref: '#/components/schemas/AppThemeScheme'
          deprecated: true
          description: 'Deprecated: use palette and logoUrl instead.'
        light:
          $ref: '#/components/schemas/AppThemeScheme'
          deprecated: true
          description: 'Deprecated: use palette and logoUrl instead.'
        logoUrl:
          type: string
        palette:
          $ref: '#/components/schemas/AppThemePalette'
        typography:
          oneOf:
            - $ref: '#/components/schemas/AppThemeTypography'
            - type: 'null'
      required:
        - palette
        - logoUrl
        - light
        - dark
      type: object
    AppThemeCodePalette:
      properties:
        saturation:
          oneOf:
            - maximum: 100
              type: number
              minimum: 0
            - type: 'null'
      type: object
    AppThemeFontRef:
      properties:
        fontRef:
          type: string
        fontWeight:
          type: number
      required:
        - fontRef
        - fontWeight
      type: object
    AppThemePalette:
      properties:
        accent:
          oneOf:
            - $ref: '#/components/schemas/AppThemePaletteSeed'
            - type: 'null'
        base:
          oneOf:
            - $ref: '#/components/schemas/AppThemePaletteSeed'
            - type: 'null'
        contrastLevel:
          oneOf:
            - maximum: 100
              type: number
              minimum: 0
            - type: 'null'
        pastel:
          oneOf:
            - type: boolean
            - type: 'null'
        surfaceMode:
          oneOf:
            - $ref: '#/components/schemas/AppThemeSurfaceMode'
            - type: 'null'
        themes:
          oneOf:
            - $ref: '#/components/schemas/AppThemePaletteThemes'
            - type: 'null'
      type: object
    AppThemePaletteSeed:
      properties:
        color:
          oneOf:
            - type: string
            - type: 'null'
        hue:
          oneOf:
            - maximum: 360
              type: number
              minimum: 0
            - type: 'null'
        saturation:
          oneOf:
            - maximum: 100
              type: number
              minimum: 0
            - type: 'null'
      type: object
    AppThemePaletteThemes:
      properties:
        code:
          oneOf:
            - $ref: '#/components/schemas/AppThemeCodePalette'
            - type: 'null'
        danger:
          oneOf:
            - $ref: '#/components/schemas/AppThemePaletteSeed'
            - type: 'null'
        note:
          oneOf:
            - $ref: '#/components/schemas/AppThemePaletteSeed'
            - type: 'null'
        success:
          oneOf:
            - $ref: '#/components/schemas/AppThemePaletteSeed'
            - type: 'null'
        warning:
          oneOf:
            - $ref: '#/components/schemas/AppThemePaletteSeed'
            - type: 'null'
      type: object
    AppThemeScheme:
      properties:
        accentColor:
          type: string
        backgroundColor:
          type: string
        contrast:
          type: number
        foregroundColor:
          type: string
        logoUrl:
          type: string
      required:
        - accentColor
        - backgroundColor
        - foregroundColor
        - contrast
        - logoUrl
      type: object
    AppThemeSurfaceMode:
      enum:
        - neutral
        - tinted
      type: string
    AppThemeTypography:
      properties:
        body:
          $ref: '#/components/schemas/AppThemeFontRef'
        fonts:
          items:
            $ref: '#/components/schemas/ThemeFont'
          type: array
        heading:
          $ref: '#/components/schemas/AppThemeFontRef'
      required:
        - fonts
        - body
        - heading
      type: object
    BranchResponse:
      properties:
        id:
          type: integer
        isStagingEnvironmentEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        lastHash:
          oneOf:
            - type: string
            - type: 'null'
        name:
          type: string
        parentBranch:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - id
        - name
      type: object
    BranchesListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/BranchResponse'
          type: array
        items:
          items:
            $ref: '#/components/schemas/BranchResponse'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    BuildStatusResponse:
      properties:
        branchName:
          type: string
        buildJobId:
          oneOf:
            - type: integer
            - type: 'null'
        deploymentId:
          type: integer
        deploymentStatus:
          oneOf:
            - type: string
            - type: 'null'
        errorText:
          oneOf:
            - type: string
            - type: 'null'
        filesHash:
          oneOf:
            - type: string
            - type: 'null'
        lastHash:
          oneOf:
            - type: string
            - type: 'null'
        mode:
          type: string
        status:
          type: string
        updatedAt:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - deploymentId
        - branchName
        - mode
        - status
      type: object
    BulkActionError:
      properties:
        message:
          type: string
        status:
          type: integer
      required:
        - status
        - message
      type: object
    BulkDeleteWorkspaceObjectsInput:
      properties:
        items:
          items:
            $ref: '#/components/schemas/WorkspaceItemRefInput'
          maxItems: 100
          minItems: 1
          type: array
      required:
        - items
      type: object
    BulkDeleteWorkspaceObjectsPayload:
      properties:
        deleted:
          items:
            $ref: '#/components/schemas/WorkspaceItemRef'
          type: array
        failed:
          items:
            $ref: '#/components/schemas/WorkspaceBulkFailure'
          type: array
      required:
        - deleted
        - failed
      type: object
    BulkMoveWorkspaceObjectsInput:
      properties:
        folderId:
          oneOf:
            - type: integer
            - type: 'null'
        items:
          items:
            $ref: '#/components/schemas/WorkspaceItemRefInput'
          maxItems: 100
          minItems: 1
          type: array
      required:
        - items
      type: object
    BulkMoveWorkspaceObjectsResponse:
      properties:
        failed:
          items:
            $ref: '#/components/schemas/WorkspaceBulkFailure'
          type: array
        moved:
          items:
            $ref: '#/components/schemas/Workbook'
          type: array
      required:
        - moved
        - failed
      type: object
    BulkUserActionFailure:
      properties:
        error:
          $ref: '#/components/schemas/BulkActionError'
        userId:
          type: integer
      required:
        - userId
        - error
      type: object
    BulkUserActionInput:
      properties:
        action:
          $ref: '#/components/schemas/BulkUserActionInputAction'
        userIds:
          items:
            type: integer
          maxItems: 100
          minItems: 1
          type: array
      required:
        - action
        - userIds
      type: object
    BulkUserActionInputAction:
      enum:
        - DEACTIVATE
        - ACTIVATE
        - DELETE
      type: string
    BulkUserActionPayload:
      properties:
        action:
          $ref: '#/components/schemas/BulkUserActionResponseAction'
        failed:
          items:
            $ref: '#/components/schemas/BulkUserActionFailure'
          type: array
        succeeded:
          items:
            type: integer
          type: array
      required:
        - action
        - succeeded
        - failed
      type: object
    BulkUserActionResponseAction:
      enum:
        - DEACTIVATE
        - ACTIVATE
        - DELETE
      type: string
    ColumnFormatOverride:
      properties:
        decimalPlaces:
          oneOf:
            - type: integer
            - type: 'null'
        type:
          $ref: '#/components/schemas/ColumnFormatOverrideDtoType'
      required:
        - type
      type: object
    ColumnFormatOverrideDtoType:
      enum:
        - currency
        - percent
        - number
      type: string
    CommitChangesRequest:
      properties:
        exitDevMode:
          oneOf:
            - type: boolean
            - type: 'null'
        message:
          oneOf:
            - type: string
            - type: 'null'
        resolveMergeConflict:
          oneOf:
            - type: boolean
            - type: 'null'
      type: object
    ConnectGitHubRequest:
      properties:
        deployBranchName:
          oneOf:
            - type: string
            - type: 'null'
        deployProjectRoot:
          oneOf:
            - type: string
            - type: 'null'
        installationId:
          type: integer
        isNewRepo:
          oneOf:
            - type: boolean
            - type: 'null'
        name:
          minLength: 1
          type: string
        private:
          oneOf:
            - type: boolean
            - type: 'null'
      required:
        - installationId
        - name
      type: object
    ConnectReportToWorkbookInput:
      properties:
        anchorCell:
          oneOf:
            - type: string
            - type: 'null'
        endResultCell:
          oneOf:
            - type: string
            - type: 'null'
        externalWorkbookId:
          type: string
        host:
          oneOf:
            - $ref: '#/components/schemas/ConnectReportToWorkbookInputHost'
            - type: 'null'
        placementId:
          oneOf:
            - type: string
            - type: 'null'
        resultLocation:
          type: string
        sheetId:
          oneOf:
            - type: string
            - type: 'null'
        sheetName:
          oneOf:
            - type: string
            - type: 'null'
        workbookName:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - externalWorkbookId
        - resultLocation
      type: object
    ConnectReportToWorkbookInputHost:
      enum:
        - GOOGLE_SHEETS
        - EXCEL
      type: string
    ControlThemeBorderSectionInput:
      properties:
        color:
          oneOf:
            - type: string
            - type: 'null'
        radius:
          oneOf:
            - type: string
            - type: 'null'
        style:
          oneOf:
            - type: string
            - type: 'null'
        width:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    ControlThemeSectionInput:
      properties:
        backgroundColor:
          oneOf:
            - type: string
            - type: 'null'
        border:
          oneOf:
            - $ref: '#/components/schemas/ControlThemeBorderSectionInput'
            - type: 'null'
        padding:
          oneOf:
            - type: string
            - type: 'null'
        title:
          oneOf:
            - $ref: '#/components/schemas/ControlThemeTitleSectionInput'
            - type: 'null'
      type: object
    ControlThemeTitleSectionInput:
      properties:
        color:
          oneOf:
            - type: string
            - type: 'null'
        fontFamily:
          oneOf:
            - type: string
            - type: 'null'
        fontSize:
          oneOf:
            - type: string
            - type: 'null'
        fontWeight:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    CreateBranchRequest:
      properties:
        activate:
          oneOf:
            - type: boolean
            - type: 'null'
        from:
          oneOf:
            - type: string
            - type: 'null'
        name:
          type: string
      required:
        - name
      type: object
    CreateDeploymentEnvironmentTokenInput:
      properties:
        expires_in:
          oneOf:
            - maximum: 3600
              type: integer
              minimum: 1
            - type: 'null'
        scopes:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        security_context:
          additionalProperties: true
          not:
            type: 'null'
          type: object
      required:
        - security_context
      type: object
    CreateDeploymentInput:
      properties:
        cloudProvider:
          $ref: '#/components/schemas/CreateDeploymentInputCloudProvider'
        creationMethod:
          oneOf:
            - $ref: '#/components/schemas/CreateDeploymentInputCreationMethod'
            - type: 'null'
        creationStep:
          $ref: '#/components/schemas/CreationStep'
        deployMode:
          oneOf:
            - $ref: '#/components/schemas/CreateDeploymentInputDeployMode'
            - type: 'null'
        isManaged:
          type: boolean
        name:
          type: string
        region:
          type: string
        targetPlatform:
          type: string
      required:
        - name
        - cloudProvider
        - isManaged
        - region
        - targetPlatform
        - creationStep
      type: object
    CreateDeploymentInputCloudProvider:
      enum:
        - cubecloud
        - aws
        - gcp
      type: string
    CreateDeploymentInputCreationMethod:
      enum:
        - upload
        - cubecloud
        - github
        - ssh
      type: string
    CreateDeploymentInputDeployMode:
      enum:
        - git
        - cli
      type: string
    CreateDeploymentTokenInput:
      properties:
        expiresIn:
          oneOf:
            - maximum: 86400
              type: integer
              minimum: 60
            - type: 'null'
          description: >-
            Token lifetime in seconds, between 60 and 86400. Omit to keep the historical default of
            24 hours (86400). Callers that hold the token outside a browser session — scripts, BI
            tools, scheduled jobs — should request a short lifetime and re-issue tokens instead.
      type: object
    CreateEmbedGroupInput:
      properties:
        description:
          oneOf:
            - maxLength: 500
              type: string
            - type: 'null'
          description: Optional human-readable description.
        name:
          description: >-
            Group name, unique within the embed tenant. The `system:` prefix is reserved and
            rejected.
          maxLength: 100
          minLength: 1
          type: string
      required:
        - name
      type: object
    CreateFolderInput:
      properties:
        name:
          maxLength: 255
          type: string
        parentId:
          oneOf:
            - type: integer
            - type: 'null'
        position:
          oneOf:
            - type: integer
            - type: 'null'
      required:
        - name
      type: object
    CreateNotificationInput:
      properties:
        customCron:
          oneOf:
            - type: string
            - type: 'null'
          description: Custom cron expression (required if scheduleType is CUSTOM)
        dashboardId:
          oneOf:
            - type: integer
            - type: 'null'
          description: >-
            Numeric id of the dashboard to run on the schedule. Provide this OR dashboardPublicId
            (exactly one).
        dashboardPublicId:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Public id of the dashboard to run on the schedule. Provide this OR dashboardId (exactly
            one).
        dayOfMonth:
          oneOf:
            - type: integer
            - type: 'null'
          description: Day of month (1-31)
        dayOfWeek:
          oneOf:
            - type: integer
            - type: 'null'
          description: Day of week (0-6, Sunday=0)
        filters:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardFilterInput'
              type: array
            - type: 'null'
          description: >-
            Dimension filters applied to the dashboard when the notification is rendered
            (substituted into the screenshot/PDF for every recipient).
        hour:
          oneOf:
            - type: integer
            - type: 'null'
          description: Hour of the day (0-23)
        minute:
          oneOf:
            - type: integer
            - type: 'null'
          description: Minute of the hour (0-59)
        notificationAiSummary:
          oneOf:
            - type: boolean
            - type: 'null'
          description: Include an AI-generated "what changed" summary in the notification body. Off by default.
        notificationEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        notificationFormat:
          oneOf:
            - $ref: '#/components/schemas/CreateNotificationInputNotificationFormat'
            - type: 'null'
        scheduleType:
          $ref: '#/components/schemas/CreateNotificationInputScheduleType'
        timeGrains:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardTimeGrainInput'
              type: array
            - type: 'null'
          description: Time-grain overrides applied to the dashboard when the notification is rendered.
        timezone:
          oneOf:
            - type: string
            - type: 'null'
          description: Timezone for the schedule (e.g. "America/New_York")
      required:
        - scheduleType
      type: object
    CreateNotificationInputNotificationFormat:
      enum:
        - png
        - pdf
      type: string
    CreateNotificationInputScheduleType:
      enum:
        - HOURLY
        - DAILY
        - WEEKLY
        - MONTHLY
        - CUSTOM
      type: string
    CreateOAuthIntegrationInput:
      properties:
        authUrl:
          format: url
          type: string
        clientId:
          type: string
        clientSecret:
          type: string
        config:
          additionalProperties: true
          type: object
        name:
          type: string
        redirectUri:
          format: url
          type: string
        scopes:
          items:
            type: string
          type: array
        tokenUrl:
          format: url
          type: string
        type:
          type: string
      required:
        - clientSecret
        - name
        - type
        - authUrl
        - tokenUrl
        - clientId
        - redirectUri
      type: object
    CreateOidcTokenConfigInput:
      properties:
        audienceType:
          type: string
        customAudience:
          oneOf:
            - type: string
            - type: 'null'
        customClaims:
          oneOf:
            - type: object
            - type: 'null'
        isEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        name:
          oneOf:
            - pattern: ^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$
              type: string
            - type: 'null'
        subFormat:
          oneOf:
            - pattern: ^(?:[A-Za-z0-9:_-]|\{(?:deployment_id|component|region)\})+$
              type: string
              maxLength: 200
            - type: 'null'
        targetEnvVar:
          oneOf:
            - pattern: ^[A-Z_][A-Z0-9_]*$
              type: string
              maxLength: 128
            - type: 'null'
      required:
        - audienceType
      type: object
    CreateReportInput:
      properties:
        endResultCell:
          oneOf:
            - type: string
            - type: 'null'
        externalWorkbookId:
          oneOf:
            - type: string
            - type: 'null'
        folderId:
          oneOf:
            - type: integer
            - type: 'null'
        host:
          oneOf:
            - $ref: '#/components/schemas/CreateReportInputHost'
            - type: 'null'
        jsonQuery:
          oneOf:
            - type: string
            - type: 'null'
        meta:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        name:
          oneOf:
            - type: string
            - type: 'null'
        pivotItems:
          oneOf:
            - $ref: '#/components/schemas/PivotItemsInput'
            - type: 'null'
        publicId:
          oneOf:
            - pattern: ^[0-9A-Za-z]+$
              type: string
              minLength: 12
              maxLength: 12
            - type: 'null'
        resultLocation:
          oneOf:
            - type: string
            - type: 'null'
        sheetId:
          oneOf:
            - type: string
            - type: 'null'
        source:
          oneOf:
            - $ref: '#/components/schemas/CreateReportInputSource'
            - type: 'null'
        sqlQuery:
          oneOf:
            - type: string
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        workbookId:
          oneOf:
            - type: integer
            - type: 'null'
        workbookName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    CreateReportInputHost:
      enum:
        - GOOGLE_SHEETS
        - EXCEL
      type: string
    CreateReportInputSource:
      enum:
        - GOOGLE_SHEETS
        - EXCEL
        - PLAYGROUND
        - D3
      type: string
    CreateWorkbookInput:
      properties:
        folderId:
          oneOf:
            - type: number
            - type: 'null'
        meta:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        name:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    CreationStep:
      enum:
        - project
        - upload
        - schema
        - github
        - ssh
        - databases
        - ready
        - demo
      type: string
    CreatorMode:
      properties:
        localizedTitles:
          oneOf:
            - items:
                $ref: '#/components/schemas/LocalizedValue'
              type: array
              maxItems: 50
            - type: 'null'
        showGeneratedSql:
          oneOf:
            - type: boolean
            - type: 'null'
        showSemanticSql:
          oneOf:
            - type: boolean
            - type: 'null'
        showWorkspaceTitle:
          oneOf:
            - type: boolean
            - type: 'null'
        workspaceTitle:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    CspsConfig:
      properties:
        awsRoleArn:
          oneOf:
            - type: string
            - type: 'null'
        azureClientId:
          oneOf:
            - type: string
            - type: 'null'
        azureContainer:
          oneOf:
            - type: string
            - type: 'null'
        azureStorageAccount:
          oneOf:
            - type: string
            - type: 'null'
        azureTenantId:
          oneOf:
            - type: string
            - type: 'null'
        enabled:
          type: boolean
        gcpServiceAccountEmail:
          oneOf:
            - type: string
            - type: 'null'
        gcpWorkloadIdentityProvider:
          oneOf:
            - type: string
            - type: 'null'
        gcsBucket:
          oneOf:
            - type: string
            - type: 'null'
        s3Bucket:
          oneOf:
            - type: string
            - type: 'null'
        s3Region:
          oneOf:
            - type: string
            - type: 'null'
        s3Sse:
          oneOf:
            - type: string
            - type: 'null'
        storageProvider:
          type: string
      required:
        - enabled
        - storageProvider
      type: object
    CspsConfigInput:
      properties:
        awsRoleArn:
          oneOf:
            - type: string
            - type: 'null'
        azureClientId:
          oneOf:
            - type: string
            - type: 'null'
        azureContainer:
          oneOf:
            - type: string
            - type: 'null'
        azureStorageAccount:
          oneOf:
            - type: string
            - type: 'null'
        azureTenantId:
          oneOf:
            - type: string
            - type: 'null'
        enabled:
          type: boolean
        gcpServiceAccountEmail:
          oneOf:
            - type: string
            - type: 'null'
        gcpWorkloadIdentityProvider:
          oneOf:
            - type: string
            - type: 'null'
        gcsBucket:
          oneOf:
            - type: string
            - type: 'null'
        s3Bucket:
          oneOf:
            - type: string
            - type: 'null'
        s3Region:
          oneOf:
            - type: string
            - type: 'null'
        s3Sse:
          oneOf:
            - type: string
            - type: 'null'
        storageProvider:
          type: string
      required:
        - enabled
        - storageProvider
      type: object
    Dashboard:
      properties:
        allowEmbed:
          type: boolean
        config:
          $ref: '#/components/schemas/DashboardConfig'
        createdBy:
          oneOf:
            - type: integer
            - type: 'null'
        deploymentId:
          type: integer
        description:
          oneOf:
            - type: string
            - type: 'null'
        fromSharedWorkspace:
          oneOf:
            - type: boolean
            - type: 'null'
        id:
          type: integer
        publicId:
          type: string
        reportSnapshots:
          items:
            $ref: '#/components/schemas/ReportSnapshot'
          type: array
        restrictDataDownload:
          oneOf:
            - type: boolean
            - type: 'null'
        status:
          $ref: '#/components/schemas/DashboardDtoStatus'
        title:
          oneOf:
            - type: string
            - type: 'null'
        useBoardDashboards:
          oneOf:
            - type: boolean
            - type: 'null'
        versionId:
          type: integer
        versionNumber:
          type: integer
        workbookId:
          type: integer
      required:
        - id
        - publicId
        - deploymentId
        - workbookId
        - status
        - allowEmbed
        - config
        - versionNumber
        - versionId
        - reportSnapshots
      type: object
    DashboardAppManifest:
      properties:
        dependencies:
          oneOf:
            - type: object
              additionalProperties:
                type: string
            - type: 'null'
        version:
          oneOf:
            - type: integer
            - type: 'null'
      type: object
    DashboardAppManifestInput:
      properties:
        dependencies:
          oneOf:
            - type: object
              additionalProperties:
                type: string
            - type: 'null'
        version:
          oneOf:
            - type: integer
            - type: 'null'
      type: object
    DashboardAppSource:
      properties:
        entry:
          oneOf:
            - maxLength: 255
              type: string
            - type: 'null'
        files:
          oneOf:
            - type: object
              additionalProperties:
                type: string
            - type: 'null'
        html:
          oneOf:
            - type: string
            - type: 'null'
        manifest:
          oneOf:
            - $ref: '#/components/schemas/DashboardAppManifest'
            - type: 'null'
      type: object
    DashboardAppSourceInput:
      properties:
        entry:
          oneOf:
            - maxLength: 255
              type: string
            - type: 'null'
        files:
          oneOf:
            - type: object
              additionalProperties:
                type: string
            - type: 'null'
        html:
          oneOf:
            - type: string
            - type: 'null'
        manifest:
          oneOf:
            - $ref: '#/components/schemas/DashboardAppManifestInput'
            - type: 'null'
      type: object
    DashboardBreakpointCols:
      properties:
        lg:
          oneOf:
            - type: integer
            - type: 'null'
        md:
          oneOf:
            - type: integer
            - type: 'null'
        sm:
          oneOf:
            - type: integer
            - type: 'null'
        xs:
          oneOf:
            - type: integer
            - type: 'null'
        xxs:
          oneOf:
            - type: integer
            - type: 'null'
      title: DashboardBreakpointColsDto
      type: object
    DashboardBreakpointColsInput:
      properties:
        lg:
          oneOf:
            - type: integer
            - type: 'null'
        md:
          oneOf:
            - type: integer
            - type: 'null'
        sm:
          oneOf:
            - type: integer
            - type: 'null'
        xs:
          oneOf:
            - type: integer
            - type: 'null'
        xxs:
          oneOf:
            - type: integer
            - type: 'null'
      title: DashboardBreakpointColsInput
      type: object
    DashboardBreakpoints:
      properties:
        lg:
          oneOf:
            - type: integer
            - type: 'null'
        md:
          oneOf:
            - type: integer
            - type: 'null'
        sm:
          oneOf:
            - type: integer
            - type: 'null'
        xs:
          oneOf:
            - type: integer
            - type: 'null'
        xxs:
          oneOf:
            - type: integer
            - type: 'null'
      title: DashboardBreakpointsDto
      type: object
    DashboardBreakpointsInput:
      properties:
        lg:
          oneOf:
            - type: integer
            - type: 'null'
        md:
          oneOf:
            - type: integer
            - type: 'null'
        sm:
          oneOf:
            - type: integer
            - type: 'null'
        xs:
          oneOf:
            - type: integer
            - type: 'null'
        xxs:
          oneOf:
            - type: integer
            - type: 'null'
      title: DashboardBreakpointsInput
      type: object
    DashboardConfig:
      properties:
        app:
          oneOf:
            - $ref: '#/components/schemas/DashboardAppSource'
            - type: 'null'
        description:
          oneOf:
            - type: string
            - type: 'null'
        kind:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfigKind'
            - type: 'null'
        layout:
          oneOf:
            - $ref: '#/components/schemas/DashboardLayout'
            - type: 'null'
        settings:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        theme:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        widgets:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardWidget'
              type: array
            - type: 'null'
      type: object
    DashboardConfigInput:
      properties:
        app:
          oneOf:
            - $ref: '#/components/schemas/DashboardAppSourceInput'
            - type: 'null'
        description:
          oneOf:
            - type: string
            - type: 'null'
        kind:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfigInputKind'
            - type: 'null'
        layout:
          oneOf:
            - $ref: '#/components/schemas/DashboardLayoutInput'
            - type: 'null'
        settings:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        theme:
          oneOf:
            - $ref: '#/components/schemas/DashboardThemeInput'
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        widgets:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardWidgetInput'
              type: array
            - type: 'null'
      type: object
    DashboardConfigInputKind:
      enum:
        - CLASSIC
        - APP
      type: string
    DashboardConfigKind:
      enum:
        - CLASSIC
        - APP
      type: string
    DashboardDtoStatus:
      enum:
        - draft
        - published
        - archived
      type: string
    DashboardEmbeddingResponse:
      properties:
        allowEmbed:
          type: boolean
        publicId:
          type: string
      required:
        - publicId
        - allowEmbed
      type: object
    DashboardFilter:
      properties:
        caseSensitive:
          oneOf:
            - {}
            - type: 'null'
        endInclusive:
          oneOf:
            - {}
            - type: 'null'
        member:
          type: string
        operator:
          oneOf:
            - $ref: '#/components/schemas/DashboardFilterOperator'
            - type: 'null'
        startInclusive:
          oneOf:
            - {}
            - type: 'null'
        value:
          oneOf:
            - oneOf:
                - type: string
                - type: number
                - type: boolean
                - type: array
                  items: {}
            - type: 'null'
      required:
        - member
      type: object
    DashboardFilterInput:
      properties:
        caseSensitive:
          oneOf:
            - {}
            - type: 'null'
          description: 'For string filters: whether matching is case-sensitive'
        endInclusive:
          oneOf:
            - {}
            - type: 'null'
          description: 'For between filters: whether the end bound is inclusive'
        member:
          description: Dimension path, e.g. "Orders.status"
          pattern: .+\..+
          type: string
        operator:
          oneOf:
            - $ref: '#/components/schemas/DashboardFilterInputOperator'
            - type: 'null'
        startInclusive:
          oneOf:
            - {}
            - type: 'null'
          description: 'For between filters: whether the start bound is inclusive'
        value:
          oneOf:
            - oneOf:
                - type: string
                - type: number
                - type: boolean
                - type: array
                  items: {}
            - type: 'null'
          description: >-
            Filter value. Omit for is_null / is_not_null / is_empty / is_not_empty; provide a
            2-element [start, end] array for between.
      required:
        - member
      type: object
    DashboardFilterInputOperator:
      enum:
        - equals
        - not_equals
        - greater_than
        - greater_than_or_equal
        - less_than
        - less_than_or_equal
        - contains
        - not_contains
        - starts_with
        - not_starts_with
        - ends_with
        - not_ends_with
        - is_null
        - is_not_null
        - is_empty
        - is_not_empty
        - between
        - custom
      type: string
    DashboardFilterOperator:
      enum:
        - equals
        - not_equals
        - greater_than
        - greater_than_or_equal
        - less_than
        - less_than_or_equal
        - contains
        - not_contains
        - starts_with
        - not_starts_with
        - ends_with
        - not_ends_with
        - is_null
        - is_not_null
        - is_empty
        - is_not_empty
        - between
        - custom
      type: string
    DashboardLayout:
      properties:
        breakpoints:
          oneOf:
            - $ref: '#/components/schemas/DashboardBreakpoints'
            - type: 'null'
        cols:
          oneOf:
            - $ref: '#/components/schemas/DashboardBreakpointCols'
            - type: 'null'
        containerPadding:
          oneOf:
            - items:
                type: integer
              type: array
            - type: 'null'
        margin:
          oneOf:
            - items:
                type: integer
              type: array
            - type: 'null'
        rowHeight:
          oneOf:
            - type: integer
            - type: 'null'
      type: object
    DashboardLayoutInput:
      properties:
        breakpoints:
          oneOf:
            - $ref: '#/components/schemas/DashboardBreakpointsInput'
            - type: 'null'
        cols:
          oneOf:
            - $ref: '#/components/schemas/DashboardBreakpointColsInput'
            - type: 'null'
        containerPadding:
          oneOf:
            - items:
                type: integer
              type: array
            - type: 'null'
        margin:
          oneOf:
            - items:
                type: integer
              type: array
            - type: 'null'
        rowHeight:
          oneOf:
            - type: integer
            - type: 'null'
      type: object
    DashboardResponsiveLayouts:
      properties:
        lg:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPosition'
            - type: 'null'
        md:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPosition'
            - type: 'null'
        sm:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPosition'
            - type: 'null'
        xs:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPosition'
            - type: 'null'
        xxs:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPosition'
            - type: 'null'
      type: object
    DashboardResponsiveLayoutsInput:
      properties:
        lg:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPositionInput'
            - type: 'null'
        md:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPositionInput'
            - type: 'null'
        sm:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPositionInput'
            - type: 'null'
        xs:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPositionInput'
            - type: 'null'
        xxs:
          oneOf:
            - $ref: '#/components/schemas/DashboardWidgetPositionInput'
            - type: 'null'
      type: object
    DashboardThemeInput:
      properties:
        backgroundColor:
          oneOf:
            - type: string
            - type: 'null'
        controls:
          oneOf:
            - $ref: '#/components/schemas/ControlThemeSectionInput'
            - type: 'null'
        dashboard:
          oneOf:
            - $ref: '#/components/schemas/DashboardThemeSectionInput'
            - type: 'null'
        fontFamily:
          oneOf:
            - type: string
            - type: 'null'
        primaryColor:
          oneOf:
            - type: string
            - type: 'null'
        themeId:
          oneOf:
            - type: string
            - type: 'null'
        widgets:
          oneOf:
            - $ref: '#/components/schemas/WidgetThemeSectionInput'
            - type: 'null'
      type: object
    DashboardThemeSectionInput:
      properties:
        backgroundColor:
          oneOf:
            - type: string
            - type: 'null'
        padding:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    DashboardTimeGrain:
      properties:
        grain:
          type: string
        member:
          type: string
      required:
        - member
        - grain
      type: object
    DashboardTimeGrainInput:
      properties:
        grain:
          description: Granularity, e.g. "day", "week", "month"
          type: string
        member:
          description: Time dimension path, e.g. "Orders.created_at"
          pattern: .+\..+
          type: string
      required:
        - member
        - grain
      type: object
    DashboardWidget:
      properties:
        config:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        id:
          type: string
        position:
          $ref: '#/components/schemas/DashboardWidgetPosition'
        responsiveLayouts:
          oneOf:
            - $ref: '#/components/schemas/DashboardResponsiveLayouts'
            - type: 'null'
        style:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        type:
          $ref: '#/components/schemas/DashboardWidgetDtoType'
      required:
        - id
        - type
        - position
      type: object
    DashboardWidgetDtoType:
      enum:
        - CHART
        - TEXT
        - FILTER
        - AI
        - TIME_GRAIN
        - FIELD
        - PARENT
        - SPACER
        - DIVIDER
        - CONTAINER
      type: string
    DashboardWidgetInput:
      properties:
        config:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        id:
          maxLength: 128
          type: string
        position:
          $ref: '#/components/schemas/DashboardWidgetPositionInput'
        responsiveLayouts:
          oneOf:
            - $ref: '#/components/schemas/DashboardResponsiveLayoutsInput'
            - type: 'null'
        style:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        type:
          $ref: '#/components/schemas/DashboardWidgetInputType'
      required:
        - id
        - type
        - position
      type: object
    DashboardWidgetInputType:
      enum:
        - CHART
        - TEXT
        - FILTER
        - AI
        - TIME_GRAIN
        - FIELD
        - PARENT
        - SPACER
        - DIVIDER
        - CONTAINER
      type: string
    DashboardWidgetPosition:
      properties:
        h:
          type: integer
        w:
          type: integer
        x:
          type: integer
        'y':
          type: integer
      required:
        - x
        - 'y'
        - w
        - h
      type: object
    DashboardWidgetPositionInput:
      properties:
        h:
          type: integer
        w:
          type: integer
        x:
          type: integer
        'y':
          type: integer
      required:
        - x
        - 'y'
        - w
        - h
      type: object
    DataModelFileContent:
      properties:
        content:
          type: string
        path:
          type: string
      required:
        - path
        - content
      type: object
    DataModelFilePath:
      properties:
        path:
          type: string
      required:
        - path
      type: object
    DataModelFileRename:
      properties:
        newPath:
          type: string
        path:
          type: string
      required:
        - path
        - newPath
      type: object
    DataModelValidationError:
      properties:
        fileName:
          oneOf:
            - type: string
            - type: 'null'
        message:
          type: string
      required:
        - message
      type: object
    DataModelValidationResponse:
      properties:
        branchName:
          type: string
        cubesCount:
          oneOf:
            - type: integer
            - type: 'null'
        deploymentId:
          type: integer
        errors:
          items:
            $ref: '#/components/schemas/DataModelValidationError'
          type: array
        mode:
          $ref: '#/components/schemas/DataModelValidationResponseMode'
        valid:
          type: boolean
      required:
        - deploymentId
        - branchName
        - mode
        - valid
        - errors
      type: object
    DataModelValidationResponseMode:
      enum:
        - production
        - dev_mode
      type: string
    DataModelWriteResponse:
      properties:
        success:
          type: boolean
      required:
        - success
      type: object
    DbtSyncCancelResponse:
      properties:
        message:
          type: string
      required:
        - message
      type: object
    DbtSyncGeneratedFile:
      properties:
        path:
          description: Path of the generated file within the data model project.
          type: string
      required:
        - path
      type: object
    DbtSyncLogEntriesListResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/DbtSyncLogEntry'
          type: array
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
      required:
        - items
        - pageInfo
      type: object
    DbtSyncLogEntry:
      properties:
        durationMs:
          oneOf:
            - type: integer
            - type: 'null'
          description: For a phase line, how long the phase took, in milliseconds.
        level:
          description: info or error.
          type: string
        message:
          type: string
        phase:
          oneOf:
            - type: string
            - type: 'null'
          description: The phase this line belongs to, e.g. dbt-compile.
        stream:
          description: >-
            Always "system" in this version. "stdout" and "stderr" join it once dbt’s own output is
            captured, so treat this as an open set.
          type: string
        timestamp:
          description: When the line was produced, as an ISO 8601 timestamp.
          type: string
      required:
        - timestamp
        - level
        - stream
        - message
      type: object
    DbtSyncManifestStats:
      properties:
        macros:
          type: integer
        models:
          type: integer
        sources:
          type: integer
      required:
        - models
        - sources
        - macros
      type: object
    DbtSyncProgress:
      properties:
        message:
          oneOf:
            - type: string
            - type: 'null'
          description: Human-readable description of what the sync is doing right now.
        percentComplete:
          description: >-
            Rough completion percentage derived from the stage. Progress reporting only — do not
            gate on it; gate on the status reaching COMPLETED or FAILED.
          type: integer
        stage:
          description: The stage the sync is currently in, from the same set of values as the sync status.
          type: string
      required:
        - stage
        - percentComplete
      type: object
    DbtSyncResponse:
      properties:
        branchName:
          type: string
        syncJobId:
          type: string
        workflowId:
          type: string
      required:
        - syncJobId
        - workflowId
        - branchName
      type: object
    DbtSyncResultResponse:
      properties:
        completedAt:
          description: When the sync finished, as an ISO 8601 timestamp.
          type: string
        cubeCount:
          description: How many cubes the sync generated from the dbt manifest.
          type: integer
        durationMs:
          description: End-to-end sync duration in milliseconds.
          type: integer
        generatedFiles:
          description: The cube files this sync generated and committed to the branch it created.
          items:
            $ref: '#/components/schemas/DbtSyncGeneratedFile'
          type: array
        manifestStats:
          $ref: '#/components/schemas/DbtSyncManifestStats'
        syncJobId:
          type: string
      required:
        - syncJobId
        - generatedFiles
        - manifestStats
        - cubeCount
        - completedAt
        - durationMs
      type: object
    DbtSyncRun:
      properties:
        branchName:
          description: The Cube branch this sync wrote its generated cubes to.
          type: string
        completedAt:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            When the sync finished, as an ISO 8601 timestamp, or null while it is still running.
            This is stamped by the process that ran the sync whereas startedAt is stamped by the
            process that launched it — two different clocks — so for a run that failed moments after
            starting, completedAt can even precede startedAt. Use durationMs to show how long a run
            took rather than subtracting these.
        deploymentId:
          type: integer
        durationMs:
          oneOf:
            - type: integer
            - type: 'null'
          description: >-
            How long the sync took, in milliseconds, and the value to use when showing a duration.
            Measured from a single clock, so it is never negative — prefer it over subtracting
            startedAt from completedAt, which can disagree with it by a small skew.
        errorMessage:
          oneOf:
            - type: string
            - type: 'null'
          description: Why the sync stopped. Present only for a failed run.
        failedPhase:
          oneOf:
            - type: string
            - type: 'null'
          description: The phase that failed, e.g. dbt-compile.
        gitRef:
          oneOf:
            - type: string
            - type: 'null'
          description: The dbt-repository ref this sync was run against, when pinned.
        lastStage:
          oneOf:
            - type: string
            - type: 'null'
          description: The pipeline stage the run reached, e.g. COMPILING_DBT.
        phases:
          oneOf:
            - items:
                $ref: '#/components/schemas/DbtSyncRunPhase'
              type: array
            - type: 'null'
          description: Per-phase timings, in the order they ran. Absent while the sync is running.
        startedAt:
          description: >-
            When the sync started, as an ISO 8601 timestamp. See completedAt before comparing the
            two.
          type: string
        stats:
          oneOf:
            - $ref: '#/components/schemas/DbtSyncRunStats'
            - type: 'null'
        status:
          description: >-
            RUNNING, COMPLETED, FAILED, CANCELLED or UNKNOWN. UNKNOWN means the outcome could not be
            established (the run’s record was lost and the workflow engine no longer knows the
            workflow) and is deliberately distinct from FAILED. Treat an unrecognized value as
            non-terminal.
          type: string
        syncJobId:
          type: string
        trigger:
          description: >-
            What started the sync: manual (the Cube Cloud UI), api (this REST API), webhook (a push
            to the dbt repository), agent (Cube AI), or unknown.
          type: string
        triggerContext:
          oneOf:
            - $ref: '#/components/schemas/DbtSyncRunTriggerContext'
            - type: 'null'
        userId:
          oneOf:
            - type: integer
            - type: 'null'
          description: The Cube user who started the sync, when a user started it.
      required:
        - syncJobId
        - deploymentId
        - status
        - trigger
        - branchName
        - startedAt
      type: object
    DbtSyncRunListResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/DbtSyncRun'
          type: array
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
      required:
        - items
        - pageInfo
      type: object
    DbtSyncRunPhase:
      properties:
        durationMs:
          description: How long the phase took, in milliseconds.
          type: integer
        outcome:
          description: ok or failed.
          type: string
        phase:
          description: Phase token, e.g. repo-clone, dbt-deps, dbt-compile.
          type: string
        startedOffsetMs:
          description: When the phase began, in milliseconds after the sync started.
          type: integer
      required:
        - phase
        - startedOffsetMs
        - durationMs
        - outcome
      type: object
    DbtSyncRunStats:
      properties:
        cubeCount:
          oneOf:
            - type: integer
            - type: 'null'
          description: How many cubes the sync generated.
        generatedFileCount:
          oneOf:
            - type: integer
            - type: 'null'
          description: How many files the sync wrote to the branch it created.
        macros:
          oneOf:
            - type: integer
            - type: 'null'
          description: dbt macros found in the manifest.
        models:
          oneOf:
            - type: integer
            - type: 'null'
          description: dbt models found in the manifest.
        sources:
          oneOf:
            - type: integer
            - type: 'null'
          description: dbt sources found in the manifest.
      type: object
    DbtSyncRunTriggerContext:
      properties:
        headSha:
          oneOf:
            - type: string
            - type: 'null'
        pushedBranch:
          oneOf:
            - type: string
            - type: 'null'
        targetBranch:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    DbtSyncRunsQueryStatus:
      enum:
        - RUNNING
        - COMPLETED
        - FAILED
        - CANCELLED
        - UNKNOWN
      type: string
    DbtSyncRunsQueryTrigger:
      enum:
        - manual
        - api
        - webhook
        - agent
        - unknown
      type: string
    DbtSyncStatusResponse:
      properties:
        error:
          oneOf:
            - type: string
            - type: 'null'
          description: Why the sync stopped. Present only when the status is FAILED.
        progress:
          $ref: '#/components/schemas/DbtSyncProgress'
        status:
          description: >-
            One of INITIALIZING, CREATING_SANDBOX, UPLOADING_PROJECT, INSTALLING_DEPENDENCIES,
            RUNNING_DBT_DEPS, COMPILING_DBT, PROCESSING_MANIFEST, WRITING_CUBE_FILES, FINALIZING,
            COMPLETED, FAILED. COMPLETED and FAILED are the only terminal values: poll until one of
            them, then read the result. Treat any unrecognized value as still running.
          type: string
        syncJobId:
          type: string
        updatedAt:
          description: When this status was last updated, as an ISO 8601 timestamp.
          type: string
      required:
        - syncJobId
        - status
        - progress
        - updatedAt
      type: object
    Deployment:
      properties:
        creationStep:
          $ref: '#/components/schemas/CreationStep'
        deploymentUrl:
          type: string
        id:
          type: integer
        name:
          type: string
      required:
        - id
        - name
        - deploymentUrl
        - creationStep
      type: object
    DeploymentDeleteResponse:
      properties:
        success:
          type: boolean
      required:
        - success
      type: object
    DeploymentEnvironment:
      properties:
        api_credentials:
          items:
            $ref: '#/components/schemas/DeploymentEnvironmentApiCredential'
          type: array
        branch:
          oneOf:
            - type: string
            - type: 'null'
        id:
          type: string
        type:
          $ref: '#/components/schemas/DeploymentEnvironmentType'
        user:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - id
        - type
        - api_credentials
      type: object
    DeploymentEnvironmentApiCredential:
      properties:
        database:
          oneOf:
            - type: string
            - type: 'null'
        host:
          oneOf:
            - type: string
            - type: 'null'
        port:
          oneOf:
            - minimum: 1
              type: integer
            - type: 'null'
        type:
          $ref: '#/components/schemas/DeploymentEnvironmentApiCredentialType'
        url:
          oneOf:
            - type: string
            - type: 'null'
        version:
          minimum: 1
          type: integer
      required:
        - type
        - version
      type: object
    DeploymentEnvironmentApiCredentialType:
      enum:
        - rest
        - sql
      type: string
    DeploymentEnvironmentToken:
      properties:
        created_at:
          type: string
        expires_at:
          type: string
        security_context:
          additionalProperties: true
          type: object
        token:
          type: string
      required:
        - token
        - security_context
        - created_at
        - expires_at
      type: object
    DeploymentEnvironmentTokenResponse:
      properties:
        data:
          $ref: '#/components/schemas/DeploymentEnvironmentToken'
      required:
        - data
      type: object
    DeploymentEnvironmentTokensListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/DeploymentEnvironmentToken'
          type: array
        items:
          items:
            $ref: '#/components/schemas/DeploymentEnvironmentToken'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
        pagination:
          oneOf:
            - $ref: '#/components/schemas/DeploymentsPagination'
            - type: 'null'
          description: 'Deprecated: use `pageInfo` instead. Kept for backward compatibility.'
          deprecated: true
      required:
        - items
        - data
      type: object
    DeploymentEnvironmentType:
      enum:
        - production
        - staging
        - development
      type: string
    DeploymentEnvironmentsListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/DeploymentEnvironment'
          type: array
        items:
          items:
            $ref: '#/components/schemas/DeploymentEnvironment'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
        pagination:
          oneOf:
            - $ref: '#/components/schemas/DeploymentsPagination'
            - type: 'null'
          description: 'Deprecated: use `pageInfo` instead. Kept for backward compatibility.'
          deprecated: true
      required:
        - items
        - data
      type: object
    DeploymentLogLine:
      properties:
        date:
          type: string
        message:
          type: string
        pod:
          type: string
      required:
        - pod
        - date
        - message
      type: object
    DeploymentLogsQueryContainer:
      enum:
        - INIT
        - MAIN
        - cubejs-server
        - vector
        - api-proxy
      type: string
    DeploymentLogsQuerySource:
      enum:
        - production
        - dev
      type: string
    DeploymentLogsResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/DeploymentLogLine'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
      type: object
    DeploymentPod:
      properties:
        containers:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        name:
          type: string
        ready:
          oneOf:
            - type: boolean
            - type: 'null'
        restartCount:
          oneOf:
            - type: integer
            - type: 'null'
        status:
          oneOf:
            - type: string
            - type: 'null'
        type:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - name
      type: object
    DeploymentPodsResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/DeploymentPod'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
      type: object
    DeploymentSettings:
      properties:
        autoDomain:
          oneOf:
            - type: string
            - type: 'null'
        cloudProvider:
          $ref: '#/components/schemas/DeploymentSettingsCloudProvider'
        creationMethod:
          oneOf:
            - $ref: '#/components/schemas/DeploymentSettingsCreationMethod'
            - type: 'null'
        creationStep:
          $ref: '#/components/schemas/CreationStep'
        cspsConfig:
          oneOf:
            - $ref: '#/components/schemas/CspsConfig'
            - type: 'null'
        cubeImageCloud:
          oneOf:
            - type: string
            - type: 'null'
        cubeImageVersion:
          oneOf:
            - type: string
            - type: 'null'
        customDomain:
          oneOf:
            - type: string
            - type: 'null'
        defaultLaunchpadViewGroup:
          oneOf:
            - type: string
            - type: 'null'
        deployBranchMergeAllowed:
          type: boolean
        deployBranchName:
          type: string
        deployBranchReadOnly:
          type: boolean
        deployMode:
          oneOf:
            - $ref: '#/components/schemas/DeploymentSettingsDeployMode'
            - type: 'null'
        deployProjectRoot:
          type: string
        deploymentUrl:
          type: string
        id:
          type: integer
        isCold:
          oneOf:
            - type: boolean
            - type: 'null'
        isCubeSqlEnabled:
          type: boolean
        isManaged:
          oneOf:
            - type: boolean
            - type: 'null'
        isSupportPreAggregations:
          type: boolean
        launchpadTabs:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        name:
          type: string
        region:
          oneOf:
            - type: string
            - type: 'null'
        releaseChannel:
          $ref: '#/components/schemas/DeploymentSettingsReleaseChannel'
        releaseChannelVersion:
          oneOf:
            - type: string
            - type: 'null'
        releaseChannelVersionHold:
          oneOf:
            - type: boolean
            - type: 'null'
        repoType:
          oneOf:
            - $ref: '#/components/schemas/DeploymentSettingsRepoType'
            - type: 'null'
        targetPlatform:
          oneOf:
            - type: string
            - type: 'null'
        template:
          $ref: '#/components/schemas/DeploymentSettingsTemplate'
        templateVariables:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
      required:
        - id
        - name
        - template
        - cloudProvider
        - creationStep
        - deploymentUrl
        - releaseChannel
        - deployBranchName
        - deployBranchReadOnly
        - deployBranchMergeAllowed
        - deployProjectRoot
        - isCubeSqlEnabled
        - isSupportPreAggregations
      type: object
    DeploymentSettingsCloudProvider:
      enum:
        - cubecloud
        - aws
        - gcp
      type: string
    DeploymentSettingsCreationMethod:
      enum:
        - upload
        - cubecloud
        - github
        - ssh
      type: string
    DeploymentSettingsDeployMode:
      enum:
        - git
        - cli
      type: string
    DeploymentSettingsReleaseChannel:
      enum:
        - latest
        - release
      type: string
    DeploymentSettingsRepoType:
      enum:
        - git
        - deployRepo
      type: string
    DeploymentSettingsTemplate:
      enum:
        - single
        - simpleCluster
        - multiCluster
      type: string
    DeploymentTokenResponse:
      properties:
        cubeApiToken:
          type: string
      required:
        - cubeApiToken
      type: object
    DeploymentVersion:
      properties:
        isCurrent:
          type: boolean
        isLatestInChannel:
          type: boolean
        releaseChannel:
          $ref: '#/components/schemas/DeploymentVersionReleaseChannel'
        releaseChannelVersion:
          type: string
        version:
          type: string
      required:
        - releaseChannelVersion
        - version
        - releaseChannel
        - isLatestInChannel
        - isCurrent
      type: object
    DeploymentVersionReleaseChannel:
      enum:
        - latest
        - release
      type: string
    DeploymentVersionsResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/DeploymentVersion'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
      type: object
    DeploymentsListResponse:
      properties:
        count:
          oneOf:
            - minimum: 0
              type: integer
            - type: 'null'
          description: >-
            Deprecated: total number of accessible deployments, ignoring pagination. Kept for
            backward compatibility.
          deprecated: true
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/Deployment'
          type: array
        items:
          items:
            $ref: '#/components/schemas/Deployment'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
        pagination:
          $ref: '#/components/schemas/DeploymentsPagination'
          deprecated: true
          description: 'Deprecated: use `pageInfo` instead. Kept for backward compatibility.'
        totalCount:
          oneOf:
            - minimum: 0
              type: integer
            - type: 'null'
          description: 'Deprecated: use `count`. Kept for backward compatibility.'
          deprecated: true
      required:
        - items
        - data
        - pagination
      type: object
    DeploymentsPagination:
      properties:
        limit:
          minimum: 0
          type: integer
        offset:
          minimum: 0
          type: integer
        total:
          minimum: 0
          type: integer
      required:
        - total
        - offset
        - limit
      type: object
    DevBranchResponse:
      properties:
        active:
          type: boolean
        branchName:
          oneOf:
            - type: string
            - type: 'null'
        parentBranch:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - active
      type: object
    DisconnectReportFromWorkbookInput:
      properties:
        anchorCell:
          oneOf:
            - type: string
            - type: 'null'
        externalWorkbookId:
          oneOf:
            - type: string
            - type: 'null'
        placementId:
          oneOf:
            - type: string
            - type: 'null'
        resultLocation:
          oneOf:
            - type: string
            - type: 'null'
        sheetId:
          oneOf:
            - type: string
            - type: 'null'
        sheetName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    DuplicateWorkbookInput:
      properties:
        shared:
          oneOf:
            - type: boolean
            - type: 'null'
      type: object
    EmbedAccessAllEmbedUsers:
      properties:
        action:
          $ref: '#/components/schemas/EmbedAccessAllEmbedUsersAction'
        enabled:
          type: boolean
        groupId:
          oneOf:
            - type: integer
            - type: 'null'
      required:
        - enabled
        - action
      type: object
    EmbedAccessAllEmbedUsersAction:
      enum:
        - read
        - none
      type: string
    EmbedAccessResponse:
      properties:
        allEmbedUsers:
          $ref: '#/components/schemas/EmbedAccessAllEmbedUsers'
        allowEmbed:
          type: boolean
        tenants:
          items:
            $ref: '#/components/schemas/EmbedAccessTenantEntry'
          type: array
      required:
        - allowEmbed
        - allEmbedUsers
        - tenants
      type: object
    EmbedAccessTenantEntry:
      properties:
        action:
          $ref: '#/components/schemas/EmbedAccessTenantEntryAction'
        embedTenantName:
          type: string
        groupId:
          type: integer
      required:
        - embedTenantName
        - groupId
        - action
      type: object
    EmbedAccessTenantEntryAction:
      enum:
        - read
        - none
      type: string
    EmbedGroupMemberInput:
      properties:
        embedUserId:
          oneOf:
            - minimum: 1
              type: integer
            - type: 'null'
          description: Numeric id of an existing embed user. Provide this OR `externalId`.
        externalId:
          oneOf:
            - minLength: 1
              type: string
            - type: 'null'
          description: >-
            External id of the embed user (the `externalId` passed to `generate-session`). Provide
            this OR `embedUserId`.
      type: object
    EmbedGroupMembersInput:
      properties:
        members:
          description: Embed users to add or remove (1–1000 per request).
          items:
            $ref: '#/components/schemas/EmbedGroupMemberInput'
          maxItems: 1000
          minItems: 1
          type: array
      required:
        - members
      type: object
    EmbedGroupMembersMutationResponse:
      properties:
        addedMembers:
          items:
            $ref: '#/components/schemas/EmbedUser'
          type: array
        unchangedMembers:
          items:
            $ref: '#/components/schemas/EmbedUser'
          type: array
      required:
        - addedMembers
        - unchangedMembers
      type: object
    EmbedPythonFilteredRunInput:
      properties:
        reportId:
          type: integer
        reportVersionId:
          type: integer
        sqlQuery:
          type: string
      required:
        - reportId
        - sqlQuery
        - reportVersionId
      type: object
    EmbedSessionSettings:
      properties:
        allowChatWorkspaceAuthoring:
          oneOf:
            - type: boolean
            - type: 'null'
          description: >-
            Whether AI Chat authenticated with this session may create or modify persistent Cube
            Workspace content. Set to `false` for headless chat integrations that render answers in
            their own UI: ad-hoc data analysis and inline tables/charts remain available, but the
            agent cannot save or update standalone explorations/reports, create or modify workbooks,
            create or publish dashboards, or direct users to those Cube UI surfaces. Omit or set to
            `true` to preserve the session user's role-derived authoring capabilities; `true` never
            grants access the user does not already have. This setting changes only AI Chat tools
            and instructions. It does not change user roles or permissions for direct API calls.
        showDashboardChat:
          oneOf:
            - type: boolean
            - type: 'null'
          description: >-
            Whether embedded published dashboards viewed with this session show the AI chat (agent
            panel and launcher bubble). Omit to inherit the account-wide embed setting (shown by
            default); `false` hides the chat even if it is enabled account-wide, `true` shows it
            even if it is disabled account-wide. Only affects the dashboard surface.
      type: object
    EmbedSettings:
      properties:
        enableDashboardComments:
          oneOf:
            - type: boolean
            - type: 'null'
        locale:
          oneOf:
            - type: string
            - type: 'null'
        showDashboardChat:
          oneOf:
            - type: boolean
            - type: 'null'
        timezone:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    EmbedTenant:
      properties:
        createdAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        displayName:
          oneOf:
            - type: string
            - type: 'null'
        id:
          type: integer
        name:
          type: string
        userCount:
          type: integer
      required:
        - id
        - name
        - userCount
      type: object
    EmbedTenantProfile:
      properties:
        displayName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    EmbedTenantsPublicResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/EmbedTenant'
          type: array
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
      required:
        - items
        - pageInfo
      type: object
    EmbedTheme:
      properties:
        analyticsChat:
          oneOf:
            - $ref: '#/components/schemas/EmbedThemeAnalyticsChat'
              type: object
            - type: 'null'
        chat:
          oneOf:
            - $ref: '#/components/schemas/EmbedThemeChat'
              type: object
            - type: 'null'
        font:
          oneOf:
            - type: string
            - type: 'null'
        primaryColor:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    EmbedThemeAnalyticsChat:
      properties:
        backgroundColor:
          oneOf:
            - type: string
            - type: 'null'
        chatInput:
          oneOf:
            - $ref: '#/components/schemas/EmbedThemeAnalyticsChatInput'
              type: object
            - type: 'null'
      type: object
    EmbedThemeAnalyticsChatInput:
      properties:
        backgroundColor:
          oneOf:
            - type: string
            - type: 'null'
        borderColor:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    EmbedThemeChat:
      properties:
        inputColor:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    EmbedUser:
      properties:
        createdAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        email:
          oneOf:
            - type: string
            - type: 'null'
        externalId:
          oneOf:
            - type: string
            - type: 'null'
        firstName:
          oneOf:
            - type: string
            - type: 'null'
        id:
          type: integer
        lastLogin:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        username:
          type: string
      required:
        - id
        - username
      type: object
    EmbedUserProfile:
      properties:
        displayName:
          oneOf:
            - type: string
            - type: 'null'
        picture:
          oneOf:
            - format: url
              type: string
            - type: 'null'
      type: object
    EmbedUsersPublicResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/EmbedUser'
          type: array
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
      required:
        - items
        - pageInfo
      type: object
    EnvVariableItem:
      properties:
        name:
          type: string
        value:
          type: string
      required:
        - name
        - value
      type: object
    EnvVariablesListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/EnvVariableItem'
          type: array
        items:
          items:
            $ref: '#/components/schemas/EnvVariableItem'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    FileHash:
      properties:
        hash:
          type: string
      required:
        - hash
      type: object
    FillMissingRows:
      properties:
        excludedDimensions:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        member:
          type: string
      required:
        - member
      type: object
    FinishUploadBody:
      properties:
        autoRemoveFiles:
          oneOf:
            - type: boolean
              default: true
            - type: 'null'
        awaitGitOperations:
          oneOf:
            - type: boolean
              default: true
            - type: 'null'
        commitMessage:
          oneOf:
            - type: string
            - type: 'null'
        files:
          type: object
        transaction:
          $ref: '#/components/schemas/UploadTransaction'
      required:
        - transaction
        - files
      type: object
    FinishUploadResponse:
      properties:
        lastHash:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    Folder:
      properties:
        createdAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        createdBy:
          type: integer
        deploymentId:
          type: integer
        folderPath:
          items:
            $ref: '#/components/schemas/WorkspaceFolderPathEntry'
          type: array
        id:
          type: integer
        name:
          type: string
        parentId:
          oneOf:
            - type: integer
            - type: 'null'
        position:
          type: integer
        type:
          $ref: '#/components/schemas/FolderDtoType'
        updatedAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        updatedBy:
          oneOf:
            - type: integer
            - type: 'null'
      required:
        - name
        - position
        - id
        - deploymentId
        - createdAt
        - updatedAt
        - type
      type: object
    FolderDtoType:
      enum:
        - FOLDER
        - WORKBOOK
        - REPORT
      type: string
    FoldersListResponse:
      properties:
        count:
          oneOf:
            - minimum: 0
              type: integer
            - type: 'null'
          description: >-
            Deprecated: total number of accessible folders, ignoring pagination. Kept for backward
            compatibility.
          deprecated: true
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/Folder'
          type: array
        items:
          items:
            $ref: '#/components/schemas/Folder'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    GenerateEmbedTokenResponse:
      properties:
        token:
          type: string
      required:
        - token
      type: object
    GenerateSession:
      properties:
        creatorMode:
          oneOf:
            - type: boolean
            - type: 'null'
        deploymentId:
          type: number
        email:
          oneOf:
            - type: string
            - type: 'null'
        embedTenantName:
          oneOf:
            - pattern: ^[a-z][a-z0-9-]{0,34}[a-z0-9]$
              type: string
            - type: 'null'
        embedTenantProfile:
          oneOf:
            - $ref: '#/components/schemas/EmbedTenantProfile'
              type: object
            - type: 'null'
        embedTheme:
          oneOf:
            - $ref: '#/components/schemas/EmbedTheme'
              type: object
            - type: 'null'
        externalId:
          oneOf:
            - type: string
            - type: 'null'
        groupDefinitions:
          oneOf:
            - items:
                $ref: '#/components/schemas/GroupDefinition'
              type: array
            - type: 'null'
          description: >-
            Deprecated and ignored. Global groups can no longer be created through this endpoint —
            define them beforehand via the Cube UI or admin API. Still accepted for backward
            compatibility (no error), but it has no effect. To create per-embed-tenant groups, use
            `tenantGroupDefinitions`.
          deprecated: true
        groups:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
          description: >-
            Global user groups — defined once at the tenant level and shared across every embed
            tenant — to assign this embed user to. Use `groups` for **data-model access control**:
            each name is placed verbatim into the Cube security context as `cubeCloud.groups`, where
            your data model's `access_policy` rules reference it to gate cubes, views, members, and
            row-/column-level filters. The groups must already exist in the tenant (create them via
            the Cube UI or admin API beforehand) — this endpoint never creates global groups, and
            names that do not resolve to an existing group are rejected. Global groups are NOT shown
            in an embed tenant’s Creator Mode UI. To share or organize content inside a single embed
            tenant, use `tenantGroups` instead.
        internalId:
          oneOf:
            - type: string
            - type: 'null'
        isEphemeral:
          oneOf:
            - type: boolean
            - type: 'null'
        publicDashboardId:
          oneOf:
            - type: string
            - type: 'null'
        roles:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        securityContext:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        settings:
          oneOf:
            - $ref: '#/components/schemas/EmbedSessionSettings'
              type: object
            - type: 'null'
          description: >-
            Per-session overrides for embed behavior, stored in the signed embed token. Each
            documented key applies only to this session; omitted keys preserve their existing
            default behavior.
        tenantGroupDefinitions:
          oneOf:
            - items:
                $ref: '#/components/schemas/GroupDefinition'
              type: array
            - type: 'null'
          description: >-
            Idempotently create or update the per-embed-tenant groups referenced by `tenantGroups`,
            before they are assigned. Requires `creatorMode: true` and `embedTenantName`. Use this
            to declare a tenant’s groups in the same call that assigns them, so you do not need a
            separate admin request. Applies only to per-embed-tenant groups; global groups must be
            defined beforehand.
        tenantGroups:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
          description: >-
            Per-embed-tenant user groups — scoped to the single embed tenant named by
            `embedTenantName` — to assign this embed user to. Use `tenantGroups` for **content
            sharing and organization within one embed tenant**: for example, so a creator can share
            a workbook, dashboard, or folder with a group of that tenant’s users. These are the only
            groups shown in the embed tenant’s Creator Mode UI. Requires `creatorMode: true` and
            `embedTenantName`. Define the groups beforehand — or in the same request — via
            `tenantGroupDefinitions`. In the Cube security context they appear namespaced as
            `system:tenant:{embedTenantName}:group:{groupName}`, so a tenant group can never collide
            with — or be mistaken for — a global `groups` entry of the same name. For
            organization-wide data-model access policies, use `groups`.
        userAttributeDefinitions:
          oneOf:
            - items:
                $ref: '#/components/schemas/UserAttributeDefinition'
              type: array
            - type: 'null'
        userAttributes:
          oneOf:
            - items:
                $ref: '#/components/schemas/UserAttributeInput'
              type: array
            - type: 'null'
        userProfile:
          oneOf:
            - $ref: '#/components/schemas/EmbedUserProfile'
              type: object
            - type: 'null'
      required:
        - deploymentId
      type: object
    GenerateSessionResponse:
      properties:
        sessionId:
          type: string
      required:
        - sessionId
      type: object
    GetDeploymentEnvironmentsQueryType:
      enum:
        - production
        - staging
        - development
      type: string
    GetReportsQuerySortBy:
      enum:
        - name
        - createdAt
        - updatedAt
        - lastViewedAt
      type: string
    GetReportsQuerySortDirection:
      enum:
        - ASC
        - DESC
      type: string
    GetUserAttributesQueryType:
      enum:
        - string
        - number
        - boolean
        - string_array
        - number_array
      type: string
    GetWorkspaceObjectsQueryOrderByDirection:
      enum:
        - ASC
        - DESC
      type: string
    GetWorkspaceObjectsQueryOrderByField:
      enum:
        - updated_at
        - created_at
        - name
        - viewer_last_viewed_at
      type: string
    GitHubBranchResponse:
      properties:
        isDefault:
          type: boolean
        name:
          type: string
      required:
        - name
        - isDefault
      type: object
    GitHubBranchesListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/GitHubBranchResponse'
          type: array
        items:
          items:
            $ref: '#/components/schemas/GitHubBranchResponse'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    GitHubConnectStatusResponse:
      properties:
        connected:
          type: boolean
        linkUrl:
          type: string
        settingsUrl:
          type: string
      required:
        - connected
        - linkUrl
        - settingsUrl
      type: object
    GitHubInstallationResponse:
      properties:
        avatarUrl:
          type: string
        id:
          type: string
        installationId:
          type: string
        login:
          type: string
      required:
        - installationId
        - id
        - login
        - avatarUrl
      type: object
    GitHubInstallationsListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/GitHubInstallationResponse'
          type: array
        items:
          items:
            $ref: '#/components/schemas/GitHubInstallationResponse'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    GitHubRepoResponse:
      properties:
        htmlUrl:
          type: string
        id:
          type: integer
        name:
          type: string
      required:
        - id
        - name
        - htmlUrl
      type: object
    GitHubReposListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/GitHubRepoResponse'
          type: array
        items:
          items:
            $ref: '#/components/schemas/GitHubRepoResponse'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    GroupDefinition:
      properties:
        description:
          oneOf:
            - type: string
            - type: 'null'
        name:
          type: string
      required:
        - name
      type: object
    LocalizedValue:
      properties:
        locale:
          maxLength: 35
          type: string
        value:
          maxLength: 1000
          type: string
      required:
        - locale
        - value
      type: object
    MergeIntoParentBranchRequest:
      properties:
        branchId:
          type: integer
        branchName:
          type: string
        deleteBranch:
          oneOf:
            - type: boolean
            - type: 'null'
        message:
          oneOf:
            - type: string
            - type: 'null'
        squashCommits:
          oneOf:
            - type: boolean
            - type: 'null'
        switchToParentBranch:
          oneOf:
            - type: boolean
            - type: 'null'
      type: object
    MergeResponse:
      properties:
        branchDeleted:
          type: boolean
        merged:
          type: boolean
      required:
        - merged
        - branchDeleted
      type: object
    MergeToDefaultBranchRequest:
      properties:
        branchId:
          type: integer
        branchName:
          type: string
        message:
          type: string
        removeBranchAfterMerge:
          oneOf:
            - type: boolean
            - type: 'null'
      required:
        - message
      type: object
    MoveWorkspaceObjectInput:
      properties:
        folderId:
          oneOf:
            - type: integer
            - type: 'null'
        id:
          type: integer
        type:
          $ref: '#/components/schemas/MoveWorkspaceObjectInputType'
      required:
        - type
        - id
      type: object
    MoveWorkspaceObjectInputType:
      enum:
        - FOLDER
        - WORKBOOK
        - REPORT
      type: string
    NotificationDto:
      properties:
        cronExpression:
          type: string
        dashboardId:
          type: integer
        deploymentId:
          type: integer
        filters:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardFilter'
              type: array
            - type: 'null'
          description: Dimension filters applied when the notification is rendered.
        humanReadableSchedule:
          description: Human-readable description of the cron schedule
          type: string
        id:
          type: integer
        isEnabled:
          type: boolean
        notificationAiSummary:
          description: Whether this notification carries an AI-generated "what changed" summary in its body.
          type: boolean
        notificationEnabled:
          type: boolean
        notificationFormat:
          type: string
        timeGrains:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardTimeGrain'
              type: array
            - type: 'null'
          description: Time-grain overrides applied when the notification is rendered.
        timezone:
          type: string
      required:
        - id
        - dashboardId
        - deploymentId
        - cronExpression
        - timezone
        - isEnabled
        - humanReadableSchedule
        - notificationEnabled
        - notificationFormat
        - notificationAiSummary
      type: object
    NotificationRecipient:
      properties:
        channelId:
          oneOf:
            - type: string
            - type: 'null'
        channelName:
          oneOf:
            - type: string
            - type: 'null'
        email:
          oneOf:
            - type: string
            - type: 'null'
        embedTenantName:
          oneOf:
            - type: string
            - type: 'null'
        embedUserId:
          oneOf:
            - type: integer
            - type: 'null'
        externalId:
          oneOf:
            - type: string
            - type: 'null'
        type:
          $ref: '#/components/schemas/NotificationRecipientType'
        userId:
          oneOf:
            - type: integer
            - type: 'null'
        username:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - type
      type: object
    NotificationRecipientInput:
      properties:
        channelId:
          oneOf:
            - type: string
            - type: 'null'
          description: Slack channel id (for type=SLACK)
        channelName:
          oneOf:
            - type: string
            - type: 'null'
          description: Slack channel display name (optional, for type=SLACK)
        email:
          oneOf:
            - type: string
            - type: 'null'
          description: Main user email (for type=USER; provide this OR userId)
        embedTenantName:
          oneOf:
            - type: string
            - type: 'null'
          description: Embed tenant name (for type=EMBED_USER)
        externalId:
          oneOf:
            - type: string
            - type: 'null'
          description: Embed user external id (for type=EMBED_USER)
        groups:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
          description: >-
            Embed user groups (type=EMBED_USER). Must reference groups that already exist; drives
            per-recipient access when the report is rendered.
        securityContext:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
          description: >-
            Embed user security context (type=EMBED_USER). Applied for per-recipient row-level
            security when the report is rendered.
        type:
          $ref: '#/components/schemas/NotificationRecipientInputType'
        userAttributes:
          oneOf:
            - items:
                $ref: '#/components/schemas/UserAttributeInput'
              type: array
            - type: 'null'
          description: >-
            Embed user attribute values (type=EMBED_USER). Names must reference attribute
            definitions that already exist.
        userId:
          oneOf:
            - type: integer
            - type: 'null'
          description: Main user id (for type=USER; provide this OR email)
      required:
        - type
      type: object
    NotificationRecipientInputType:
      enum:
        - USER
        - EMBED_USER
        - SLACK
      type: string
    NotificationRecipientType:
      enum:
        - USER
        - EMBED_USER
        - SLACK
      type: string
    NotificationRecipientsListResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/NotificationRecipient'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
      type: object
    NotificationRecipientsMutationResponse:
      properties:
        createdRecipients:
          description: Recipients newly subscribed by this request
          items:
            $ref: '#/components/schemas/NotificationRecipient'
          type: array
        unchangedRecipients:
          description: Recipients that already existed and were left unchanged
          items:
            $ref: '#/components/schemas/NotificationRecipient'
          type: array
        updatedRecipients:
          description: >-
            Existing recipients whose properties (e.g. embed security context / attributes / groups,
            or Slack channel name) were updated
          items:
            $ref: '#/components/schemas/NotificationRecipient'
          type: array
      required:
        - createdRecipients
        - updatedRecipients
        - unchangedRecipients
      type: object
    NotificationsListResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/NotificationDto'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
      type: object
    OAuthIntegration:
      properties:
        authUrl:
          format: url
          type: string
        clientId:
          type: string
        config:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        createdAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        id:
          type: integer
        name:
          type: string
        redirectUri:
          format: url
          type: string
        scopes:
          oneOf:
            - items: {}
              type: array
            - type: 'null'
        tokenUrl:
          format: url
          type: string
        type:
          type: string
        updatedAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
      required:
        - id
        - name
        - type
        - authUrl
        - tokenUrl
        - clientId
        - redirectUri
        - createdAt
        - updatedAt
      type: object
    OidcTokenConfig:
      properties:
        audience:
          type: string
        audienceType:
          type: string
        createdAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        customClaims:
          oneOf:
            - type: object
            - type: 'null'
        id:
          type: integer
        isEnabled:
          type: boolean
        name:
          type: string
        subFormat:
          oneOf:
            - type: string
            - type: 'null'
        targetEnvVar:
          oneOf:
            - type: string
            - type: 'null'
        updatedAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
      required:
        - id
        - audienceType
        - audience
        - name
        - isEnabled
        - createdAt
        - updatedAt
      type: object
    PageInfo:
      properties:
        endCursor:
          oneOf:
            - type: string
            - type: 'null'
        hasNextPage:
          type: boolean
        hasPreviousPage:
          type: boolean
        startCursor:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - hasNextPage
        - hasPreviousPage
      type: object
    PeriodComparison:
      properties:
        measure:
          type: string
        offset:
          $ref: '#/components/schemas/PeriodComparisonOffset'
        outputs:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        timeDimension:
          type: string
      required:
        - measure
        - timeDimension
        - offset
      type: object
    PeriodComparisonOffset:
      properties:
        amount:
          type: integer
        unit:
          type: string
      required:
        - amount
        - unit
      type: object
    PivotItems:
      properties:
        columns:
          items:
            type: string
          type: array
        filters:
          items:
            type: string
          type: array
        measures:
          items:
            type: string
          type: array
        measuresAxis:
          oneOf:
            - $ref: '#/components/schemas/PivotItemsMeasuresAxis'
            - type: 'null'
        measuresPosition:
          oneOf:
            - $ref: '#/components/schemas/PivotItemsMeasuresPosition'
            - type: 'null'
        rows:
          items:
            type: string
          type: array
      required:
        - columns
        - measures
        - rows
        - filters
      type: object
    PivotItemsInput:
      properties:
        columns:
          items:
            type: string
          type: array
        filters:
          items:
            type: string
          type: array
        measures:
          items:
            type: string
          type: array
        measuresAxis:
          oneOf:
            - $ref: '#/components/schemas/PivotItemsInputMeasuresAxis'
            - type: 'null'
        measuresPosition:
          oneOf:
            - $ref: '#/components/schemas/PivotItemsInputMeasuresPosition'
            - type: 'null'
        rows:
          items:
            type: string
          type: array
      required:
        - columns
        - measures
        - rows
        - filters
      type: object
    PivotItemsInputMeasuresAxis:
      enum:
        - columns
        - rows
      type: string
    PivotItemsInputMeasuresPosition:
      enum:
        - before
        - after
      type: string
    PivotItemsMeasuresAxis:
      enum:
        - columns
        - rows
      type: string
    PivotItemsMeasuresPosition:
      enum:
        - before
        - after
      type: string
    Policy:
      properties:
        actions:
          items:
            enum:
              - All
              - DeploymentsManage
              - DeploymentCreate
              - DeploymentRead
              - DeploymentUpdate
              - DeploymentDelete
              - SecretsManage
              - DownloadData
              - PlaygroundRead
              - SchemaRead
              - SchemaUpdate
              - SchemaUpdateDevBranches
              - APMRead
              - PreAggregationBuild
              - AlertsCreate
              - AlertsRead
              - AlertsUpdate
              - AlertsDelete
              - AuditLogManage
              - BillingRead
              - SqlRunnerRead
              - DataAssetsRead
              - DataAssetsManage
              - CubeNetworkConnect
              - ReportRead
              - ReportEdit
              - ReportManage
              - WorkbookManage
              - WorkbookRead
              - WorkbookEdit
              - ChatThreadRead
              - AgentManage
              - AgentRead
              - AgentSpaceManage
              - AgentAdmin
              - DeploymentAgentRead
              - OAuthIntegrationsManage
              - OAuthIntegrationsIssueTokens
              - McpToolsManage
              - AIBIDevelop
              - AIBIExplore
              - AIBIView
              - ChartPalettesManage
              - DashboardThemesManage
              - AIBIDeveloper
              - AIBIUser
              - AIBIViewer
              - EmbedDeploymentRead
              - EmbedDashboardRead
              - FolderRead
              - FolderEdit
              - FolderManage
            type: string
          type: array
        resourceType:
          $ref: '#/components/schemas/PolicyResourceType'
        resources:
          items:
            type: string
          type: array
      required:
        - resourceType
        - actions
        - resources
      type: object
    PolicyResourceType:
      enum:
        - Global
        - Deployment
        - Report
        - ReportFolder
        - Agent
        - AgentSpace
        - Workbook
        - Dashboard
        - Folder
        - ChatThread
      type: string
    PostTokenBySessionIdInput:
      properties:
        sessionId:
          type: string
      required:
        - sessionId
      type: object
    ProvisionEmbedUserFailure:
      properties:
        error:
          $ref: '#/components/schemas/BulkActionError'
        externalId:
          description: The `externalId` of the entry that failed, normalized the same way a successful one is.
          type: string
      required:
        - externalId
        - error
      type: object
    ProvisionEmbedUserInput:
      properties:
        email:
          oneOf:
            - format: email
              type: string
            - type: 'null'
          description: >-
            Email address, shown wherever the user is listed and searchable through `GET
            /embed-tenants/{embedTenantName}/users`. Must be a valid address, and is stored
            lowercased. Omit it and Cube derives a synthetic `{externalId}@cubecloud.dev`
            placeholder instead, which is what makes a user hard to recognise in a list. Supplying
            it again later updates the stored address.
        externalId:
          description: >-
            The id your own system knows this user by — the same `externalId` you will pass to
            `generate-session`. Trimmed and lowercased before it is stored, so casing never produces
            a second user.
          minLength: 1
          type: string
        groups:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
          description: >-
            Global, account-wide groups (the `groups` field of `generate-session`) that gate
            data-model access. They must already exist. Supplying the field REPLACES the user’s
            global groups; omit it to leave them untouched, pass `[]` to clear them.
        tenantGroups:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
          description: >-
            Groups belonging to this embed tenant (the `tenantGroups` field of `generate-session`),
            which scope content sharing and organization within the tenant. Create them first via
            `POST /embed-tenants/{embedTenantName}/groups`. Supplying the field REPLACES the user’s
            tenant groups; omit it to leave them untouched, pass `[]` to clear them.
        userProfile:
          oneOf:
            - $ref: '#/components/schemas/EmbedUserProfile'
              type: object
            - type: 'null'
          description: >-
            Display name and avatar. `displayName` is the name shown wherever the user appears,
            including on content they author. Omitted fields keep their current value.
      required:
        - externalId
      type: object
    ProvisionEmbedUsersInput:
      properties:
        users:
          description: Embed users to provision (1–100 per request).
          items:
            $ref: '#/components/schemas/ProvisionEmbedUserInput'
          maxItems: 100
          minItems: 1
          type: array
      required:
        - users
      type: object
    ProvisionEmbedUsersResponse:
      properties:
        failed:
          description: The entries that were not applied, each with the reason.
          items:
            $ref: '#/components/schemas/ProvisionEmbedUserFailure'
          type: array
        succeeded:
          description: The users that were provisioned, in the order they were requested.
          items:
            $ref: '#/components/schemas/EmbedUser'
          type: array
      required:
        - succeeded
        - failed
      type: object
    PublishDashboardInput:
      properties:
        allowEmbed:
          oneOf:
            - type: boolean
            - type: 'null'
        config:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfigInput'
            - type: 'null'
        dashboardId:
          oneOf:
            - type: integer
            - type: 'null'
        description:
          oneOf:
            - type: string
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        workbookId:
          type: integer
      required:
        - workbookId
      type: object
    PullRequest:
      properties:
        branchName:
          type: string
      required:
        - branchName
      type: object
    PullResponse:
      properties:
        buildTriggered:
          type: boolean
      required:
        - buildTriggered
      type: object
    PythonAnalysisFilteredRun:
      properties:
        at:
          type: string
        executionError:
          oneOf:
            - type: string
            - type: 'null'
        inputRowCount:
          type: integer
        outputData:
          oneOf:
            - {}
            - type: 'null'
        stderr:
          type: string
        stdout:
          type: string
      required:
        - at
        - stdout
        - stderr
        - inputRowCount
      type: object
    RefreshReportInput:
      properties:
        anchorCell:
          oneOf:
            - type: string
            - type: 'null'
        externalWorkbookId:
          oneOf:
            - type: string
            - type: 'null'
        placementId:
          oneOf:
            - type: string
            - type: 'null'
        resultLocation:
          oneOf:
            - type: string
            - type: 'null'
        sheetId:
          oneOf:
            - type: string
            - type: 'null'
        sheetName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    RegionResponse:
      properties:
        id:
          type: integer
        isDedicated:
          oneOf:
            - type: boolean
            - type: 'null'
        isHybrid:
          oneOf:
            - type: boolean
            - type: 'null'
        isPublic:
          oneOf:
            - type: boolean
            - type: 'null'
        name:
          type: string
        provider:
          oneOf:
            - type: string
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        useAiEngineer:
          oneOf:
            - type: boolean
            - type: 'null'
      required:
        - id
        - name
      type: object
    RegionsListResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/RegionResponse'
          type: array
        items:
          items:
            $ref: '#/components/schemas/RegionResponse'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    RemoveDataModelFilesInput:
      properties:
        branchId:
          type: integer
        branchName:
          type: string
        files:
          items:
            $ref: '#/components/schemas/DataModelFilePath'
          type: array
      required:
        - files
      type: object
    RemoveNotificationRecipientInput:
      properties:
        embedTenantName:
          oneOf:
            - type: string
            - type: 'null'
          description: Embed tenant name (required for type=EMBED_USER; resolves the storage partition)
        id:
          description: >-
            Recipient id: userId (type=USER), embedUserId (type=EMBED_USER), or channelId
            (type=SLACK)
          not:
            type: 'null'
          oneOf:
            - type: integer
            - type: string
        type:
          $ref: '#/components/schemas/RemoveNotificationRecipientInputType'
      required:
        - type
        - id
      type: object
    RemoveNotificationRecipientInputType:
      enum:
        - USER
        - EMBED_USER
        - SLACK
      type: string
    RemoveNotificationRecipientsInput:
      properties:
        recipients:
          description: Recipients to unsubscribe (1–1000 per request)
          items:
            $ref: '#/components/schemas/RemoveNotificationRecipientInput'
          maxItems: 1000
          minItems: 1
          type: array
      required:
        - recipients
      type: object
    RenameDataModelFilesInput:
      properties:
        branchId:
          type: integer
        branchName:
          type: string
        files:
          items:
            $ref: '#/components/schemas/DataModelFileRename'
          type: array
      required:
        - files
      type: object
    Report:
      properties:
        canEdit:
          oneOf:
            - type: boolean
            - type: 'null'
        canManage:
          oneOf:
            - type: boolean
            - type: 'null'
        createdAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        createdBy:
          type: integer
        currentQueryChecksum:
          oneOf:
            - type: string
            - type: 'null'
        deploymentId:
          type: integer
        description:
          oneOf:
            - type: string
            - type: 'null'
        endResultCell:
          oneOf:
            - type: string
            - type: 'null'
        externalWorkbookId:
          oneOf:
            - type: string
            - type: 'null'
        externalWorkbookPlacements:
          oneOf:
            - items:
                $ref: '#/components/schemas/ReportPlacement'
              type: array
            - type: 'null'
        folderId:
          oneOf:
            - type: integer
            - type: 'null'
        folderPath:
          items:
            $ref: '#/components/schemas/WorkspaceFolderPathEntry'
          type: array
        id:
          type: integer
        jsonQuery:
          oneOf:
            - type: string
            - type: 'null'
        meta:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        name:
          type: string
        pivotItems:
          oneOf:
            - $ref: '#/components/schemas/PivotItems'
            - type: 'null'
        publicId:
          maxLength: 12
          minLength: 12
          pattern: ^[0-9A-Za-z]+$
          type: string
        refreshedBy:
          oneOf:
            - type: integer
            - type: 'null'
        refreshedByUser:
          $ref: '#/components/schemas/ResourceOwner'
        resultLocation:
          oneOf:
            - type: string
            - type: 'null'
        rolesWithAccess:
          oneOf:
            - items:
                $ref: '#/components/schemas/RoleWithAccess'
              type: array
            - type: 'null'
        source:
          oneOf:
            - $ref: '#/components/schemas/ReportDtoSource'
            - type: 'null'
        sqlQuery:
          oneOf:
            - type: string
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        type:
          $ref: '#/components/schemas/ReportDtoType'
        updatedAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        user:
          $ref: '#/components/schemas/ResourceOwner'
        userId:
          type: integer
        version:
          oneOf:
            - type: integer
            - type: 'null'
        workbookId:
          oneOf:
            - type: integer
            - type: 'null'
      required:
        - publicId
        - userId
        - user
        - name
        - refreshedByUser
        - id
        - deploymentId
        - createdAt
        - updatedAt
        - type
      type: object
    ReportDtoSource:
      enum:
        - GOOGLE_SHEETS
        - EXCEL
        - PLAYGROUND
        - D3
      type: string
    ReportDtoType:
      enum:
        - FOLDER
        - WORKBOOK
        - REPORT
      type: string
    ReportPlacement:
      properties:
        anchorCell:
          oneOf:
            - type: string
            - type: 'null'
        endResultCell:
          oneOf:
            - type: string
            - type: 'null'
        host:
          oneOf:
            - $ref: '#/components/schemas/ReportPlacementHost'
            - type: 'null'
        id:
          oneOf:
            - type: string
            - type: 'null'
        placedAt:
          oneOf:
            - type: string
            - type: 'null'
        placedByUserId:
          oneOf:
            - type: integer
            - type: 'null'
        queryChecksum:
          oneOf:
            - type: string
            - type: 'null'
        refreshedAt:
          oneOf:
            - type: string
            - type: 'null'
        refreshedByUserId:
          oneOf:
            - type: integer
            - type: 'null'
        resultLocation:
          type: string
        sheetId:
          oneOf:
            - type: string
            - type: 'null'
        sheetName:
          oneOf:
            - type: string
            - type: 'null'
        syncStatus:
          oneOf:
            - $ref: '#/components/schemas/ReportPlacementSyncStatus'
            - type: 'null'
        workbookId:
          type: string
        workbookName:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - workbookId
        - resultLocation
      type: object
    ReportPlacementHost:
      enum:
        - GOOGLE_SHEETS
        - EXCEL
      type: string
    ReportPlacementSyncStatus:
      enum:
        - UP_TO_DATE
        - CHANGED
        - UNKNOWN
      type: string
    ReportSnapshot:
      properties:
        description:
          oneOf:
            - type: string
            - type: 'null'
        fillMissingRows:
          oneOf:
            - $ref: '#/components/schemas/FillMissingRows'
            - type: 'null'
        id:
          type: integer
        isSourceReport:
          oneOf:
            - type: boolean
            - type: 'null'
        kind:
          oneOf:
            - $ref: '#/components/schemas/ReportSnapshotDtoKind'
            - type: 'null'
        meta:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        name:
          oneOf:
            - type: string
            - type: 'null'
        periodComparisons:
          oneOf:
            - items:
                $ref: '#/components/schemas/PeriodComparison'
              type: array
            - type: 'null'
        preferences:
          oneOf:
            - $ref: '#/components/schemas/ReportSnapshotPreferences'
            - type: 'null'
        pythonCode:
          oneOf:
            - type: string
            - type: 'null'
        reportId:
          type: integer
        spec:
          oneOf:
            - oneOf:
                - type: string
                - type: object
            - type: 'null'
        sqlQuery:
          oneOf:
            - type: string
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        versionNumber:
          type: integer
      required:
        - id
        - reportId
        - versionNumber
      type: object
    ReportSnapshotDtoKind:
      enum:
        - vega
        - table
        - kpi
        - html
        - map
        - sankey
      type: string
    ReportSnapshotPreferences:
      properties:
        columnFormats:
          oneOf:
            - type: object
              additionalProperties:
                $ref: '#/components/schemas/ColumnFormatOverride'
            - type: 'null'
      type: object
    ReportsListResponse:
      properties:
        count:
          oneOf:
            - minimum: 0
              type: integer
            - type: 'null'
          description: >-
            Deprecated: total number of accessible reports, ignoring pagination. Kept for backward
            compatibility.
          deprecated: true
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/Report'
          type: array
        items:
          items:
            $ref: '#/components/schemas/Report'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    ResourceOwner:
      properties:
        email:
          type: string
        firstName:
          oneOf:
            - type: string
            - type: 'null'
        id:
          type: integer
        picture:
          oneOf:
            - type: string
            - type: 'null'
      required:
        - id
        - email
      type: object
    RoleWithAccess:
      properties:
        actions:
          items:
            enum:
              - All
              - DeploymentsManage
              - DeploymentCreate
              - DeploymentRead
              - DeploymentUpdate
              - DeploymentDelete
              - SecretsManage
              - DownloadData
              - PlaygroundRead
              - SchemaRead
              - SchemaUpdate
              - SchemaUpdateDevBranches
              - APMRead
              - PreAggregationBuild
              - AlertsCreate
              - AlertsRead
              - AlertsUpdate
              - AlertsDelete
              - AuditLogManage
              - BillingRead
              - SqlRunnerRead
              - DataAssetsRead
              - DataAssetsManage
              - CubeNetworkConnect
              - ReportRead
              - ReportEdit
              - ReportManage
              - WorkbookManage
              - WorkbookRead
              - WorkbookEdit
              - ChatThreadRead
              - AgentManage
              - AgentRead
              - AgentSpaceManage
              - AgentAdmin
              - DeploymentAgentRead
              - OAuthIntegrationsManage
              - OAuthIntegrationsIssueTokens
              - McpToolsManage
              - AIBIDevelop
              - AIBIExplore
              - AIBIView
              - ChartPalettesManage
              - DashboardThemesManage
              - AIBIDeveloper
              - AIBIUser
              - AIBIViewer
              - EmbedDeploymentRead
              - EmbedDashboardRead
              - FolderRead
              - FolderEdit
              - FolderManage
            type: string
          type: array
        id:
          type: integer
        name:
          type: string
      required:
        - id
        - name
        - actions
      type: object
    SetBranchStagingEnvironmentRequest:
      properties:
        branchId:
          oneOf:
            - type: integer
            - type: 'null'
        branchName:
          oneOf:
            - type: string
            - type: 'null'
        enabled:
          type: boolean
      required:
        - enabled
      type: object
    SetBranchStagingEnvironmentResponse:
      properties:
        data:
          $ref: '#/components/schemas/BranchResponse'
      required:
        - data
      type: object
    SetEnvVariablesInput:
      properties:
        env_variables:
          items:
            $ref: '#/components/schemas/EnvVariableItem'
          type: array
      required:
        - env_variables
      type: object
    SheetsUiSettings:
      properties:
        showAppliedFilters:
          oneOf:
            - type: boolean
            - type: 'null'
      type: object
    SheetsUserSettingsInput:
      properties:
        autoRunQueryOnChange:
          oneOf:
            - type: boolean
            - type: 'null'
        openExplorationFromSheet:
          oneOf:
            - type: boolean
            - type: 'null'
        revealSheetOnOpen:
          oneOf:
            - type: boolean
            - type: 'null'
        showAppliedFilters:
          oneOf:
            - type: boolean
            - type: 'null'
        suppressDuplicateValues:
          oneOf:
            - type: boolean
            - type: 'null'
      type: object
    SourceTreeResponse:
      properties:
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            additionalProperties: true
            type: object
          type: array
        items:
          items:
            additionalProperties: true
            type: object
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    StartDbtSyncInput:
      properties:
        branchName:
          oneOf:
            - type: string
            - type: 'null'
        ref:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Git ref in the dbt repository to sync from — a branch or a tag, NOT a commit SHA.
            Overrides the branch saved on the deployment’s dbt git integration for this sync only,
            so CI can sync the ref under review (e.g. a pull request’s head branch) instead of the
            tracked branch. The generated Cube branch is named after it.
      type: object
    StartDevModeRequest:
      properties:
        branchName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    StartUploadResponse:
      properties:
        deploymentName:
          type: string
        transaction:
          $ref: '#/components/schemas/UploadTransaction'
      required:
        - transaction
        - deploymentName
      type: object
    TenantSettings:
      properties:
        auditLogEnabled:
          type: boolean
        auditLogEnabledCurrent:
          type: boolean
        auditLogEnabledTimestamp:
          type: integer
        hasSupportAccess:
          type: boolean
        maintenanceWindowDay:
          type: string
        maintenanceWindowEnabled:
          type: boolean
        maintenanceWindowTime:
          type: string
        oidcEnabled:
          type: boolean
        useAIBIUserInterface:
          type: boolean
      required:
        - auditLogEnabled
        - auditLogEnabledCurrent
        - auditLogEnabledTimestamp
        - hasSupportAccess
        - useAIBIUserInterface
        - maintenanceWindowEnabled
        - maintenanceWindowDay
        - maintenanceWindowTime
        - oidcEnabled
      type: object
    TenantSettingsInput:
      properties:
        auditLogEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        hasSupportAccess:
          oneOf:
            - type: boolean
            - type: 'null'
        maintenanceWindowDay:
          oneOf:
            - type: string
            - type: 'null'
        maintenanceWindowEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        maintenanceWindowTime:
          oneOf:
            - type: string
            - type: 'null'
        oidcEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        useAIBIUserInterface:
          oneOf:
            - type: boolean
            - type: 'null'
      type: object
    ThemeFont:
      properties:
        family:
          oneOf:
            - type: string
            - type: 'null'
        format:
          type: string
        id:
          type: string
        name:
          oneOf:
            - type: string
            - type: 'null'
        url:
          type: string
      required:
        - id
        - url
        - format
      type: object
    TimezoneSettings:
      properties:
        allowUserOverride:
          oneOf:
            - type: boolean
            - type: 'null'
        enabled:
          oneOf:
            - type: boolean
            - type: 'null'
        timezone:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    UpdateDashboardEmbeddingInput:
      properties:
        allowEmbed:
          description: >-
            Whether customer-signed embedding is allowed for this dashboard ("Allow signed
            embedding" in the UI). `true` lets embed sessions fetch the dashboard via `GET
            /api/v1/embed/dashboard/{publicId}`; `false` makes that fetch return `403`. Does not
            affect creator-mode sessions or dashboards shared with all embed users.
          type: boolean
      required:
        - allowEmbed
      type: object
    UpdateDataModelFilesInput:
      properties:
        branchId:
          type: integer
        branchName:
          type: string
        files:
          items:
            $ref: '#/components/schemas/DataModelFileContent'
          type: array
      required:
        - files
      type: object
    UpdateDeploymentInput:
      properties:
        cloudProvider:
          oneOf:
            - $ref: '#/components/schemas/UpdateDeploymentInputCloudProvider'
            - type: 'null'
        creationMethod:
          oneOf:
            - $ref: '#/components/schemas/UpdateDeploymentInputCreationMethod'
            - type: 'null'
        cspsConfig:
          oneOf:
            - $ref: '#/components/schemas/CspsConfigInput'
            - type: 'null'
        customDomain:
          oneOf:
            - type: string
            - type: 'null'
        defaultLaunchpadViewGroup:
          oneOf:
            - type: string
            - type: 'null'
        deployBranchMergeAllowed:
          oneOf:
            - type: boolean
            - type: 'null'
        deployBranchName:
          oneOf:
            - type: string
            - type: 'null'
        deployBranchReadOnly:
          oneOf:
            - type: boolean
            - type: 'null'
        deployMode:
          oneOf:
            - $ref: '#/components/schemas/UpdateDeploymentInputDeployMode'
            - type: 'null'
        deployProjectRoot:
          oneOf:
            - type: string
            - type: 'null'
        launchpadTabs:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        name:
          oneOf:
            - type: string
            - type: 'null'
        region:
          oneOf:
            - type: string
            - type: 'null'
        releaseChannel:
          oneOf:
            - $ref: '#/components/schemas/UpdateDeploymentInputReleaseChannel'
            - type: 'null'
        releaseChannelVersion:
          oneOf:
            - type: string
            - type: 'null'
        releaseChannelVersionHold:
          oneOf:
            - type: boolean
            - type: 'null'
        template:
          oneOf:
            - $ref: '#/components/schemas/UpdateDeploymentInputTemplate'
            - type: 'null'
        templateVariables:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
      type: object
    UpdateDeploymentInputCloudProvider:
      enum:
        - cubecloud
        - aws
        - gcp
      type: string
    UpdateDeploymentInputCreationMethod:
      enum:
        - upload
        - cubecloud
        - github
        - ssh
      type: string
    UpdateDeploymentInputDeployMode:
      enum:
        - git
        - cli
      type: string
    UpdateDeploymentInputReleaseChannel:
      enum:
        - latest
        - release
      type: string
    UpdateDeploymentInputTemplate:
      enum:
        - single
        - simpleCluster
        - multiCluster
      type: string
    UpdateEmbedAccessInput:
      properties:
        action:
          oneOf:
            - $ref: '#/components/schemas/UpdateEmbedAccessInputAction'
            - type: 'null'
        allEmbedUsers:
          oneOf:
            - type: boolean
            - type: 'null'
        allowEmbed:
          oneOf:
            - type: boolean
            - type: 'null'
        embedTenantName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    UpdateEmbedAccessInputAction:
      enum:
        - read
        - none
      type: string
    UpdateEmbedGroupInput:
      properties:
        description:
          oneOf:
            - maxLength: 500
              type: string
            - type: 'null'
          description: New description. Pass an empty string to clear it. Omit to leave it unchanged.
      type: object
    UpdateFolderInput:
      properties:
        name:
          oneOf:
            - maxLength: 255
              type: string
            - type: 'null'
        position:
          oneOf:
            - type: integer
            - type: 'null'
      type: object
    UpdateNotificationInput:
      properties:
        customCron:
          oneOf:
            - type: string
            - type: 'null'
        dayOfMonth:
          oneOf:
            - type: integer
            - type: 'null'
        dayOfWeek:
          oneOf:
            - type: integer
            - type: 'null'
        filters:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardFilterInput'
              type: array
            - type: 'null'
          description: >-
            Dimension filters applied to the dashboard when the notification is rendered. Replaces
            the existing set when provided.
        hour:
          oneOf:
            - type: integer
            - type: 'null'
        isEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
          description: Enable or disable the schedule
        minute:
          oneOf:
            - type: integer
            - type: 'null'
        notificationAiSummary:
          oneOf:
            - type: boolean
            - type: 'null'
          description: Include an AI-generated "what changed" summary in the notification body. Off by default.
        notificationEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        notificationFormat:
          oneOf:
            - $ref: '#/components/schemas/UpdateNotificationInputNotificationFormat'
            - type: 'null'
        scheduleType:
          oneOf:
            - $ref: '#/components/schemas/UpdateNotificationInputScheduleType'
            - type: 'null'
        timeGrains:
          oneOf:
            - items:
                $ref: '#/components/schemas/DashboardTimeGrainInput'
              type: array
            - type: 'null'
          description: >-
            Time-grain overrides applied to the dashboard when the notification is rendered.
            Replaces the existing set when provided.
        timezone:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    UpdateNotificationInputNotificationFormat:
      enum:
        - png
        - pdf
      type: string
    UpdateNotificationInputScheduleType:
      enum:
        - HOURLY
        - DAILY
        - WEEKLY
        - MONTHLY
        - CUSTOM
      type: string
    UpdateOAuthIntegrationInput:
      properties:
        authUrl:
          format: url
          type: string
        clientId:
          type: string
        clientSecret:
          oneOf:
            - type: string
            - type: 'null'
        config:
          additionalProperties: true
          type: object
        name:
          type: string
        redirectUri:
          format: url
          type: string
        scopes:
          items:
            type: string
          type: array
        tokenUrl:
          format: url
          type: string
        type:
          type: string
      required:
        - name
        - type
        - authUrl
        - tokenUrl
        - clientId
        - redirectUri
      type: object
    UpdateOidcTokenConfigInput:
      properties:
        customAudience:
          oneOf:
            - type: string
            - type: 'null'
        customClaims:
          oneOf:
            - type: object
            - type: 'null'
        isEnabled:
          oneOf:
            - type: boolean
            - type: 'null'
        name:
          oneOf:
            - pattern: ^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$
              type: string
            - type: 'null'
        subFormat:
          oneOf:
            - pattern: ^(?:[A-Za-z0-9:_-]|\{(?:deployment_id|component|region)\})+$
              type: string
              maxLength: 200
            - type: 'null'
        targetEnvVar:
          oneOf:
            - pattern: ^[A-Z_][A-Z0-9_]*$
              type: string
              maxLength: 128
            - type: 'null'
      type: object
    UpdatePublishedAiWidgetThreadInput:
      properties:
        checksum:
          oneOf:
            - type: string
            - type: 'null'
        threadId:
          type: string
        widgetId:
          type: string
      required:
        - widgetId
        - threadId
      type: object
    UpdateReportInput:
      properties:
        endResultCell:
          oneOf:
            - type: string
            - type: 'null'
        externalWorkbookId:
          oneOf:
            - type: string
            - type: 'null'
        folderId:
          oneOf:
            - type: integer
            - type: 'null'
        host:
          oneOf:
            - $ref: '#/components/schemas/UpdateReportInputHost'
            - type: 'null'
        jsonQuery:
          oneOf:
            - type: string
            - type: 'null'
        meta:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        name:
          oneOf:
            - type: string
            - type: 'null'
        pivotItems:
          oneOf:
            - $ref: '#/components/schemas/PivotItems'
            - type: 'null'
        placementId:
          oneOf:
            - type: string
            - type: 'null'
        publicId:
          oneOf:
            - pattern: ^[0-9A-Za-z]+$
              type: string
              minLength: 12
              maxLength: 12
            - type: 'null'
        resultLocation:
          oneOf:
            - type: string
            - type: 'null'
        sheetId:
          oneOf:
            - type: string
            - type: 'null'
        sqlQuery:
          oneOf:
            - type: string
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        workbookId:
          oneOf:
            - type: integer
            - type: 'null'
        workbookName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    UpdateReportInputHost:
      enum:
        - GOOGLE_SHEETS
        - EXCEL
      type: string
    UpdateWorkbookInput:
      properties:
        folderId:
          oneOf:
            - type: number
            - type: 'null'
        meta:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        name:
          oneOf:
            - type: string
            - type: 'null'
        slug:
          oneOf:
            - type: string
            - type: 'null'
        slugTakeover:
          oneOf:
            - type: boolean
            - type: 'null'
      type: object
    UploadFileBody:
      properties:
        fileName:
          type: string
        transaction:
          type: string
      required:
        - transaction
        - fileName
      type: object
    UploadTransaction:
      properties:
        id:
          type: string
      required:
        - id
      type: object
    UsageAnalyticsTokenResponse:
      properties:
        apiUrl:
          description: >-
            Base URL of the Usage Analytics deployment’s Cube REST API (e.g.
            `https://<host>/cubejs-api/v1`). Query it with the returned token.
          type: string
        deploymentId:
          description: Id of the Usage Analytics deployment the token was issued for.
          type: integer
        expiresAt:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            When the token expires, as an ISO-8601 timestamp. Request a new token before this moment
            — issuing one is idempotent and cheap.
        token:
          description: >-
            A short-lived JWT for the Usage Analytics deployment, carrying this tenant’s security
            context. Send it as `Authorization: Bearer <token>` on requests to `apiUrl`.
          type: string
      required:
        - token
        - apiUrl
        - deploymentId
      type: object
    User:
      properties:
        activeRoleId:
          oneOf:
            - type: integer
            - type: 'null'
        aliases:
          oneOf:
            - items:
                $ref: '#/components/schemas/UserAlias'
              type: array
            - type: 'null'
        createdAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        defaultRoles:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        email:
          type: string
        externalId:
          oneOf:
            - type: string
            - type: 'null'
        firstName:
          oneOf:
            - type: string
            - type: 'null'
        gitUser:
          oneOf:
            - type: string
            - type: 'null'
        id:
          type: integer
        impersonation:
          oneOf:
            - $ref: '#/components/schemas/UserImpersonationDTO'
            - type: 'null'
        isAdmin:
          type: boolean
        isDeactivated:
          oneOf:
            - type: boolean
            - type: 'null'
        lastLogin:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        notifications:
          additionalProperties: true
          type: object
        picture:
          oneOf:
            - type: string
            - type: 'null'
        samlId:
          oneOf:
            - type: string
            - type: 'null'
        settings:
          oneOf:
            - $ref: '#/components/schemas/UserSettingsInput'
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        tosAccepted:
          oneOf:
            - type: object
            - type: 'null'
        updatedAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        userPolicies:
          oneOf:
            - items:
                $ref: '#/components/schemas/Policy'
              type: array
            - type: 'null'
          description: >-
            The caller's effective resource policies: direct grants, organization-wide grants, and
            grants inherited from their groups. Only populated by `GET /api/v1/users/me`.
        username:
          type: string
      required:
        - id
        - email
        - username
        - isAdmin
        - notifications
      type: object
    UserAlias:
      properties:
        createdAt:
          pattern: \d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d.\d+Z?
          type: string
        id:
          type: integer
        source:
          $ref: '#/components/schemas/UserAliasDTOSource'
        updatedAt:
          pattern: \d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d.\d+Z?
          type: string
        userId:
          type: integer
        username:
          type: string
      required:
        - id
        - userId
        - username
        - source
        - createdAt
        - updatedAt
      type: object
    UserAliasDTOSource:
      enum:
        - ldap
        - saml
        - scim
        - manual
      type: string
    UserAttribute:
      properties:
        defaultValue:
          oneOf:
            - type: string
            - type: 'null'
        description:
          oneOf:
            - type: string
            - type: 'null'
        displayName:
          oneOf:
            - type: string
            - type: 'null'
        id:
          type: integer
        name:
          type: string
        type:
          $ref: '#/components/schemas/UserAttributeType'
      required:
        - id
        - name
        - type
      type: object
    UserAttributeCreateInput:
      properties:
        defaultValue:
          oneOf:
            - type: string
            - type: 'null'
        description:
          oneOf:
            - type: string
            - type: 'null'
        displayName:
          oneOf:
            - type: string
            - type: 'null'
        name:
          minLength: 1
          type: string
        type:
          $ref: '#/components/schemas/UserAttributeCreateInputType'
      required:
        - name
        - type
      type: object
    UserAttributeCreateInputType:
      enum:
        - string
        - number
        - boolean
        - string_array
        - number_array
      type: string
    UserAttributeDefinition:
      properties:
        defaultValue:
          oneOf:
            - type: string
            - type: 'null'
        description:
          oneOf:
            - type: string
            - type: 'null'
        displayName:
          oneOf:
            - type: string
            - type: 'null'
        name:
          type: string
        type:
          $ref: '#/components/schemas/UserAttributeDefinitionDTOType'
      required:
        - name
        - type
      type: object
    UserAttributeDefinitionDTOType:
      enum:
        - string
        - number
        - boolean
        - string_array
        - number_array
      type: string
    UserAttributeInput:
      properties:
        name:
          type: string
        value:
          oneOf:
            - oneOf:
                - type: string
                - type: number
                - type: boolean
                - type: array
                  items:
                    type: string
                - type: array
                  items:
                    type: number
            - type: 'null'
      required:
        - name
      type: object
    UserAttributeType:
      enum:
        - string
        - number
        - boolean
        - string_array
        - number_array
      type: string
    UserAttributeUpdateInput:
      properties:
        defaultValue:
          oneOf:
            - type: string
            - type: 'null'
        description:
          oneOf:
            - type: string
            - type: 'null'
        displayName:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    UserAttributeValue:
      properties:
        description:
          oneOf:
            - type: string
            - type: 'null'
        displayName:
          oneOf:
            - type: string
            - type: 'null'
        formattedValue:
          oneOf:
            - {}
            - type: 'null'
        name:
          type: string
        type:
          $ref: '#/components/schemas/UserAttributeValueType'
        userAttributeId:
          type: integer
        userId:
          type: integer
        value:
          oneOf:
            - {}
            - type: 'null'
      required:
        - userId
        - userAttributeId
        - name
        - type
      type: object
    UserAttributeValueCreateInput:
      properties:
        userAttributeId:
          minLength: 1
          type: string
        userId:
          minLength: 1
          type: string
        value:
          oneOf:
            - {}
            - type: 'null'
      required:
        - userId
        - userAttributeId
      type: object
    UserAttributeValueType:
      enum:
        - string
        - number
        - boolean
        - string_array
        - number_array
      type: string
    UserAttributesListResponse:
      properties:
        count:
          deprecated: true
          description: >-
            Deprecated: total number of user attributes, ignoring pagination. Kept for backward
            compatibility.
          minimum: 0
          type: integer
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/UserAttribute'
          type: array
        items:
          items:
            $ref: '#/components/schemas/UserAttribute'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
        - count
      type: object
    UserCreateInput:
      properties:
        defaultRoles:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        email:
          type: string
        externalId:
          oneOf:
            - type: string
            - type: 'null'
        firstName:
          oneOf:
            - type: string
            - type: 'null'
        isAdmin:
          oneOf:
            - type: boolean
            - type: 'null'
        isExternal:
          oneOf:
            - {}
            - type: 'null'
        password:
          oneOf:
            - type: string
            - type: 'null'
        picture:
          oneOf:
            - {}
            - type: 'null'
        settings:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        username:
          type: string
      required:
        - email
        - username
      type: object
    UserGroupDTO:
      properties:
        description:
          oneOf:
            - type: string
            - type: 'null'
        id:
          type: integer
        name:
          type: string
        userCount:
          oneOf:
            - type: integer
            - type: 'null'
      required:
        - id
        - name
      type: object
    UserGroupsConnectionResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/UserGroupDTO'
          type: array
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
      required:
        - items
        - pageInfo
      type: object
    UserImpersonationDTO:
      properties:
        expiresAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        impersonatedUser:
          oneOf:
            - $ref: '#/components/schemas/User'
            - type: 'null'
        startedAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
      type: object
    UserOAuthToken:
      properties:
        accessTokenExpiresAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        createdAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        id:
          type: integer
        integrationId:
          type: integer
        lastError:
          oneOf:
            - {}
            - type: 'null'
        refreshTokenExpiresAt:
          oneOf:
            - oneOf:
                - format: date
                  type: string
                - format: date-time
                  type: string
            - type: 'null'
        status:
          type: string
        updatedAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        userId:
          type: integer
      required:
        - id
        - userId
        - integrationId
        - status
        - createdAt
        - updatedAt
      type: object
    UserSettingsInput:
      properties:
        alternatingRowColors:
          oneOf:
            - type: boolean
            - type: 'null'
        defaultDeploymentId:
          oneOf:
            - type: integer
            - type: 'null'
        lastSeenChangelogId:
          oneOf:
            - type: integer
            - type: 'null'
          description: >-
            Deprecated and ignored. The changelog now arrives in the notification inbox, which
            carries its own read state. Accepted for backward compatibility but never read or
            written.
          deprecated: true
        locale:
          oneOf:
            - type: string
            - type: 'null'
        sheets:
          oneOf:
            - $ref: '#/components/schemas/SheetsUserSettingsInput'
            - type: 'null'
        theme:
          oneOf:
            - type: string
            - type: 'null'
        timezone:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    UserUpdateInput:
      properties:
        embedTheme:
          oneOf:
            - {}
            - type: 'null'
        firstName:
          oneOf:
            - type: string
            - type: 'null'
        isAdmin:
          oneOf:
            - type: boolean
            - type: 'null'
        isDeactivated:
          oneOf:
            - type: boolean
            - type: 'null'
        lastLogin:
          oneOf:
            - {}
            - type: 'null'
        notifications:
          oneOf:
            - items:
                type: string
              type: array
            - type: 'null'
        password:
          oneOf:
            - type: string
            - type: 'null'
        picture:
          oneOf:
            - {}
            - type: 'null'
        securityContext:
          oneOf:
            - {}
            - type: 'null'
        settings:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
        title:
          oneOf:
            - type: string
            - type: 'null'
        tosAccepted:
          oneOf:
            - type: object
              additionalProperties: true
            - type: 'null'
      type: object
    WidgetThemeBorderSectionInput:
      properties:
        color:
          oneOf:
            - type: string
            - type: 'null'
        radius:
          oneOf:
            - type: string
            - type: 'null'
        style:
          oneOf:
            - type: string
            - type: 'null'
        width:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    WidgetThemeSectionInput:
      properties:
        backgroundColor:
          oneOf:
            - type: string
            - type: 'null'
        border:
          oneOf:
            - $ref: '#/components/schemas/WidgetThemeBorderSectionInput'
            - type: 'null'
        margin:
          oneOf:
            - type: string
            - type: 'null'
        padding:
          oneOf:
            - type: string
            - type: 'null'
        text:
          oneOf:
            - $ref: '#/components/schemas/WidgetThemeTextSectionInput'
            - type: 'null'
        title:
          oneOf:
            - $ref: '#/components/schemas/WidgetThemeTitleSectionInput'
            - type: 'null'
      type: object
    WidgetThemeTextSectionInput:
      properties:
        codeFontFamily:
          oneOf:
            - type: string
            - type: 'null'
        color:
          oneOf:
            - type: string
            - type: 'null'
        fontFamily:
          oneOf:
            - type: string
            - type: 'null'
        secondaryColor:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    WidgetThemeTitleSectionInput:
      properties:
        color:
          oneOf:
            - type: string
            - type: 'null'
        fontFamily:
          oneOf:
            - type: string
            - type: 'null'
        fontSize:
          oneOf:
            - type: string
            - type: 'null'
        fontWeight:
          oneOf:
            - type: string
            - type: 'null'
      type: object
    Workbook:
      properties:
        calculatedFields:
          type: object
        createdAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        createdBy:
          type: integer
        dashboardDraft:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfig'
            - type: 'null'
        dashboardPublished:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfig'
            - type: 'null'
        deploymentId:
          type: integer
        folderId:
          oneOf:
            - type: number
            - type: 'null'
        folderPath:
          items:
            $ref: '#/components/schemas/WorkspaceFolderPathEntry'
          type: array
        id:
          type: integer
        isFavorite:
          oneOf:
            - type: boolean
            - type: 'null'
        meta:
          additionalProperties: true
          type: object
        name:
          type: string
        publishedDashboard:
          oneOf:
            - $ref: '#/components/schemas/Dashboard'
            - type: 'null'
        slug:
          oneOf:
            - type: string
            - type: 'null'
        type:
          $ref: '#/components/schemas/WorkbookDtoType'
        updatedAt:
          oneOf:
            - format: date
              type: string
            - format: date-time
              type: string
        user:
          oneOf:
            - $ref: '#/components/schemas/ResourceOwner'
            - type: 'null'
        userId:
          oneOf:
            - type: number
            - type: 'null'
      required:
        - name
        - meta
        - calculatedFields
        - id
        - deploymentId
        - createdAt
        - updatedAt
        - type
      type: object
    WorkbookDashboard:
      properties:
        dashboardDraft:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfig'
            - type: 'null'
        dashboardPublished:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfig'
            - type: 'null'
      type: object
    WorkbookDashboardInput:
      properties:
        dashboardDraft:
          oneOf:
            - $ref: '#/components/schemas/DashboardConfigInput'
            - type: 'null'
      type: object
    WorkbookDtoType:
      enum:
        - FOLDER
        - WORKBOOK
        - REPORT
      type: string
    WorkbooksListResponse:
      properties:
        count:
          oneOf:
            - minimum: 0
              type: integer
            - type: 'null'
          description: >-
            Deprecated: total number of accessible workbooks, ignoring pagination. Kept for backward
            compatibility.
          deprecated: true
        data:
          deprecated: true
          description: 'Deprecated: use `items` instead. Kept for backward compatibility.'
          items:
            $ref: '#/components/schemas/Workbook'
          type: array
        items:
          items:
            $ref: '#/components/schemas/Workbook'
          type: array
        pageInfo:
          oneOf:
            - $ref: '#/components/schemas/PageInfo'
            - type: 'null'
      required:
        - items
        - data
      type: object
    WorkspaceBulkFailure:
      properties:
        error:
          $ref: '#/components/schemas/BulkActionError'
        id:
          type: integer
        type:
          $ref: '#/components/schemas/WorkspaceBulkFailureType'
      required:
        - error
        - type
        - id
      type: object
    WorkspaceBulkFailureType:
      enum:
        - FOLDER
        - WORKBOOK
        - REPORT
      type: string
    WorkspaceConnectionResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/Workbook'
          type: array
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
      required:
        - items
        - pageInfo
      type: object
    WorkspaceFolderPathEntry:
      properties:
        id:
          type: integer
        name:
          type: string
      required:
        - id
        - name
      type: object
    WorkspaceItemRef:
      properties:
        id:
          type: integer
        type:
          $ref: '#/components/schemas/WorkspaceItemRefType'
      required:
        - type
        - id
      type: object
    WorkspaceItemRefInput:
      properties:
        id:
          type: integer
        type:
          $ref: '#/components/schemas/WorkspaceItemRefInputType'
      required:
        - type
        - id
      type: object
    WorkspaceItemRefInputType:
      enum:
        - FOLDER
        - WORKBOOK
        - REPORT
      type: string
    WorkspaceItemRefType:
      enum:
        - FOLDER
        - WORKBOOK
        - REPORT
      type: string
