openapi: 3.1.0
info:
  title: marimohub API
  version: 1.0.0
  description: API for managing Marimo notebooks, projects, and sandboxes
tags:
  - name: Auth
    description: Authentication
  - name: Projects
    description: Project management
  - name: Alerts
    description: Project alert destinations
  - name: Notebooks
    description: Notebook CRUD and versioning
  - name: Sessions
    description: Notebook session lifecycle
  - name: Jobs
    description: Scheduled and on-demand headless notebook runs
  - name: Integrations
    description: Project and organization integrations
  - name: Secrets
    description: Project secret management
  - name: Users
    description: User identity resolution
  - name: Audit
    description: Deployment and project audit events
  - name: System
    description: Deployment metadata
security:
  - cookieAuth: []
  - bearerAuth: []
components:
  securitySchemes:
    cookieAuth:
      type: apiKey
      in: cookie
      name: mh_session
      description: Session cookie minted by the OIDC login flow; browsers attach it
        automatically.
    bearerAuth:
      type: http
      scheme: bearer
      description: Personal access token (`mhub_pat_…`) minted at POST
        /api/v1/me/tokens, for CI/CLI/service callers. Acts as the issuing user;
        cannot manage tokens.
  schemas:
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - false
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - BAD_REQUEST
                - PRECONDITION_FAILED
                - NOT_FOUND
                - CONFLICT
                - PROPOSAL_RETRY_REQUIRED
                - EDIT_SESSION_OWNED
                - EDIT_SESSION_CHANGED
                - TAKEOVER_IN_PROGRESS
                - FORBIDDEN
                - VALIDATION_ERROR
                - SYNC_NOT_CONFIGURED
                - NOT_INITIALIZED
                - SERVICE_UNAVAILABLE
                - PYTHON_ENV_SETUP_FAILED
                - RESOURCE_EXHAUSTED
                - SURFACE_NOT_ENABLED
                - SURFACE_UNAVAILABLE
                - SURFACE_FORBIDDEN
                - SURFACE_PRIMARY
                - SURFACE_UNSUPPORTED_PROVIDER
                - SURFACE_OPEN_INVALID
                - UNAUTHORIZED
                - USER_SUSPENDED
                - GONE
                - PAYLOAD_TOO_LARGE
                - NO_HTML_SNAPSHOT
                - NO_RUN_OUTPUT
                - INTERNAL_ERROR
            message:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  message:
                    type: string
                required:
                  - field
                  - message
              description: Field-level validation failures.
            request_id:
              type: string
          required:
            - code
            - message
      required:
        - success
        - error
    Me:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
        name:
          type:
            - string
            - 'null'
        picture_url:
          type:
            - string
            - 'null'
          format: uri
        logout_url:
          type:
            - string
            - 'null'
        is_super_admin:
          type: boolean
        can_create_projects:
          type: boolean
      required:
        - id
        - email
        - logout_url
        - is_super_admin
        - can_create_projects
    DeploymentInfo:
      type: object
      properties:
        version:
          type: string
      required:
        - version
    Capabilities:
      type: object
      properties:
        federation:
          type: object
          properties:
            available:
              type: boolean
          required:
            - available
        integrations:
          type: object
          properties:
            available:
              type: boolean
          required:
            - available
        source_control:
          type: object
          properties:
            change_request_providers:
              type: array
              items:
                type: string
              description: Provider ids configured to publish pull requests, merge requests,
                or equivalents from notebook sessions.
              example:
                - github
            sync_providers:
              type: array
              items:
                type: string
              description: Provider ids configured for server-initiated pull sync (drift
                lookup and "Sync now").
              example:
                - github
            pull_source_providers:
              type: array
              items:
                type: string
              description: Provider ids configured to create pull-mode sources with
                server-materialized Git metadata.
              example:
                - github
          required:
            - change_request_providers
            - sync_providers
            - pull_source_providers
        project_alerts:
          type: object
          properties:
            available:
              type: boolean
            destination_types:
              type: array
              items:
                type: string
                enum:
                  - slack
                  - webhook
                  - unknown
                description: 'Known values: slack, webhook. Unrecognized values normalize to
                  unknown.'
                example: slack
            selectable_kinds:
              type: array
              items:
                type: string
                enum:
                  - member.invited
                  - member.added
                  - member.role_changed
                  - member.removed
                  - session.takeover
                  - notebook.deleted
                  - project.deleted
                  - app.start_failed
                  - app.unavailable
                  - sync.failed
                  - job.run.failed
                  - job.run.succeeded
                  - unknown
                description: 'Known values: member.invited, member.added, member.role_changed,
                  member.removed, session.takeover, notebook.deleted,
                  project.deleted, app.start_failed, app.unavailable,
                  sync.failed, job.run.failed, job.run.succeeded. Unrecognized
                  values normalize to unknown.'
                example: member.invited
            max_destinations:
              type: integer
              exclusiveMinimum: 0
          required:
            - available
            - destination_types
            - selectable_kinds
            - max_destinations
        jobs:
          type: object
          properties:
            available:
              type: boolean
            max_per_notebook:
              type:
                - integer
                - 'null'
            max_queued_runs_per_job:
              type:
                - integer
                - 'null'
              exclusiveMinimum: 0
            default_timeout_seconds:
              type:
                - integer
                - 'null'
            max_timeout_seconds:
              type:
                - integer
                - 'null'
            run_retention_days:
              type:
                - number
                - 'null'
          required:
            - available
            - max_per_notebook
            - max_queued_runs_per_job
            - default_timeout_seconds
            - max_timeout_seconds
            - run_retention_days
        data_browser:
          type: object
          properties:
            available:
              type: boolean
            preview:
              type: boolean
            query:
              type: boolean
            ai_query:
              type: boolean
          required:
            - available
            - preview
            - query
            - ai_query
        viewer_mode:
          type: string
          enum:
            - static
            - applications
            - ephemeral-sandbox
        viewer_session_modes:
          type: array
          items:
            type: string
            enum:
              - edit
              - app
        editor_sandbox_sharing:
          type: string
          enum:
            - shared
            - exclusive
        default_role:
          type:
            - string
            - 'null'
          enum:
            - manager
            - editor
            - viewer
            - null
        limits:
          type: object
          properties:
            max_concurrent_sessions_per_user:
              type:
                - number
                - 'null'
            max_apps_per_project:
              type:
                - number
                - 'null'
            max_request_bytes:
              type: number
            max_versions_per_notebook:
              type: number
            default_page_size:
              type: number
            max_page_size:
              type: number
          required:
            - max_concurrent_sessions_per_user
            - max_apps_per_project
            - max_request_bytes
            - max_versions_per_notebook
            - default_page_size
            - max_page_size
        sandbox_images:
          type: array
          items:
            type: string
        sandbox_startup_timeout_seconds:
          type: number
        compute_profiles:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/ComputeResources'
              - type: object
                properties:
                  name:
                    type: string
                required:
                  - name
        compute_profile_override:
          type: string
          enum:
            - none
            - editors
        surfaces:
          type: array
          items:
            oneOf:
              - type: object
                properties:
                  id:
                    type: string
                    enum:
                      - vscode
                  flavor:
                    type: string
                    enum:
                      - code-server
                      - openvscode
                  start:
                    type: string
                    enum:
                      - on-demand
                      - eager
                  embed:
                    type: string
                    enum:
                      - tab
                      - iframe
                required:
                  - id
                  - flavor
                  - start
                  - embed
              - type: object
                properties:
                  id:
                    type: string
                    enum:
                      - opencode
                  start:
                    type: string
                    enum:
                      - on-demand
                      - eager
                  embed:
                    type: string
                    enum:
                      - tab
                      - iframe
                  managed_ai:
                    type: boolean
                required:
                  - id
                  - start
                  - embed
                  - managed_ai
      required:
        - federation
        - integrations
        - source_control
        - project_alerts
        - jobs
        - data_browser
        - viewer_mode
        - viewer_session_modes
        - editor_sandbox_sharing
        - default_role
        - limits
        - sandbox_images
        - sandbox_startup_timeout_seconds
        - compute_profiles
        - compute_profile_override
        - surfaces
    ComputeResources:
      type: object
      properties:
        cpu:
          type: number
        memory_bytes:
          type: number
        gpu:
          type: string
    ProjectPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/SnapshotProjectEntry'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    SnapshotProjectEntry:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        owner:
          type: string
        status:
          type: string
          enum:
            - active
            - deleted
        created_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        updated_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        notebook_count:
          type: number
      required:
        - id
        - name
        - description
        - owner
        - status
        - created_at
        - updated_at
        - notebook_count
    Project:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        owner:
          type: string
        members:
          type: array
          items:
            $ref: '#/components/schemas/ProjectMember'
        status:
          type: string
          enum:
            - active
            - deleted
        created_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        updated_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        tags:
          type: array
          items:
            type: string
        federation:
          $ref: '#/components/schemas/ProjectFederation'
        security_labels:
          $ref: '#/components/schemas/SecurityLabels'
        your_role:
          type:
            - string
            - 'null'
          enum:
            - admin
            - manager
            - editor
            - viewer
            - null
      required:
        - id
        - name
        - description
        - owner
        - members
        - status
        - created_at
        - updated_at
        - tags
        - your_role
    ProjectMember:
      type: object
      properties:
        user_id:
          type: string
        email:
          type: string
        role:
          type: string
          enum:
            - admin
            - manager
            - editor
            - viewer
      required:
        - role
    ProjectFederation:
      type: object
      properties:
        enabled:
          type: boolean
        target:
          type: string
      required:
        - enabled
    SecurityLabels:
      type: object
      properties:
        classification:
          type: string
        compartments:
          type: array
          items:
            type: string
      required:
        - classification
        - compartments
    ProjectFederationInput:
      type: object
      properties:
        enabled:
          type: boolean
          example: true
        target:
          type: string
          example: default
      required:
        - enabled
    SecurityLabelsInput:
      type: object
      properties:
        classification:
          type: string
          pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
        compartments:
          type: array
          items:
            type: string
            pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
          maxItems: 64
      required:
        - classification
        - compartments
    SuccessResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
      required:
        - success
    AssignableRole:
      type: string
      enum:
        - manager
        - editor
        - viewer
      example: editor
    ProjectAlertDestinationPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/ProjectAlertDestination'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    ProjectAlertDestination:
      oneOf:
        - type: object
          properties:
            id:
              type: string
              pattern: ^alert-[0-9a-z]{16}$
            name:
              type: string
            kinds:
              type: array
              items:
                type: string
                enum: &a1
                  - member.invited
                  - member.added
                  - member.role_changed
                  - member.removed
                  - session.takeover
                  - notebook.deleted
                  - project.deleted
                  - app.start_failed
                  - app.unavailable
                  - sync.failed
                  - job.run.failed
                  - job.run.succeeded
                  - unknown
                description: 'Known values: member.invited, member.added, member.role_changed,
                  member.removed, session.takeover, notebook.deleted,
                  project.deleted, app.start_failed, app.unavailable,
                  sync.failed, job.run.failed, job.run.succeeded. Unrecognized
                  values normalize to unknown.'
                example: member.invited
            enabled:
              type: boolean
            verified_at:
              type:
                - string
                - 'null'
              format: date-time
            endpoint_host:
              type: string
            created_by:
              type: string
            created_at:
              type: string
              format: date-time
            updated_at:
              type: string
              format: date-time
            type:
              type: string
              enum:
                - slack
            webhook_url_set:
              type: boolean
              enum:
                - true
          required:
            - id
            - name
            - kinds
            - enabled
            - verified_at
            - endpoint_host
            - created_by
            - created_at
            - updated_at
            - type
            - webhook_url_set
        - type: object
          properties:
            id:
              type: string
              pattern: ^alert-[0-9a-z]{16}$
            name:
              type: string
            kinds:
              type: array
              items:
                type: string
                enum: *a1
                description: 'Known values: member.invited, member.added, member.role_changed,
                  member.removed, session.takeover, notebook.deleted,
                  project.deleted, app.start_failed, app.unavailable,
                  sync.failed, job.run.failed, job.run.succeeded. Unrecognized
                  values normalize to unknown.'
                example: member.invited
            enabled:
              type: boolean
            verified_at:
              type:
                - string
                - 'null'
              format: date-time
            endpoint_host:
              type: string
            created_by:
              type: string
            created_at:
              type: string
              format: date-time
            updated_at:
              type: string
              format: date-time
            type:
              type: string
              enum:
                - webhook
            url_set:
              type: boolean
              enum:
                - true
            signing_secret_set:
              type: boolean
              enum:
                - true
          required:
            - id
            - name
            - kinds
            - enabled
            - verified_at
            - endpoint_host
            - created_by
            - created_at
            - updated_at
            - type
            - url_set
            - signing_secret_set
    AuditLogPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/AuditLogEntry'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    AuditLogEntry:
      type: object
      properties:
        id:
          type: string
        schema_version:
          type: integer
          exclusiveMinimum: 0
        ts:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        event:
          type: string
          example: project.update
        actor:
          type: string
        metadata:
          type: object
          additionalProperties: {}
      required:
        - id
        - schema_version
        - ts
        - event
        - actor
        - metadata
    AuditEvent:
      type: object
      properties:
        ts:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        event:
          type: string
          example: project.update
        actor:
          type: string
      required:
        - ts
        - event
        - actor
      additionalProperties: {}
    AdminUserPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/AdminUser'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    AdminUser:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
        name:
          type: string
        updated_at:
          type: string
          format: date-time
        suspended_at:
          type:
            - string
            - 'null'
          format: date-time
        is_super_admin:
          type: boolean
      required:
        - id
        - email
        - name
        - updated_at
        - suspended_at
        - is_super_admin
    SandboxStartupReport:
      type: object
      properties:
        ok:
          type: boolean
        sandbox_id:
          type: string
        image:
          type:
            - string
            - 'null'
        compute_profile:
          type:
            - string
            - 'null'
        compute_resources:
          $ref: '#/components/schemas/ComputeResources'
        started_at:
          type: string
          format: date-time
        finished_at:
          type: string
          format: date-time
        total_ms:
          type: number
          minimum: 0
        handle:
          $ref: '#/components/schemas/SandboxStartupPhase'
        readiness:
          $ref: '#/components/schemas/SandboxStartupCommand'
        exec:
          $ref: '#/components/schemas/SandboxStartupCommand'
        cleanup:
          $ref: '#/components/schemas/SandboxStartupPhase'
        startup_timings_ms:
          type: object
          additionalProperties:
            type: number
            minimum: 0
        counters:
          type: object
          additionalProperties:
            type: number
        environment_setup_benchmark:
          $ref: '#/components/schemas/SandboxEnvironmentSetupBenchmark'
      required:
        - ok
        - sandbox_id
        - image
        - compute_profile
        - compute_resources
        - started_at
        - finished_at
        - total_ms
        - handle
        - readiness
        - exec
        - cleanup
        - startup_timings_ms
        - counters
        - environment_setup_benchmark
    SandboxStartupPhase:
      type: object
      properties:
        status:
          type: string
          enum:
            - ok
            - failed
            - skipped
            - unknown
          description: 'Known values: ok, failed, skipped. Unrecognized values normalize
            to unknown.'
          example: ok
        duration_ms:
          type:
            - number
            - 'null'
          minimum: 0
        error:
          type: object
          additionalProperties: {}
      required:
        - status
        - duration_ms
    SandboxStartupCommand:
      allOf:
        - $ref: '#/components/schemas/SandboxStartupPhase'
        - type: object
          properties:
            command:
              type: string
              example: echo "Hello"
            stdout:
              type: string
            stderr:
              type: string
            failure_code:
              type: string
              enum:
                - COMMAND_FAILED
                - SPAWN_FAILED
                - BACKEND_ERROR
                - unknown
              description: 'Known values: COMMAND_FAILED, SPAWN_FAILED, BACKEND_ERROR.
                Unrecognized values normalize to unknown.'
              example: COMMAND_FAILED
          required:
            - command
            - stdout
            - stderr
    SandboxEnvironmentSetupBenchmark:
      type:
        - object
        - 'null'
      properties:
        tool:
          type: string
          minLength: 1
          example: uv
        runtime_probe:
          $ref: '#/components/schemas/SandboxStartupCommand'
        artifact_download:
          $ref: '#/components/schemas/SandboxStartupCommand'
        prepare:
          $ref: '#/components/schemas/SandboxStartupCommand'
        install:
          $ref: '#/components/schemas/SandboxStartupCommand'
      required:
        - tool
        - runtime_probe
        - artifact_download
        - prepare
        - install
      description: The optional fixed-package benchmark, or null when it was not requested
    SandboxStartupRequest:
      type: object
      properties:
        image:
          type: string
          minLength: 1
        compute_profile:
          type: string
          minLength: 1
        environment_setup_benchmark:
          type: boolean
          description: Run the fixed-package uv, wheel-download, runtime, and
            CPU-throttling benchmark
      additionalProperties: false
    DeploymentConfig:
      type: object
      properties:
        deployment:
          $ref: '#/components/schemas/AdminDeployment'
        groups:
          type: array
          items:
            $ref: '#/components/schemas/ConfigGroup'
        policy:
          $ref: '#/components/schemas/AdminPolicy'
      required:
        - deployment
        - groups
        - policy
    AdminDeployment:
      type:
        - object
        - 'null'
      properties:
        version:
          type: string
        image:
          type:
            - string
            - 'null'
        sandbox_image:
          type:
            - string
            - 'null'
        started_at:
          type:
            - string
            - 'null'
        replica:
          type:
            - string
            - 'null'
        node:
          type:
            - string
            - 'null'
        backends:
          type:
            - object
            - 'null'
          properties:
            storage:
              type: string
            compute:
              type: string
            auth:
              type: string
          required:
            - storage
            - compute
            - auth
      required:
        - version
        - image
        - sandbox_image
        - started_at
        - replica
        - node
        - backends
    ConfigGroup:
      type: object
      properties:
        name:
          type: string
        backend:
          type:
            - string
            - 'null'
        settings:
          type: array
          items:
            $ref: '#/components/schemas/ConfigSetting'
      required:
        - name
        - backend
        - settings
    ConfigSetting:
      type: object
      properties:
        key:
          type: string
        name:
          type: string
        value:
          type:
            - string
            - 'null'
        secret:
          type: boolean
        set:
          type: boolean
      required:
        - key
        - name
        - value
        - secret
        - set
    AdminPolicy:
      type: object
      properties:
        default_role:
          type:
            - string
            - 'null'
          enum:
            - manager
            - editor
            - viewer
            - null
        super_admins:
          type: array
          items:
            type: string
      required:
        - default_role
        - super_admins
    PolicyAnalyzerMetadata:
      type: object
      properties:
        schema_version:
          type: number
          enum:
            - 1
        max_cases:
          type: integer
          exclusiveMinimum: 0
        capabilities:
          type: object
          properties:
            login_policy:
              type: boolean
            resource_security:
              type: boolean
            live_self_context:
              type: boolean
          required:
            - login_policy
            - resource_security
            - live_self_context
          additionalProperties: false
        entitlements:
          type: array
          items:
            type: string
            enum:
              - super-admin
              - project-creator
              - default-role:viewer
              - default-role:editor
              - default-role:manager
        classification_order:
          type: array
          items:
            type: string
        actions:
          type: array
          items:
            type: object
            properties:
              action:
                type: string
                enum:
                  - project.create
                  - admin.access
                  - org-integration.manage
                  - audit.global.read
                  - directory.search
                  - project.read
                  - project.update
                  - project.delete
                  - project.members.manage
                  - project.events.read
                  - project.alerts.manage
                  - notebook.write
                  - notebook.manage
                  - integration.read
                  - integration.use
                  - integration.manage
                  - change-request.publish
                  - security-labels.raise
                  - security-labels.lower
                  - session.attach
                  - session.stop
                  - session.surface
                  - session.proxy
                  - session.start
              scope:
                type: string
                enum:
                  - deployment
                  - project
                  - session
                  - session-start
              minimum_role:
                type:
                  - string
                  - 'null'
                enum:
                  - viewer
                  - editor
                  - manager
                  - admin
                  - null
              denied_as:
                type:
                  - string
                  - 'null'
                enum:
                  - not-found
                  - forbidden
                  - null
              requires_super_admin:
                type: boolean
            required:
              - action
              - scope
              - minimum_role
              - denied_as
              - requires_super_admin
            additionalProperties: false
      required:
        - schema_version
        - max_cases
        - capabilities
        - entitlements
        - classification_order
        - actions
      additionalProperties: false
    PolicySuiteResult:
      type: object
      properties:
        valid:
          type: boolean
        summary:
          $ref: '#/components/schemas/PolicySuiteSummary'
        cases:
          type: array
          items:
            $ref: '#/components/schemas/PolicyCaseResult'
      required:
        - valid
        - summary
        - cases
      additionalProperties: false
    PolicySuiteSummary:
      type: object
      properties:
        case_count:
          type: integer
          minimum: 0
        passed:
          type: integer
          minimum: 0
        failed:
          type: integer
          minimum: 0
      required:
        - case_count
        - passed
        - failed
      additionalProperties: false
    PolicyCaseResult:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        valid:
          type: boolean
        login:
          $ref: '#/components/schemas/PolicyLoginResult'
        authorization:
          $ref: '#/components/schemas/PolicyAuthorizationResult'
        errors:
          type: array
          items:
            type: object
            properties:
              stage:
                type: string
                enum:
                  - login
                  - authorization
              code:
                type: string
            required:
              - stage
              - code
            additionalProperties: false
      required:
        - id
        - name
        - valid
        - login
        - authorization
        - errors
      additionalProperties: false
    PolicyLoginResult:
      type:
        - object
        - 'null'
      properties:
        outcome:
          type: string
          enum:
            - allow
            - deny
            - timeout
            - error
            - invalid
            - unavailable
        duration_ms:
          type: number
          minimum: 0
        entitlements:
          type: array
          items:
            type: string
            enum:
              - super-admin
              - project-creator
              - default-role:viewer
              - default-role:editor
              - default-role:manager
        reason:
          type: string
        problem:
          type: string
        assertion:
          $ref: '#/components/schemas/PolicyAssertionResult'
      required:
        - outcome
        - duration_ms
        - entitlements
        - assertion
      additionalProperties: false
    PolicyAssertionResult:
      type: object
      properties:
        passed:
          type: boolean
        expected:
          type: object
          additionalProperties: {}
      required:
        - passed
        - expected
      additionalProperties: false
    PolicyAuthorizationResult:
      type:
        - object
        - 'null'
      properties:
        decision:
          $ref: '#/components/schemas/PolicyAuthorizationDecision'
        presentation:
          type: string
          enum:
            - allowed
            - forbidden
            - not-found
        trace:
          type: array
          items:
            $ref: '#/components/schemas/PolicyAuthorizationTraceStep'
        assertion:
          $ref: '#/components/schemas/PolicyAssertionResult'
      required:
        - decision
        - presentation
        - trace
        - assertion
      additionalProperties: false
    PolicyAuthorizationDecision:
      type: object
      properties:
        allowed:
          type: boolean
        role:
          type:
            - string
            - 'null'
          enum:
            - viewer
            - editor
            - manager
            - admin
            - null
        category:
          type: string
          enum:
            - lifecycle
            - visibility
            - role
            - session
            - standing
            - constraint
            - credential-resource
            - credential-action
        constraint_reason:
          type: string
          enum:
            - missing-context
            - constraint
            - unavailable
      required:
        - allowed
        - role
      additionalProperties: false
    PolicyAuthorizationTraceStep:
      type: object
      properties:
        stage:
          type: string
          enum:
            - action
            - lifecycle
            - role
            - standing
            - session
            - constraint
            - credential
            - final
        status:
          type: string
          enum:
            - passed
            - failed
            - skipped
        code:
          type: string
        details:
          type: object
          additionalProperties: {}
      required:
        - stage
        - status
        - code
      additionalProperties: false
    PolicySuiteV1:
      type: object
      properties:
        schema_version:
          type: number
          enum:
            - 1
        name:
          type: string
          minLength: 1
          maxLength: 200
        cases:
          type: array
          items:
            $ref: '#/components/schemas/PolicyCaseV1'
          minItems: 1
          maxItems: 25
      required:
        - schema_version
        - cases
      additionalProperties: false
    PolicyCaseV1:
      anyOf:
        - type: object
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 128
            name:
              type: string
              minLength: 1
              maxLength: 200
            login:
              $ref: '#/components/schemas/PolicyLoginStageV1'
            authorization:
              $ref: '#/components/schemas/PolicyAuthorizationStageV1'
          required:
            - id
            - name
            - login
          additionalProperties: false
        - type: object
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 128
            name:
              type: string
              minLength: 1
              maxLength: 200
            login:
              $ref: '#/components/schemas/PolicyLoginStageV1'
            authorization:
              $ref: '#/components/schemas/PolicyAuthorizationStageV1'
          required:
            - id
            - name
            - authorization
          additionalProperties: false
    PolicyLoginStageV1:
      type: object
      properties:
        identity:
          type: object
          properties:
            id:
              type: string
              minLength: 1
            email:
              type: string
              minLength: 3
              maxLength: 320
          required:
            - id
            - email
          additionalProperties: false
        id_token_claims:
          type: object
          additionalProperties: {}
        user_info_claims:
          type: object
          additionalProperties: {}
        expected:
          $ref: '#/components/schemas/PolicyLoginExpectationV1'
      required:
        - identity
        - id_token_claims
        - expected
      additionalProperties: false
    PolicyLoginExpectationV1:
      oneOf:
        - type: object
          properties:
            outcome:
              type: string
              enum:
                - allow
            entitlements:
              type: array
              items:
                type: string
                enum:
                  - super-admin
                  - project-creator
                  - default-role:viewer
                  - default-role:editor
                  - default-role:manager
          required:
            - outcome
          additionalProperties: false
        - type: object
          properties:
            outcome:
              type: string
              enum:
                - deny
          required:
            - outcome
          additionalProperties: false
    PolicyAuthorizationStageV1:
      type: object
      properties:
        subject:
          type: object
          properties:
            id:
              type: string
              minLength: 1
            email:
              type: string
              minLength: 3
              maxLength: 320
            entitlement_source:
              type: string
              enum:
                - explicit
                - login
            entitlements:
              type: array
              items:
                type: string
                enum:
                  - super-admin
                  - project-creator
                  - default-role:viewer
                  - default-role:editor
                  - default-role:manager
            grant:
              type: object
              properties:
                actions:
                  anyOf:
                    - type: string
                      enum:
                        - '*'
                    - type: array
                      items:
                        type: string
                        enum:
                          - project.create
                          - admin.access
                          - org-integration.manage
                          - audit.global.read
                          - directory.search
                          - project.read
                          - project.update
                          - project.delete
                          - project.members.manage
                          - project.events.read
                          - project.alerts.manage
                          - notebook.write
                          - notebook.manage
                          - integration.read
                          - integration.use
                          - integration.manage
                          - change-request.publish
                          - security-labels.raise
                          - security-labels.lower
                          - session.attach
                          - session.stop
                          - session.surface
                          - session.proxy
                          - session.start
                      uniqueItems: true
                projects:
                  anyOf:
                    - type: string
                      enum:
                        - '*'
                    - type: array
                      items:
                        type: string
                        pattern: ^proj-[0-9a-z]{16}$
                      minItems: 1
                      maxItems: 100
                      uniqueItems: true
              required:
                - actions
                - projects
              additionalProperties: false
          required:
            - id
            - email
            - entitlement_source
          additionalProperties: false
        action:
          type: string
          enum:
            - project.create
            - admin.access
            - org-integration.manage
            - audit.global.read
            - directory.search
            - project.read
            - project.update
            - project.delete
            - project.members.manage
            - project.events.read
            - project.alerts.manage
            - notebook.write
            - notebook.manage
            - integration.read
            - integration.use
            - integration.manage
            - change-request.publish
            - security-labels.raise
            - security-labels.lower
            - session.attach
            - session.stop
            - session.surface
            - session.proxy
            - session.start
        resource:
          $ref: '#/components/schemas/PolicyAuthorizationResourceV1'
        context:
          $ref: '#/components/schemas/PolicyAuthorizationContextV1'
        expected:
          type: object
          properties:
            allowed:
              type: boolean
            denial_category:
              type: string
              enum:
                - lifecycle
                - visibility
                - role
                - session
                - standing
                - constraint
                - credential-resource
                - credential-action
          required:
            - allowed
          additionalProperties: false
      required:
        - subject
        - action
        - resource
        - context
        - expected
      additionalProperties: false
    PolicyAuthorizationResourceV1:
      type: object
      properties:
        source:
          type: string
          enum:
            - stored
            - synthetic
        kind:
          type: string
          enum:
            - deployment
            - project
            - session
            - session-start
        project_id:
          type: string
        notebook_id:
          type: string
        session_id:
          type: string
        project:
          type: object
          properties:
            owner:
              type: string
              minLength: 1
            members:
              type: array
              items:
                type: object
                properties:
                  user_id:
                    type: string
                    minLength: 1
                  email:
                    type: string
                    minLength: 3
                    maxLength: 320
                  role:
                    type: string
                    enum:
                      - viewer
                      - editor
                      - manager
                      - admin
                required:
                  - role
                additionalProperties: false
              maxItems: 500
            status:
              type: string
              enum:
                - active
                - deleted
              default: active
            security_labels:
              type: object
              properties:
                classification:
                  type: string
                  pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
                compartments:
                  type: array
                  items:
                    type: string
                    pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
                  maxItems: 64
              required:
                - classification
                - compartments
              additionalProperties: false
          required:
            - owner
            - members
          additionalProperties: false
        notebook_labels:
          type: object
          properties:
            classification:
              type: string
              pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
            compartments:
              type: array
              items:
                type: string
                pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
              maxItems: 64
          required:
            - classification
            - compartments
          additionalProperties: false
        session:
          type: object
          properties:
            mode:
              type: string
              enum:
                - edit
                - app
            ephemeral:
              type: boolean
            user_id:
              type: string
              minLength: 1
            editor_sandbox_sharing:
              type: string
              enum:
                - shared
                - exclusive
          required:
            - user_id
          additionalProperties: false
        mode:
          type: string
          enum:
            - edit
            - app
      required:
        - source
        - kind
      additionalProperties: false
    PolicyAuthorizationContextV1:
      oneOf:
        - type: object
          properties:
            mode:
              type: string
              enum:
                - live-self
          required:
            - mode
          additionalProperties: false
        - type: object
          properties:
            mode:
              type: string
              enum:
                - synthetic
            value:
              type:
                - object
                - 'null'
              properties:
                schemaVersion:
                  type: number
                  enum:
                    - 1
                classification:
                  type: string
                  pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
                compartments:
                  type: array
                  items:
                    type: string
                    pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
                  maxItems: 64
                policyVersion:
                  type: string
                  pattern: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,63}$
                expiresAt:
                  type: string
                  format: date-time
              required:
                - schemaVersion
                - classification
                - compartments
                - policyVersion
                - expiresAt
              additionalProperties: false
          required:
            - mode
            - value
          additionalProperties: false
    WorkspaceItem:
      type: object
      properties:
        path:
          type: string
        name:
          type: string
        kind:
          type: string
          enum:
            - file
            - directory
        size:
          type: integer
          minimum: 0
        modified_at:
          type: integer
          minimum: 0
        mime_type:
          type: string
      required:
        - path
        - name
        - kind
    WorkspaceAccess:
      type: object
      properties:
        writable:
          type: boolean
        read_only_reason:
          type:
            - string
            - 'null'
          enum:
            - git_source
            - viewer
            - active_session
            - null
        protected_paths:
          type: array
          items:
            type: object
            properties:
              path:
                type: string
              denied_operations:
                type: array
                items:
                  type: string
                  enum:
                    - create
                    - write
                    - move
                    - copy
                    - delete
            required:
              - path
              - denied_operations
      required:
        - writable
        - read_only_reason
        - protected_paths
    NotebookPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/SnapshotNotebookEntry'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    SnapshotNotebookEntry:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum:
            - draft
            - active
            - archived
            - deleted
        source_type:
          type: string
          enum:
            - local
            - git
        author:
          type: string
        created_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        updated_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        tags:
          type: array
          items:
            type: string
        last_run_at:
          type:
            - string
            - 'null'
          format: date-time
          example: 2025-03-05T14:00:00Z
        compute_profile:
          type: string
      required:
        - id
        - title
        - description
        - status
        - source_type
        - author
        - created_at
        - updated_at
        - tags
        - last_run_at
    NotebookMeta:
      type: object
      properties:
        id:
          type: string
        project_id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum:
            - draft
            - active
            - archived
            - deleted
        author:
          type: string
        created_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        updated_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        last_run_at:
          type:
            - string
            - 'null'
          format: date-time
          example: 2025-03-05T14:00:00Z
        tags:
          type: array
          items:
            type: string
        runtime:
          type: object
          properties:
            python_version:
              type: string
            marimo_version:
              type: string
        base_image:
          type: string
        compute_profile:
          type: string
        security_labels:
          $ref: '#/components/schemas/SecurityLabels'
      required:
        - id
        - project_id
        - title
        - description
        - status
        - author
        - created_at
        - updated_at
        - last_run_at
        - tags
    GitNotebookCreateResult:
      type: object
      properties:
        notebook:
          $ref: '#/components/schemas/NotebookMeta'
        sync_url:
          type: string
        sync_token:
          type: string
        sync_error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
          required:
            - code
            - message
          description: Initial pull failure. The draft notebook remains available and can
            be retried with Sync now.
      required:
        - notebook
    SyncToken:
      type: object
      properties:
        sync_url:
          type: string
        sync_token:
          type: string
      required:
        - sync_url
        - sync_token
    GitSourceConfig:
      type: object
      properties:
        repo:
          type: string
          description: 'Normalized repository coordinate: owner/repo or an HTTPS
            repository URL.'
          example: marimo-team/marimohub
        branch:
          type: string
          description: Synced repository branch.
          example: main
        root_path:
          type: string
          description: Repository-relative directory synced into the notebook workspace.
          example: apps
        entry_notebook:
          type: string
          description: Path to the entry notebook relative to root_path.
          example: dashboard.py
      required:
        - repo
        - branch
        - root_path
        - entry_notebook
    SourceDrift:
      type: object
      properties:
        current_commit:
          type:
            - string
            - 'null'
          description: Commit of the last successful sync; null before the first sync.
        remote_commit:
          type: string
          description: Live head of the configured branch, resolved at request time.
        in_sync:
          type: boolean
        pending_config:
          type: boolean
          description: Whether a settings edit is waiting for a matching sync.
        checked_at:
          type: string
          format: date-time
      required:
        - current_commit
        - remote_commit
        - in_sync
        - pending_config
        - checked_at
    SourceSyncResult:
      type: object
      properties:
        synced:
          type: boolean
          description: False when the notebook was already at the branch head.
        commit:
          type: string
        version_id:
          type:
            - string
            - 'null'
      required:
        - synced
        - commit
        - version_id
    NotebookDetail:
      type: object
      properties:
        meta:
          $ref: '#/components/schemas/NotebookMeta'
        readme:
          type:
            - string
            - 'null'
        source:
          $ref: '#/components/schemas/Source'
      required:
        - meta
        - readme
        - source
    Source:
      oneOf:
        - type: object
          properties:
            type:
              type: string
              enum:
                - local
            current_version_id:
              type: string
          required:
            - type
            - current_version_id
        - type: object
          properties:
            type:
              type: string
              enum:
                - git
            provider:
              type:
                - string
                - 'null'
              minLength: 1
              description: Detected Git provider id, or null when the repository host is not
                recognized.
              example: github
            repo:
              type: string
              description: 'Normalized repository coordinate: owner/repo or an HTTPS
                repository URL.'
              example: marimo-team/marimohub
            branch:
              type: string
              description: Synced repository branch.
              example: main
            root_path:
              type: string
              description: Repository-relative directory synced into the notebook workspace.
              example: apps
            entry_notebook:
              type: string
              description: Path to the entry notebook relative to root_path.
              example: dashboard.py
            pending_config:
              $ref: '#/components/schemas/GitSourceConfig'
            sync_mode:
              type: string
              enum:
                - push
                - pull
            current_version_id:
              type:
                - string
                - 'null'
            commit:
              type:
                - string
                - 'null'
            last_synced_at:
              type:
                - string
                - 'null'
              format: date-time
              example: 2025-03-05T14:00:00Z
          required:
            - type
            - provider
            - repo
            - branch
            - root_path
            - entry_notebook
            - sync_mode
            - current_version_id
            - commit
            - last_synced_at
    NotebookVersionPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/NotebookVersion'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    NotebookVersion:
      type: object
      properties:
        version_id:
          type: string
        notebook_id:
          type: string
        saved_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        author:
          type: string
        message:
          type: string
        parent_id:
          type:
            - string
            - 'null'
        html_snapshot:
          $ref: '#/components/schemas/SnapshotDescriptor'
        session_snapshot:
          $ref: '#/components/schemas/SnapshotDescriptor'
        commit:
          type: string
        git_source:
          $ref: '#/components/schemas/GitSourceRevision'
      required:
        - version_id
        - notebook_id
        - saved_at
        - author
        - message
        - parent_id
    SnapshotDescriptor:
      type: object
      properties:
        captured_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        size_bytes:
          type: number
      required:
        - captured_at
        - size_bytes
    GitSourceRevision:
      type: object
      properties:
        provider:
          type:
            - string
            - 'null'
          minLength: 1
          description: Detected provider id for this immutable source revision, or null
            when the repository host is unrecognized.
          example: github
        repo:
          type: string
          description: 'Normalized repository coordinate: owner/repo or an HTTPS
            repository URL.'
          example: marimo-team/marimohub
        branch:
          type: string
          description: Synced repository branch.
          example: main
        root_path:
          type: string
          description: Repository-relative directory synced into the notebook workspace.
          example: apps
        entry_notebook:
          type: string
          description: Path to the entry notebook relative to root_path.
          example: dashboard.py
        commit:
          type: string
          description: Immutable Git commit from which the saved version was synced.
          example: 9e107d9d372bb6826bd81d3542a419d6
      required:
        - provider
        - repo
        - branch
        - root_path
        - entry_notebook
        - commit
    OpenNotebookChangeRequestResult:
      type: object
      properties:
        proposal_id:
          type: string
          pattern: ^prop-[0-9a-z]{16}$
          description: Identifier of the immutable proposal captured from the notebook
            session and published by this change request.
          example: prop-7h2k9qm4xz7rp3w8
        change_request:
          type: object
          properties:
            provider:
              type: string
              minLength: 1
              example: github
            number:
              type: integer
              exclusiveMinimum: 0
              example: 42
            url:
              type: string
              format: uri
              example: https://github.com/acme/analytics/pull/42
            head_branch:
              type: string
              minLength: 1
              example: marimohub/nb-7h2k9qm4xz7rp3w8/prop-7h2k9qm4xz7rp3w8
            head_commit:
              type: string
              minLength: 1
              example: 9e107d9d372bb6826bd81d3542a419d6
          required:
            - provider
            - number
            - url
            - head_branch
            - head_commit
      required:
        - proposal_id
        - change_request
    OpenNotebookChangeRequestBody:
      type: object
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 256
          description: Change request title. Defaults to the notebook title.
          example: Update revenue dashboard
        body:
          type: string
          maxLength: 65536
          description: Change request description. Defaults to the session and base commit.
          example: Updates the regional revenue analysis.
        target_proposal_id:
          type: string
          pattern: ^prop-[0-9a-z]{16}$
          description: Published proposal whose existing change request should receive
            this new proposal. Omit to create a new change request.
          example: prop-7h2k9qm4xz7rp3w8
    SessionPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Session'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    Session:
      type: object
      properties:
        session_id:
          type: string
        notebook_id:
          type: string
        project_id:
          type: string
        user_id:
          type: string
        status:
          type: string
          enum:
            - starting
            - running
            - terminating
            - terminated
            - failed
            - expired
        sandbox_url:
          type: string
        started_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        last_heartbeat:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        ephemeral:
          type: boolean
        editor_sandbox_sharing:
          type: string
          enum:
            - shared
            - exclusive
        ended_reason:
          type: string
          enum:
            - takeover
        ended_by_user_id:
          type: string
        mode:
          type: string
          enum:
            - edit
            - app
        source_version_id:
          type: string
        can:
          type: object
          properties:
            attach:
              type: boolean
            stop:
              type: boolean
            surfaces:
              type: object
              properties:
                vscode:
                  type: boolean
                opencode:
                  type: boolean
              required:
                - vscode
                - opencode
          required:
            - attach
            - stop
        surfaces:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Surface'
        active_connections:
          type: number
        connections_checked_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        compute_profile:
          type: string
        compute_resources:
          $ref: '#/components/schemas/ComputeResources'
        compute_from_snapshot:
          type: boolean
        integrations:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              name:
                type: string
              kind:
                type: string
              version:
                type: integer
            required:
              - id
              - name
              - kind
              - version
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
          required:
            - code
            - message
      required:
        - session_id
        - notebook_id
        - project_id
        - user_id
        - status
        - started_at
        - last_heartbeat
        - mode
        - can
    Surface:
      type: object
      properties:
        status:
          type: string
          enum:
            - starting
            - ready
            - stopping
            - stopped
            - failed
            - unavailable
        port:
          type: integer
          exclusiveMinimum: 0
        url:
          type: string
        started_at:
          type: string
          format: date-time
          example: 2025-03-05T14:00:00Z
        probe:
          type: object
          properties:
            available:
              type: boolean
            reason:
              type: string
            version:
              type: string
          required:
            - available
        last_error:
          type: string
      required:
        - status
    EditorSessionState:
      type: object
      properties:
        sharing:
          type: string
          enum:
            - shared
            - exclusive
        holder:
          type:
            - object
            - 'null'
          properties:
            session_id:
              type: string
            user_id:
              type: string
            status:
              type: string
              enum:
                - starting
                - running
                - terminating
            started_at:
              type: string
            activity:
              type: object
              properties:
                state:
                  type: string
                  enum:
                    - active
                    - idle
                    - unknown
                    - starting
                active_connections:
                  type: number
                checked_at:
                  type: string
              required:
                - state
          required:
            - session_id
            - user_id
            - status
            - started_at
            - activity
        can_take_over:
          type: boolean
        transfer:
          type: object
          properties:
            status:
              type: string
              enum:
                - requested
                - draining
                - ready
          required:
            - status
      required:
        - sharing
        - holder
        - can_take_over
    EditorTakeoverBody:
      type: object
      properties:
        takeover_id:
          type: string
          minLength: 1
          maxLength: 255
        expected_holder_session_id:
          type: string
        expected_activity:
          type: string
          enum:
            - active
            - idle
            - unknown
            - starting
        acknowledge_disruption:
          type: boolean
          enum:
            - true
      required:
        - takeover_id
        - expected_holder_session_id
        - expected_activity
        - acknowledge_disruption
    SessionCreateResult:
      allOf:
        - $ref: '#/components/schemas/Session'
        - type: object
          properties:
            reused:
              type: boolean
            editor_session:
              type: object
              properties:
                sharing:
                  type: string
                  enum:
                    - shared
                    - exclusive
                access:
                  type: string
                  enum:
                    - shared
                    - owner
                    - temporary
              required:
                - sharing
                - access
          required:
            - reused
    SessionCreateBody:
      type: object
      properties:
        mode:
          type: string
          enum:
            - edit
            - app
        compute_profile:
          type: string
          enum:
            - default
        edit_intent:
          type: string
          enum:
            - temporary
        surfaces:
          type: array
          items:
            type: string
            enum:
              - vscode
              - opencode
          maxItems: 2
      additionalProperties: false
    SurfaceStartBody:
      type: object
      properties:
        open:
          type: string
          maxLength: 4096
          description: Workspace-relative file to open. Supported only by the VS Code
            surface.
    JobPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Job'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    Job:
      type: object
      properties:
        id:
          type: string
          pattern: ^job-[0-9a-z]{16}$
        notebook_id:
          type: string
        project_id:
          type: string
        name:
          type: string
        enabled:
          type: boolean
        schedule:
          $ref: '#/components/schemas/JobSchedule'
        parameters:
          $ref: '#/components/schemas/JobParameters'
        retry:
          $ref: '#/components/schemas/JobRetryPolicy'
        timeout_seconds:
          type: integer
        concurrency_policy:
          type: string
          enum:
            - forbid
            - allow
            - unknown
          description: 'Known values: forbid, allow. Unrecognized values normalize to
            unknown.'
          example: forbid
        notifications:
          $ref: '#/components/schemas/JobNotifications'
        created_by:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - notebook_id
        - project_id
        - name
        - enabled
        - concurrency_policy
        - created_by
        - created_at
        - updated_at
    JobSchedule:
      type: object
      properties:
        cron:
          type: string
          minLength: 1
          maxLength: 100
          description: Five-field cron expression (minute hour day-of-month month
            day-of-week).
          example: 0 6 * * 1-5
        timezone:
          type: string
          minLength: 1
          maxLength: 64
          description: IANA time zone the cron fields are evaluated in.
          example: Europe/Berlin
      required:
        - cron
        - timezone
    JobParameters:
      type: object
      additionalProperties:
        type: string
        maxLength: 4096
      maxProperties: 32
      propertyNames: &a2
        type: string
        pattern: ^[A-Za-z][A-Za-z0-9_-]{0,63}$
      description: String parameters passed to the notebook as `--key value` after
        `--`, readable via `mo.cli_args()`. Parameters are visible to every
        project member who can read the job or its run history; do not store
        secrets here.
      example:
        region: eu-west-1
    JobRetryPolicy:
      type: object
      properties:
        max_retries:
          type: integer
          minimum: 0
          maximum: 5
        backoff_seconds:
          type: integer
          minimum: 0
          maximum: 3600
          default: 60
      required:
        - max_retries
    JobNotifications:
      type: object
      properties:
        on:
          type: array
          items:
            type: string
            enum:
              - failure
              - success
          minItems: 1
      required:
        - on
      description: Deliver `job.run.failed` / `job.run.succeeded` project alerts for
        this job. Failures notify once retries are exhausted.
    JobCreateBody:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 120
          example: Nightly refresh
        enabled:
          type: boolean
          default: true
        schedule:
          $ref: '#/components/schemas/JobSchedule'
        parameters:
          $ref: '#/components/schemas/JobParameters'
        retry:
          $ref: '#/components/schemas/JobRetryPolicy'
        timeout_seconds:
          type: integer
          minimum: 60
          description: Run deadline in seconds; capped by
            MARIMOHUB_JOBS_MAX_TIMEOUT_SECONDS.
          example: 1800
        concurrency_policy:
          type: string
          enum:
            - forbid
            - allow
          default: forbid
        notifications:
          $ref: '#/components/schemas/JobNotifications'
      required:
        - name
      additionalProperties: false
    JobUpdateBody:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 120
        enabled:
          type: boolean
        schedule:
          type:
            - object
            - 'null'
          properties:
            cron:
              type: string
              minLength: 1
              maxLength: 100
              description: Five-field cron expression (minute hour day-of-month month
                day-of-week).
              example: 0 6 * * 1-5
            timezone:
              type: string
              minLength: 1
              maxLength: 64
              description: IANA time zone the cron fields are evaluated in.
              example: Europe/Berlin
          required:
            - cron
            - timezone
        parameters:
          type:
            - object
            - 'null'
          additionalProperties:
            type: string
            maxLength: 4096
          maxProperties: 32
          propertyNames: *a2
        retry:
          type:
            - object
            - 'null'
          properties:
            max_retries:
              type: integer
              minimum: 0
              maximum: 5
            backoff_seconds:
              type: integer
              minimum: 0
              maximum: 3600
              default: 60
          required:
            - max_retries
        timeout_seconds:
          type:
            - integer
            - 'null'
          minimum: 60
          description: Run deadline in seconds; capped by
            MARIMOHUB_JOBS_MAX_TIMEOUT_SECONDS.
          example: 1800
        concurrency_policy:
          type: string
          enum:
            - forbid
            - allow
        notifications:
          type:
            - object
            - 'null'
          properties:
            on:
              type: array
              items:
                type: string
                enum:
                  - failure
                  - success
              minItems: 1
          required:
            - on
      additionalProperties: false
    JobRun:
      type: object
      properties:
        run_id:
          type: string
          pattern: ^run_[0-9A-HJKMNP-TV-Z]{26}$
        job_id:
          type: string
        notebook_id:
          type: string
        project_id:
          type: string
        status:
          type: string
          enum:
            - queued
            - provisioning
            - running
            - succeeded
            - failed
            - timed_out
            - cancelled
            - skipped
            - unknown
          description: queued/provisioning/running are active.
            succeeded/failed/timed_out/cancelled/skipped are terminal; terminal
            records are never rewritten.
          example: queued
        trigger:
          type: string
          enum:
            - schedule
            - manual
            - unknown
          description: 'Known values: schedule, manual. Unrecognized values normalize to
            unknown.'
          example: manual
        triggered_by:
          type: string
        scheduled_for:
          type: string
          format: date-time
        source_version_id:
          type: string
        parameters:
          $ref: '#/components/schemas/JobParameters'
        attempt:
          type: integer
          exclusiveMinimum: 0
          description: One-based attempt number. A failed or timed-out attempt can create
            a new run with attempt + 1 and retry_of set, subject to the job
            retry policy.
        retry_of:
          type: string
        image:
          type: string
        compute_profile:
          type: string
        compute_resources:
          $ref: '#/components/schemas/ComputeResources'
        timeout_seconds:
          type: integer
        queued_at:
          type: string
          format: date-time
        eligible_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
          description: Present after the run enters running.
        finished_at:
          type: string
          format: date-time
          description: Present on terminal runs.
        deadline_at:
          type: string
          format: date-time
          description: Present after provisioning establishes the watchdog deadline.
        exit_code:
          type: integer
          description: Process exit code when the export command reported one.
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
          required:
            - code
            - message
          description: Sanitized failure detail, present on failed, timed-out, or skipped
            runs.
        output:
          type: object
          properties:
            html_bytes:
              type: integer
              minimum: 0
            logs_bytes:
              type: integer
              minimum: 0
          required:
            - html_bytes
          description: Captured write-once artifacts, present after execution.
        cancelled_by:
          type: string
      required:
        - run_id
        - job_id
        - notebook_id
        - project_id
        - status
        - trigger
        - attempt
        - timeout_seconds
        - queued_at
    JobRunTriggerBody:
      type: object
      properties:
        parameters:
          $ref: '#/components/schemas/JobParameters'
      additionalProperties: false
    JobRunPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/JobRun'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    IntegrationKind:
      type: object
      properties:
        kind:
          type: string
          minLength: 1
          example: postgres
        title:
          type: string
        description:
          type: string
        category:
          type: string
          enum:
            - database
            - catalog
            - engine
            - storage
            - other
        brand:
          type: object
          properties:
            icon:
              type: string
              minLength: 1
              example: postgresql
            color:
              type: string
              pattern: ^#[0-9A-Fa-f]{6}$
              example: '#4169E1'
          required:
            - color
        schema_version:
          type: integer
          exclusiveMinimum: 0
        json_schema:
          type: object
          additionalProperties: {}
        ui_hints:
          type: object
          additionalProperties:
            type: object
            properties:
              widget:
                type: string
                enum:
                  - text
                  - password
                  - textarea
                  - select
                  - toggle
                  - number
                  - kv-pairs
              placeholder:
                type: string
              group:
                type: string
              order:
                type: number
              advanced:
                type: boolean
              docs_url:
                type: string
        supports_test:
          type: boolean
        supports_browse:
          type: boolean
        browse_surfaces:
          type: array
          items:
            type: string
            enum:
              - tables
              - objects
              - unknown
            description: 'Known values: tables, objects. Unrecognized values normalize to
              unknown.'
            example: tables
        secret_sources:
          type: object
          properties:
            inline:
              type: boolean
            references:
              type: array
              items:
                type: object
                properties:
                  backend:
                    type: string
                    minLength: 1
                    example: aws-sm
                  title:
                    type: string
                    minLength: 1
                    example: AWS Secrets Manager
                  locator_placeholder:
                    type: string
                    minLength: 1
                  locator_help:
                    type: string
                    minLength: 1
                  docs_url:
                    type: string
                    format: uri
                required:
                  - backend
                  - title
                  - locator_placeholder
                  - locator_help
          required:
            - inline
            - references
        requirements:
          type: array
          items:
            type: string
      required:
        - kind
        - title
        - description
        - category
        - brand
        - schema_version
        - json_schema
        - ui_hints
        - supports_test
        - supports_browse
        - browse_surfaces
        - secret_sources
        - requirements
    IntegrationPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/IntegrationEntry'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    IntegrationEntry:
      type: object
      properties:
        id:
          type: string
          pattern: ^intg-[0-9a-z]{16}$
        kind:
          type: string
          minLength: 1
        name:
          type: string
          pattern: ^[a-z][a-z0-9-]{0,31}$
        enabled:
          type: boolean
        current_version:
          type: integer
          exclusiveMinimum: 0
        created_by:
          type: string
          minLength: 1
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        scope:
          type: string
          enum:
            - project
            - org
        shadowed:
          type: boolean
      required:
        - id
        - kind
        - name
        - enabled
        - current_version
        - created_by
        - created_at
        - updated_at
        - scope
    IntegrationDetail:
      allOf:
        - $ref: '#/components/schemas/IntegrationEntry'
        - type: object
          properties:
            config:
              type: object
              additionalProperties: {}
            change_note:
              type: string
          required:
            - config
    IntegrationVersionPage:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/IntegrationVersion'
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    IntegrationVersion:
      type: object
      properties:
        version:
          type: integer
          exclusiveMinimum: 0
        kind_schema_version:
          type: integer
          exclusiveMinimum: 0
        created_by:
          type: string
          minLength: 1
        created_at:
          type: string
          format: date-time
        change_note:
          type: string
      required:
        - version
        - kind_schema_version
        - created_by
        - created_at
    IntegrationCopyRequest:
      type: object
      properties:
        source_project_id:
          type: string
          pattern: ^proj-[0-9a-z]{16}$
          example: proj-7h2k9qm4xz7rp3w8
        source_integration_id:
          type: string
          pattern: ^intg-[0-9a-z]{16}$
          example: intg-7h2k9qm4xz7rp3w8
        name:
          type: string
          pattern: ^[a-z][a-z0-9-]{0,31}$
      required:
        - source_project_id
        - source_integration_id
      additionalProperties: false
    IntegrationTestResult:
      type: object
      properties:
        ok:
          type: boolean
        latency_ms:
          type: number
          minimum: 0
        details:
          type: string
      required:
        - ok
    IntegrationTestRequest:
      oneOf:
        - type: object
          properties:
            source:
              type: string
              enum:
                - draft
            kind:
              type: string
              minLength: 1
            config:
              type: object
              additionalProperties: {}
            id:
              type: string
              pattern: ^intg-[0-9a-z]{16}$
          required:
            - source
            - kind
            - config
          additionalProperties: false
        - type: object
          properties:
            source:
              type: string
              enum:
                - stored
            id:
              type: string
              pattern: ^intg-[0-9a-z]{16}$
          required:
            - source
            - id
          additionalProperties: false
    IntegrationQueryReadinessCheck:
      type: object
      properties:
        id:
          type: string
          minLength: 1
        label:
          type: string
          minLength: 1
        ready:
          type: boolean
        field:
          type: string
        reason:
          type: string
          minLength: 1
      required:
        - id
        - label
        - ready
        - field
        - reason
    IntegrationQueryReadinessRequest:
      type: object
      properties:
        kind:
          type: string
          minLength: 1
        config:
          type: object
          additionalProperties: {}
      required:
        - kind
        - config
      additionalProperties: false
    IntegrationBrowseCapability:
      type: object
      properties:
        surfaces:
          type: object
          properties:
            tables:
              type: object
              properties:
                available:
                  type: boolean
                preview:
                  type: boolean
                reason:
                  type: string
              required:
                - available
                - preview
            objects:
              type: object
              properties:
                provider:
                  type: string
                  enum:
                    - s3
                    - gcs
                    - azure_blob
                    - unknown
                  description: 'Known values: s3, gcs, azure_blob. Unrecognized values normalize
                    to unknown.'
                  example: s3
                root_kind:
                  type: string
                  enum:
                    - bucket
                    - container
                    - unknown
                  description: 'Known values: bucket, container. Unrecognized values normalize to
                    unknown.'
                  example: bucket
                uri_scheme:
                  type: string
                  enum:
                    - s3
                    - gs
                    - az
                    - unknown
                  description: 'Known values: s3, gs, az. Unrecognized values normalize to
                    unknown.'
                  example: s3
                available:
                  type: boolean
                preview:
                  type: boolean
                download:
                  type: boolean
                search:
                  type: string
                  enum:
                    - none
                    - bounded-key-name
                    - unknown
                  description: 'Known values: none, bounded-key-name. Unrecognized values
                    normalize to unknown.'
                  example: bounded-key-name
                versions:
                  type: boolean
                preview_formats:
                  type: array
                  items:
                    type: string
                reason:
                  type: string
              required:
                - provider
                - root_kind
                - uri_scheme
                - available
                - preview
                - download
                - search
                - versions
                - preview_formats
            query:
              type: object
              properties:
                available:
                  type: boolean
                dialect:
                  type: string
                  enum:
                    - duckdb
                    - postgresql
                    - unknown
                  description: 'Known values: duckdb, postgresql. Unrecognized values normalize to
                    unknown.'
                  example: duckdb
                reason:
                  type: string
              required:
                - available
                - dialect
      required:
        - surfaces
    IntegrationBrowseNamespacePage:
      type: object
      properties:
        items:
          type: array
          items:
            type: array
            items:
              type: string
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    IntegrationBrowseTablePage:
      type: object
      properties:
        items:
          type: array
          items:
            type: string
        next_cursor:
          type:
            - string
            - 'null'
      required:
        - items
        - next_cursor
    IntegrationTableSchema:
      type: object
      properties:
        columns:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              type:
                type: string
              nullable:
                type: boolean
              comment:
                type: string
            required:
              - name
              - type
              - nullable
        partitioning:
          type: array
          items:
            type: string
        snippet:
          type: string
        location:
          type: string
        format_version:
          type: integer
        current_snapshot:
          type: object
          properties:
            committed_at:
              type: string
              format: date-time
            total_records:
              type: number
            total_data_size_bytes:
              type: number
      required:
        - columns
    IntegrationTablePreview:
      type: object
      properties:
        columns:
          type: array
          items:
            type: string
        rows:
          type: array
          items:
            type: array
            items: {}
      required:
        - columns
        - rows
    IntegrationDataQueryResult:
      type: object
      properties:
        columns:
          type: array
          items:
            type: string
        rows:
          type: array
          items:
            type: array
            items: {}
        truncated:
          type: boolean
        execution_ms:
          type: integer
          minimum: 0
      required:
        - columns
        - rows
        - truncated
        - execution_ms
    IntegrationQuerySchema:
      type: object
      properties:
        tables:
          type: array
          items:
            type: object
            properties:
              namespace:
                type: array
                items:
                  type: string
              name:
                type: string
              columns:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                    type:
                      type: string
                    nullable:
                      type: boolean
                  required:
                    - name
                    - type
                    - nullable
            required:
              - namespace
              - name
              - columns
        truncated:
          type: object
          properties:
            tables:
              type: boolean
            columns:
              type: boolean
            bytes:
              type: boolean
          required:
            - tables
            - columns
            - bytes
        counts:
          type: object
          properties:
            tables:
              type: integer
              minimum: 0
            discovered_tables:
              type: integer
              minimum: 0
            columns:
              type: integer
              minimum: 0
            discovery_complete:
              type: boolean
          required:
            - tables
            - discovered_tables
            - columns
            - discovery_complete
      required:
        - tables
        - truncated
        - counts
    IntegrationObjectBucket:
      type: object
      properties:
        name:
          type: string
        created_at:
          type: string
          format: date-time
        configured:
          type: boolean
      required:
        - name
        - configured
    IntegrationObjectEntry:
      type: object
      properties:
        kind:
          type: string
          enum:
            - prefix
            - object
        name:
          type: string
        key:
          type: string
        size:
          type: number
          minimum: 0
        last_modified:
          type: string
          format: date-time
        etag:
          type: string
        storage_class:
          type: string
      required:
        - kind
        - name
        - key
    IntegrationObjectDetail:
      type: object
      properties:
        bucket:
          type: string
        key:
          type: string
        version_id:
          type: string
        size:
          type: number
          minimum: 0
        last_modified:
          type: string
          format: date-time
        etag:
          type: string
        storage_class:
          type: string
        content_type:
          type: string
        content_encoding:
          type: string
        cache_control:
          type: string
        checksums:
          type: array
          items:
            type: object
            properties:
              algorithm:
                type: string
              value:
                type: string
            required:
              - algorithm
              - value
        metadata:
          type: object
          additionalProperties:
            type: string
        tags:
          type: array
          items:
            type: object
            properties:
              key:
                type: string
              value:
                type: string
            required:
              - key
              - value
        tags_available:
          type: boolean
        snippet:
          type: string
      required:
        - bucket
        - key
        - size
        - checksums
        - metadata
        - tags_available
    IntegrationObjectVersion:
      type: object
      properties:
        bucket:
          type: string
        key:
          type: string
        version_id:
          type: string
        kind:
          type: string
          enum:
            - version
            - delete-marker
        is_latest:
          type: boolean
        last_modified:
          type: string
          format: date-time
        size:
          type: number
          minimum: 0
        etag:
          type: string
        storage_class:
          type: string
        owner:
          type: object
          properties:
            id:
              type: string
            display_name:
              type: string
      required:
        - bucket
        - key
        - kind
        - is_latest
    IntegrationObjectPreview:
      oneOf:
        - type: object
          properties:
            kind:
              type: string
              enum:
                - tabular
            format:
              type: string
              enum:
                - table
                - csv
                - tsv
                - json
                - jsonl
                - parquet
                - unknown
              description: 'Known values: table, csv, tsv, json, jsonl, parquet. Unrecognized
                values normalize to unknown.'
              example: csv
            columns:
              type: array
              items:
                type: object
                properties:
                  name:
                    type: string
                  type:
                    type: string
                required:
                  - name
            rows:
              type: array
              items:
                type: array
                items: {}
            truncated:
              type: boolean
            bytes_read:
              type: number
              minimum: 0
            total_bytes:
              type: number
              minimum: 0
            warnings:
              type: array
              items:
                type: string
          required:
            - kind
            - format
            - columns
            - rows
            - truncated
            - warnings
        - type: object
          properties:
            kind:
              type: string
              enum:
                - text
            format:
              type: string
              enum:
                - text
                - markdown
                - code
                - log
                - json
                - unknown
              description: 'Known values: text, markdown, code, log, json. Unrecognized values
                normalize to unknown.'
              example: text
            text:
              type: string
            truncated:
              type: boolean
            bytes_read:
              type: number
              minimum: 0
            total_bytes:
              type: number
              minimum: 0
            warnings:
              type: array
              items:
                type: string
          required:
            - kind
            - format
            - text
            - truncated
            - bytes_read
            - total_bytes
            - warnings
        - type: object
          properties:
            kind:
              type: string
              enum:
                - image
            format:
              type: string
              enum:
                - png
                - jpeg
                - gif
                - webp
                - unknown
              description: 'Known values: png, jpeg, gif, webp. Unrecognized values normalize
                to unknown.'
              example: png
            content_url:
              type: string
            width:
              type: integer
              exclusiveMinimum: 0
            height:
              type: integer
              exclusiveMinimum: 0
            total_bytes:
              type: number
              minimum: 0
            warnings:
              type: array
              items:
                type: string
          required:
            - kind
            - format
            - content_url
            - total_bytes
            - warnings
        - type: object
          properties:
            kind:
              type: string
              enum:
                - unsupported
            reason:
              type: string
            detected_type:
              type: string
            total_bytes:
              type: number
              minimum: 0
          required:
            - kind
            - reason
            - total_bytes
    User:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
        name:
          type: string
        picture_url:
          type:
            - string
            - 'null'
          format: uri
      required:
        - id
        - email
        - name
    ApiTokenCreated:
      allOf:
        - $ref: '#/components/schemas/ApiToken'
        - type: object
          properties:
            token:
              type: string
          required:
            - token
    ApiToken:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
        last_used_at:
          type: string
          format: date-time
        grant:
          type: object
          properties:
            actions:
              anyOf:
                - type: string
                  enum:
                    - '*'
                - type: array
                  items:
                    type: string
                    enum:
                      - project.create
                      - admin.access
                      - org-integration.manage
                      - audit.global.read
                      - directory.search
                      - project.read
                      - project.update
                      - project.delete
                      - project.members.manage
                      - project.events.read
                      - project.alerts.manage
                      - notebook.write
                      - notebook.manage
                      - integration.read
                      - integration.use
                      - integration.manage
                      - change-request.publish
                      - security-labels.raise
                      - security-labels.lower
                      - session.attach
                      - session.stop
                      - session.surface
                      - session.proxy
                      - session.start
                  uniqueItems: true
            projects:
              anyOf:
                - type: string
                  enum:
                    - '*'
                - type: array
                  items:
                    type: string
                    pattern: ^proj-[0-9a-z]{16}$
                  minItems: 1
                  maxItems: 100
                  uniqueItems: true
          required:
            - actions
            - projects
          additionalProperties: false
      required:
        - id
        - name
        - created_at
  parameters: {}
paths:
  /api/cli/v1/device-authorizations:
    post:
      operationId: auth.cli.device.request
      x-cli-hidden: true
      tags:
        - Auth
      summary: Start a CLI device login
      description: Returns a high-entropy device code that is bound to the PKCE
        challenge. Also returns a short code for browser approval.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code_challenge:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{43}$
                  description: Base64url-encoded SHA-256 PKCE challenge generated by the CLI.
              required:
                - code_challenge
              additionalProperties: false
      responses:
        '200':
          description: Device and user verification codes
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      device_code:
                        type: string
                      user_code:
                        type: string
                      verification_uri:
                        type: string
                        format: uri
                      verification_uri_complete:
                        type: string
                        format: uri
                      expires_in:
                        type: integer
                      interval:
                        type: integer
                    required:
                      - device_code
                      - user_code
                      - verification_uri
                      - verification_uri_complete
                      - expires_in
                      - interval
                required:
                  - success
                  - data
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/cli/v1/device-authorizations/scoped:
    post:
      operationId: auth.cli.device.requestScoped
      x-cli-hidden: true
      tags:
        - Auth
      summary: Start a scoped CLI device login
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code_challenge:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{43}$
                  description: Base64url-encoded SHA-256 PKCE challenge generated by the CLI.
                grant:
                  type: object
                  properties:
                    actions:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            enum:
                              - project.create
                              - admin.access
                              - org-integration.manage
                              - audit.global.read
                              - directory.search
                              - project.read
                              - project.update
                              - project.delete
                              - project.members.manage
                              - project.events.read
                              - project.alerts.manage
                              - notebook.write
                              - notebook.manage
                              - integration.read
                              - integration.use
                              - integration.manage
                              - change-request.publish
                              - security-labels.raise
                              - security-labels.lower
                              - session.attach
                              - session.stop
                              - session.surface
                              - session.proxy
                              - session.start
                          uniqueItems: true
                    projects:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            pattern: ^proj-[0-9a-z]{16}$
                          minItems: 1
                          maxItems: 100
                          uniqueItems: true
                  required:
                    - actions
                    - projects
                  additionalProperties: false
              required:
                - code_challenge
                - grant
              additionalProperties: false
      responses:
        '200':
          description: Device and user verification codes
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      device_code:
                        type: string
                      user_code:
                        type: string
                      verification_uri:
                        type: string
                        format: uri
                      verification_uri_complete:
                        type: string
                        format: uri
                      expires_in:
                        type: integer
                      interval:
                        type: integer
                    required:
                      - device_code
                      - user_code
                      - verification_uri
                      - verification_uri_complete
                      - expires_in
                      - interval
                required:
                  - success
                  - data
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/cli/v1/device-token:
    post:
      operationId: auth.cli.device.poll
      x-cli-hidden: true
      tags:
        - Auth
      summary: Poll a CLI device login
      description: Returns 202 while browser approval is pending. Returns a new
        personal access token once after approval.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                device_code:
                  type: string
                  minLength: 1
                  maxLength: 100
                code_verifier:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{43,128}$
              required:
                - device_code
                - code_verifier
              additionalProperties: false
      responses:
        '200':
          description: The new personal access token
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      token:
                        type: string
                    required:
                      - token
                required:
                  - success
                  - data
        '202':
          description: Browser approval is still pending
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - authorization_pending
                    required:
                      - status
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/cli/v1/token:
    post:
      operationId: auth.cli.exchange
      x-cli-hidden: true
      tags:
        - Auth
      summary: Exchange a CLI authorization code
      description: Public PKCE exchange for loopback login. The code is short-lived
        and single-use. Exchange also requires the verifier held by the CLI.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  minLength: 1
                  maxLength: 100
                code_verifier:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{43,128}$
              required:
                - code
                - code_verifier
              additionalProperties: false
      responses:
        '200':
          description: The new personal access token
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      token:
                        type: string
                    required:
                      - token
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me:
    get:
      operationId: me
      tags:
        - Auth
      summary: Get current user info
      responses:
        '200':
          description: Current user information
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Me'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/version:
    get:
      operationId: version
      tags:
        - System
      summary: Get the deployment version
      description: Just the version string. The rest of the build/runtime identity
        (image, replica, backends, …) is super-admin material on `GET
        /api/v1/admin/config`.
      responses:
        '200':
          description: Deployment version information
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/DeploymentInfo'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/capabilities:
    get:
      operationId: capabilities
      tags:
        - System
      summary: Get deployment capability flags
      responses:
        '200':
          description: Deployment capability flags
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Capabilities'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects:
    get:
      operationId: projects.list
      tags:
        - Projects
      summary: List all projects
      description: When paging a filtered list, send the same filters with each cursor.
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            enum:
              - active
              - deleted
            description: Project status to match. Deleted projects are excluded when
              omitted.
            example: active
          required: false
          description: Project status to match. Deleted projects are excluded when omitted.
          name: status
          in: query
        - schema:
            type: string
            description: Exact tag to match.
            example: analytics
          required: false
          description: Exact tag to match.
          name: tag
          in: query
        - schema:
            type: string
            description: Case-insensitive substring to match against the name or title and
              description.
            example: revenue
          required: false
          description: Case-insensitive substring to match against the name or title and
            description.
          name: q
          in: query
      responses:
        '200':
          description: List of projects with notebook summaries, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/ProjectPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      operationId: projects.create
      tags:
        - Projects
      summary: Create a project
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: false
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  example: Data Science
                description:
                  type: string
                  example: Exploratory analysis notebooks
                tags:
                  type: array
                  items:
                    type: string
                  example:
                    - analytics
                federation:
                  $ref: '#/components/schemas/ProjectFederationInput'
              required:
                - name
                - description
      responses:
        '201':
          description: Project created
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Project'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}:
    get:
      operationId: projects.get
      tags:
        - Projects
      summary: Get a project
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      responses:
        '200':
          description: Project details
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Project'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      operationId: projects.update
      tags:
        - Projects
      summary: Update a project
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  example: ML Pipeline
                description:
                  type: string
                tags:
                  type: array
                  items:
                    type: string
                federation:
                  $ref: '#/components/schemas/ProjectFederationInput'
      responses:
        '200':
          description: Project updated
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Project'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: projects.delete
      tags:
        - Projects
      summary: Delete a project
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      responses:
        '200':
          description: Project deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/security-labels:
    put:
      operationId: projects.securityLabels.set
      tags:
        - Projects
      summary: Set project security labels
      description: Sets the project classification and required compartments. Requires
        super-admin standing — no project role grants label authority — and the
        deployment must have resource security configured. Labels only add
        restrictions on top of role checks.
      security: &a3
        - cookieAuth: []
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SecurityLabelsInput'
      responses:
        '200':
          description: Security labels updated
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Project'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: projects.securityLabels.clear
      tags:
        - Projects
      summary: Remove project security labels
      security: *a3
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      responses:
        '200':
          description: Security labels removed
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Project'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/members:
    get:
      operationId: projects.members.list
      tags:
        - Projects
      summary: List project members
      description: Pending email invites are visible only to project managers (plus
        the invitee themself); other callers see the id-keyed rows only.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      responses:
        '200':
          description: Project members
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProjectMember'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      operationId: projects.members.add
      tags:
        - Projects
      summary: Add a project member
      description: Add a member by user id or email. A known email resolves to its
        user id; an unknown email becomes a pending invite that grants access
        when that person first signs in.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_id:
                  type: string
                  minLength: 1
                  example: user_01HXY00000000000000000000
                email:
                  type: string
                  format: email
                  example: teammate@example.com
                role:
                  $ref: '#/components/schemas/AssignableRole'
              required:
                - role
      responses:
        '201':
          description: Member added
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Project'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/members/{uid}:
    put:
      operationId: projects.members.update
      tags:
        - Projects
      summary: Change a member's role
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            minLength: 1
            example: user_01HXY00000000000000000000
          required: true
          name: uid
          in: path
          description: The member's user id, or the (URL-encoded) email of a pending invite
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                role:
                  allOf:
                    - $ref: '#/components/schemas/AssignableRole'
                    - example: manager
              required:
                - role
      responses:
        '200':
          description: Member role updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Project'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: projects.members.remove
      tags:
        - Projects
      summary: Remove a project member
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            minLength: 1
            example: user_01HXY00000000000000000000
          required: true
          name: uid
          in: path
          description: The member's user id, or the (URL-encoded) email of a pending invite
      responses:
        '200':
          description: Member removed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/alert-destinations:
    get:
      operationId: alerts.destinations.list
      tags:
        - Alerts
      summary: List project alert destinations
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      responses:
        '200':
          description: Project alert destinations with secret material redacted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/ProjectAlertDestinationPage'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      operationId: alerts.destinations.create
      tags:
        - Alerts
      summary: Create a project alert destination
      description: New destinations subscribe to all 12 project alert kinds when kinds
        is omitted. They remain disabled until a successful test.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 100
                    kinds:
                      type: array
                      items:
                        type: string
                        enum:
                          - member.invited
                          - member.added
                          - member.role_changed
                          - member.removed
                          - session.takeover
                          - notebook.deleted
                          - project.deleted
                          - app.start_failed
                          - app.unavailable
                          - sync.failed
                          - job.run.failed
                          - job.run.succeeded
                      minItems: 1
                    type:
                      type: string
                      enum:
                        - slack
                    webhook_url:
                      type: string
                      format: uri
                  required:
                    - name
                    - type
                    - webhook_url
                  additionalProperties: false
                - type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 100
                    kinds:
                      type: array
                      items:
                        type: string
                        enum:
                          - member.invited
                          - member.added
                          - member.role_changed
                          - member.removed
                          - session.takeover
                          - notebook.deleted
                          - project.deleted
                          - app.start_failed
                          - app.unavailable
                          - sync.failed
                          - job.run.failed
                          - job.run.succeeded
                      minItems: 1
                    type:
                      type: string
                      enum:
                        - webhook
                    url:
                      type: string
                      format: uri
                    signing_secret:
                      type: string
                      minLength: 1
                  required:
                    - name
                    - type
                    - url
                    - signing_secret
                  additionalProperties: false
      responses:
        '201':
          description: Alert destination created
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/ProjectAlertDestination'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/alert-destinations/{aid}:
    patch:
      operationId: alerts.destinations.update
      tags:
        - Alerts
      summary: Update a project alert destination
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^alert-[0-9a-z]{16}$
            example: alert-7h2k9qm4xz7rp3w8
          required: true
          name: aid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 100
                    kinds:
                      type: array
                      items:
                        type: string
                        enum:
                          - member.invited
                          - member.added
                          - member.role_changed
                          - member.removed
                          - session.takeover
                          - notebook.deleted
                          - project.deleted
                          - app.start_failed
                          - app.unavailable
                          - sync.failed
                          - job.run.failed
                          - job.run.succeeded
                      minItems: 1
                    enabled:
                      type: boolean
                    type:
                      type: string
                      enum:
                        - slack
                    webhook_url:
                      type: string
                      format: uri
                  required:
                    - type
                  additionalProperties: false
                - type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 100
                    kinds:
                      type: array
                      items:
                        type: string
                        enum:
                          - member.invited
                          - member.added
                          - member.role_changed
                          - member.removed
                          - session.takeover
                          - notebook.deleted
                          - project.deleted
                          - app.start_failed
                          - app.unavailable
                          - sync.failed
                          - job.run.failed
                          - job.run.succeeded
                      minItems: 1
                    enabled:
                      type: boolean
                    type:
                      type: string
                      enum:
                        - webhook
                    url:
                      type: string
                      format: uri
                    signing_secret:
                      type: string
                      minLength: 1
                  required:
                    - type
                  additionalProperties: false
      responses:
        '200':
          description: Alert destination updated
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/ProjectAlertDestination'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: alerts.destinations.delete
      tags:
        - Alerts
      summary: Delete a project alert destination
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^alert-[0-9a-z]{16}$
            example: alert-7h2k9qm4xz7rp3w8
          required: true
          name: aid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      responses:
        '200':
          description: Alert destination deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/alert-destinations/{aid}/test:
    post:
      operationId: alerts.destinations.test
      tags:
        - Alerts
      summary: Send a test project alert
      description: Sends a real external message. A completed Idempotency-Key replays
        its result. A concurrent, failed, or uncertain delivery returns 409 on
        reuse. A pre-delivery rejection does not consume the key. Use a new key
        to start another test.
      x-cli-destructive: true
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^alert-[0-9a-z]{16}$
            example: alert-7h2k9qm4xz7rp3w8
          required: true
          name: aid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: true
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      responses:
        '200':
          description: Test delivered and destination verified
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/ProjectAlertDestination'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/events:
    get:
      operationId: audit.list
      tags:
        - Audit
      summary: List deployment audit events
      description: Deployment-wide audit trail, newest first. Super-admin only. Date
        ranges are inclusive and limited to 30 UTC days.
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
            example: 2026-07-01
            description: UTC calendar date
          required: false
          description: UTC calendar date
          name: from
          in: query
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
            example: 2026-07-01
            description: UTC calendar date
          required: false
          description: UTC calendar date
          name: to
          in: query
        - schema:
            type: string
            minLength: 1
          required: false
          name: event
          in: query
        - schema:
            type: string
            minLength: 1
          required: false
          name: actor
          in: query
        - schema:
            type: string
            minLength: 1
          required: false
          name: project_id
          in: query
      responses:
        '200':
          description: Deployment audit events, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/AuditLogPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/events:
    get:
      operationId: projects.audit.list
      tags:
        - Projects
      summary: List a project's audit events for one day
      description: 'Catalog mutation audit trail (project/notebook lifecycle,
        membership changes), one UTC day at a time. Manager-only: events may
        record member management and deletions.'
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
            example: 2026-07-01
            description: UTC day (defaults to today)
          required: false
          description: UTC day (defaults to today)
          name: date
          in: query
      responses:
        '200':
          description: The day's audit events for this project, in append order
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/AuditEvent'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/admin/users:
    get:
      operationId: admin.users.list
      tags:
        - Admin
      summary: List all users in the identity directory
      description: 'Every user who has signed in at least once, name-sorted. Currently
        a single page (`next_cursor` is always null). Super-admin only, and
        session-only: a PAT — even a super admin’s — is rejected with 403.'
      security: *a3
      responses:
        '200':
          description: The user directory, name-sorted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/AdminUserPage'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/admin/users/{id}/suspension:
    put:
      operationId: admin.users.suspend
      x-cli-destructive: true
      tags:
        - Users
        - Admin
      summary: Suspend a user
      description: Blocks the user at authentication time, including personal access
        tokens. Super-admin only and session-only. A super admin cannot suspend
        their own account.
      security: *a3
      parameters:
        - schema:
            type: string
            minLength: 1
            example: user_01HXY00000000000000000000
          required: true
          name: id
          in: path
          description: The user's identity-provider subject id
      responses:
        '200':
          description: The suspended user
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/AdminUser'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: admin.users.unsuspend
      tags:
        - Users
        - Admin
      summary: Reactivate a suspended user
      description: Restores authentication for a known user. Super-admin only and
        session-only.
      security: *a3
      parameters:
        - schema:
            type: string
            minLength: 1
            example: user_01HXY00000000000000000000
          required: true
          name: id
          in: path
          description: The user's identity-provider subject id
      responses:
        '200':
          description: The reactivated user
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/AdminUser'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/admin/debug/sandbox-startup:
    post:
      operationId: admin.debug.sandboxStartup
      x-cli-hidden: true
      tags:
        - Admin
      summary: Measure sandbox startup and command latency
      description: Creates a fresh ephemeral sandbox, uses the first fixed echo
        command as the readiness probe, and measures a second fixed echo
        command. An optional fresh-sandbox uv benchmark also records runtime and
        CPU limits, files.pythonhosted.org throughput, uv phase timings, and CPU
        throttling counters. The sandbox is always destroyed. Runtime failures
        are returned as a partial report. Super-admin only and session-only.
      security: *a3
      requestBody:
        required: false
        description: Optional; omit to use the deployment defaults.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SandboxStartupRequest'
      responses:
        '200':
          description: The sandbox startup diagnostic report
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/SandboxStartupReport'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/admin/config:
    get:
      operationId: admin.config.get
      tags:
        - Admin
      summary: Describe the deployment's configuration
      description: Read-only view of every configuration group (storage, compute,
        auth, …) as resolved from the serving replica's environment at boot;
        secret values are never included, only whether they are set. Super-admin
        only, session-only.
      security: *a3
      responses:
        '200':
          description: The deployment configuration, secrets redacted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/DeploymentConfig'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/admin/policy-analyzer/metadata:
    get:
      operationId: admin.policyAnalyzer.metadata
      tags:
        - Admin
      summary: Describe policy analyzer inputs
      security: *a3
      responses:
        '200':
          description: Policy analyzer metadata
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/PolicyAnalyzerMetadata'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/admin/policy-analyzer/evaluate:
    post:
      operationId: admin.policyAnalyzer.evaluate
      x-cli-hidden: true
      tags:
        - Admin
      summary: Evaluate a policy test suite
      security: *a3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PolicySuiteV1'
      responses:
        '200':
          description: Policy analysis results
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/PolicySuiteResult'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/workspace/files:
    get:
      operationId: notebooks.workspace.files.read
      x-cli-hidden: true
      tags:
        - Notebooks
      summary: Read raw workspace file content
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            minLength: 1
          required: true
          name: path
          in: query
      responses:
        '200':
          description: Raw workspace file bytes
          content:
            '*/*':
              schema:
                type: string
                format: binary
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    put:
      operationId: notebooks.workspace.files.write
      x-cli-hidden: true
      tags:
        - Notebooks
      summary: Create or overwrite a workspace file
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            minLength: 1
          required: true
          name: path
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
          required: false
          name: create
          in: query
      requestBody:
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
      responses:
        '200':
          description: Workspace file saved
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/WorkspaceItem'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/workspace/access:
    get:
      operationId: notebooks.workspace.access
      tags:
        - Notebooks
      summary: Get workspace file capabilities
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: Workspace access policy
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/WorkspaceAccess'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/workspace/entries:
    get:
      operationId: notebooks.workspace.list
      tags:
        - Notebooks
      summary: List a workspace directory
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            default: /
          required: false
          name: path
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 500
          required: false
          name: limit
          in: query
      responses:
        '200':
          description: Workspace entries
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/WorkspaceItem'
                      cursor:
                        type: string
                    required:
                      - items
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: notebooks.workspace.delete
      x-cli-destructive: true
      tags:
        - Notebooks
      summary: Delete a workspace entry
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            minLength: 1
          required: true
          name: path
          in: query
      responses:
        '200':
          description: Workspace entry deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/workspace/search:
    get:
      operationId: notebooks.workspace.search
      tags:
        - Notebooks
      summary: Search workspace paths
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            default: /
          required: false
          name: path
          in: query
        - schema:
            type: string
            minLength: 1
          required: true
          name: query
          in: query
      responses:
        '200':
          description: Workspace search results
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/WorkspaceItem'
                    required:
                      - items
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/workspace/directories:
    post:
      operationId: notebooks.workspace.directories.create
      tags:
        - Notebooks
      summary: Create a workspace directory
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                path:
                  type: string
                  minLength: 1
              required:
                - path
      responses:
        '201':
          description: Workspace directory created
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/WorkspaceItem'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/workspace/move:
    post:
      operationId: notebooks.workspace.move
      x-cli-destructive: true
      tags:
        - Notebooks
      summary: Move a workspace entry
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                from:
                  type: string
                  minLength: 1
                to:
                  type: string
                  minLength: 1
              required:
                - from
                - to
      responses:
        '200':
          description: Workspace entry moved
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/WorkspaceItem'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/workspace/copy:
    post:
      operationId: notebooks.workspace.copy
      tags:
        - Notebooks
      summary: Copy a workspace entry
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                from:
                  type: string
                  minLength: 1
                to:
                  type: string
                  minLength: 1
              required:
                - from
                - to
      responses:
        '200':
          description: Workspace entry copied
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/WorkspaceItem'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks:
    get:
      operationId: notebooks.list
      tags:
        - Notebooks
      summary: List notebooks in a project
      description: When paging a filtered list, send the same filters with each cursor.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            enum:
              - draft
              - active
              - archived
              - deleted
            description: Notebook status to match. Deleted notebooks are excluded when
              omitted.
            example: active
          required: false
          description: Notebook status to match. Deleted notebooks are excluded when
            omitted.
          name: status
          in: query
        - schema:
            type: string
            description: Exact tag to match.
            example: analytics
          required: false
          description: Exact tag to match.
          name: tag
          in: query
        - schema:
            type: string
            description: Case-insensitive substring to match against the name or title and
              description.
            example: revenue
          required: false
          description: Case-insensitive substring to match against the name or title and
            description.
          name: q
          in: query
      responses:
        '200':
          description: List of notebooks, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      operationId: notebooks.create
      tags:
        - Notebooks
      summary: Create a notebook
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: false
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  minLength: 1
                  example: Revenue Analysis
                description:
                  type: string
                  example: Monthly revenue breakdown
                code:
                  type: string
                  example: import marimo as mo
                tags:
                  type: array
                  items:
                    type: string
                  example:
                    - finance
                readme:
                  type: string
                deps:
                  type: string
                runtime:
                  type: object
                  properties:
                    python_version:
                      type: string
                    marimo_version:
                      type: string
                base_image:
                  type: string
                  minLength: 1
                  example: ghcr.io/orgname/marimo-gpu:latest
                compute_profile:
                  type: string
                  minLength: 1
                  example: large
              required:
                - title
                - description
                - code
      responses:
        '201':
          description: Notebook created
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookMeta'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/git:
    post:
      operationId: notebooks.create-git
      tags:
        - Notebooks
      summary: Create a git-synced workspace notebook
      description: Requires project manager access because this selects a server-side
        repository.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  minLength: 1
                  example: GitHub app
                description:
                  type: string
                  example: Synced from a git repository
                provider:
                  type: string
                  minLength: 1
                  description: Git provider id. Recognized repository hosts take precedence over
                    this explicit claim.
                  example: github
                repo:
                  type: string
                  minLength: 1
                  example: marimo-team/marimohub
                branch:
                  type: string
                  minLength: 1
                  example: main
                root_path:
                  type: string
                  example: apps
                entry_notebook:
                  type: string
                  minLength: 1
                  example: my_app.py
                tags:
                  type: array
                  items:
                    type: string
                  example:
                    - git
                readme:
                  type: string
                runtime:
                  type: object
                  properties:
                    python_version:
                      type: string
                    marimo_version:
                      type: string
                base_image:
                  type: string
                  minLength: 1
                compute_profile:
                  type: string
                  minLength: 1
                sync_mode:
                  type: string
                  enum:
                    - push
                    - pull
                  default: push
              required:
                - title
                - description
                - repo
                - branch
                - entry_notebook
      responses:
        '201':
          description: Git-synced notebook created
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/GitNotebookCreateResult'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/sync-token/rotate:
    post:
      operationId: notebooks.rotate-sync-token
      x-cli-destructive: true
      tags:
        - Notebooks
      summary: Rotate a notebook sync token
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: Sync token rotated
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/SyncToken'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/source:
    patch:
      operationId: notebooks.update-source
      tags:
        - Notebooks
      summary: Update a git-synced notebook source
      description: Requires project manager access because this changes the
        server-side repository.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                repo:
                  type: string
                  minLength: 1
                  example: marimo-team/marimohub
                branch:
                  type: string
                  minLength: 1
                  example: main
                root_path:
                  type: string
                  example: apps
                entry_notebook:
                  type: string
                  minLength: 1
                  example: my_app.py
                sync_mode:
                  type: string
                  enum:
                    - push
                    - pull
              required:
                - repo
                - branch
                - root_path
                - entry_notebook
      responses:
        '200':
          description: Git source updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      source:
                        type: object
                        properties:
                          type:
                            type: string
                            enum:
                              - git
                          provider:
                            type:
                              - string
                              - 'null'
                            minLength: 1
                            description:
                              Detected Git provider id, or null when the repository host is not
                              recognized.
                            example: github
                          repo:
                            type: string
                            description: 'Normalized repository coordinate: owner/repo or an HTTPS
                              repository URL.'
                            example: marimo-team/marimohub
                          branch:
                            type: string
                            description: Synced repository branch.
                            example: main
                          root_path:
                            type: string
                            description: Repository-relative directory synced into the notebook workspace.
                            example: apps
                          entry_notebook:
                            type: string
                            description: Path to the entry notebook relative to root_path.
                            example: dashboard.py
                          pending_config:
                            $ref: '#/components/schemas/GitSourceConfig'
                          sync_mode:
                            type: string
                            enum:
                              - push
                              - pull
                          current_version_id:
                            type:
                              - string
                              - 'null'
                          commit:
                            type:
                              - string
                              - 'null'
                          last_synced_at:
                            type:
                              - string
                              - 'null'
                            format: date-time
                            example: 2025-03-05T14:00:00Z
                        required:
                          - type
                          - provider
                          - repo
                          - branch
                          - root_path
                          - entry_notebook
                          - sync_mode
                          - current_version_id
                          - commit
                          - last_synced_at
                    required:
                      - source
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/source/drift:
    get:
      operationId: notebooks.source.drift
      tags:
        - Notebooks
      summary: Compare a git-synced notebook against its branch head
      description: Resolves the configured branch head via the server-side provider
        credential and reports whether the notebook is behind it. Stateless —
        nothing is stored. Requires a provider listed in
        `capabilities.source_control.sync_providers`.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: Drift between the synced commit and the branch head
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/SourceDrift'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/source/sync:
    post:
      operationId: notebooks.source.sync
      x-cli-destructive: true
      tags:
        - Notebooks
      summary: Pull the branch head into a git-synced notebook
      description: 'Server-initiated sync: fetches the configured repository tree at
        the branch head and ingests it exactly like a pushed archive. A no-op
        when already at the head. Requires a provider listed in
        `capabilities.source_control.sync_providers`.'
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: Sync outcome
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/SourceSyncResult'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}:
    get:
      operationId: notebooks.get
      tags:
        - Notebooks
      summary: Get notebook metadata
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: Notebook detail
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      operationId: notebooks.update
      tags:
        - Notebooks
      summary: Update a notebook
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  minLength: 1
                description:
                  type: string
                code:
                  type: string
                tags:
                  type: array
                  items:
                    type: string
                readme:
                  type: string
                deps:
                  type: string
                message:
                  type: string
                  example: Add regional breakdown
                base_image:
                  type:
                    - string
                    - 'null'
                  minLength: 1
                compute_profile:
                  type:
                    - string
                    - 'null'
                  minLength: 1
      responses:
        '200':
          description: Notebook updated
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookMeta'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: notebooks.delete
      tags:
        - Notebooks
      summary: Delete a notebook (soft-delete)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      responses:
        '200':
          description: Notebook deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/content:
    get:
      operationId: notebooks.content
      tags:
        - Notebooks
      summary: Get notebook code
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: Notebook source code
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      code:
                        type: string
                    required:
                      - code
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/security-labels:
    put:
      operationId: notebooks.securityLabels.set
      tags:
        - Notebooks
      summary: Set a notebook security-label override
      description: Sets an override enforced IN ADDITION to the project labels, so it
        can only add restrictions. Requires super-admin standing — no project
        role grants label authority.
      security: *a3
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SecurityLabelsInput'
      responses:
        '200':
          description: Security labels updated
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookMeta'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: notebooks.securityLabels.clear
      tags:
        - Notebooks
      summary: Remove a notebook security-label override
      security: *a3
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      responses:
        '200':
          description: Security labels removed
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookMeta'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/versions:
    get:
      operationId: notebooks.versions.list
      tags:
        - Notebooks
      summary: List notebook versions
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: List of versions, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookVersionPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/versions/{vid}:
    get:
      operationId: notebooks.versions.get
      tags:
        - Notebooks
      summary: Get a specific version
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^ver_[0-9A-Z]{26}$
            example: ver_01HXYZ33333RSTUVWXYZAB
          required: true
          name: vid
          in: path
      responses:
        '200':
          description: Version details with code
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      version:
                        $ref: '#/components/schemas/NotebookVersion'
                      code:
                        type: string
                    required:
                      - version
                      - code
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/html:
    get:
      operationId: notebooks.html
      tags:
        - Notebooks
      summary: Latest HTML snapshot of the notebook's outputs
      description: Serves the newest version's HTML snapshot (captured best-effort at
        session teardown) raw — the static outputs shown to viewers under
        MARIMOHUB_VIEWER_MODE=static. `X-Marimohub-Version-Id` /
        `X-Marimohub-Captured-At` identify the snapshot. 404 with code
        `NO_HTML_SNAPSHOT` when no version has one.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: The HTML snapshot, served sandboxed (CSP forces an opaque origin)
          content:
            text/html:
              schema:
                type: string
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/versions/{vid}/html:
    get:
      operationId: notebooks.versions.html
      tags:
        - Notebooks
      summary: One version's HTML snapshot of the notebook's outputs
      description: Serves the HTML snapshot captured for this specific version, raw.
        404 with code `NO_HTML_SNAPSHOT` when the version captured none.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^ver_[0-9A-Z]{26}$
            example: ver_01HXYZ33333RSTUVWXYZAB
          required: true
          name: vid
          in: path
      responses:
        '200':
          description: The HTML snapshot, served sandboxed (CSP forces an opaque origin)
          content:
            text/html:
              schema:
                type: string
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/versions/{vid}/restore:
    post:
      operationId: notebooks.versions.restore
      x-cli-destructive: true
      tags:
        - Notebooks
      summary: Restore a version as a new save
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^ver_[0-9A-Z]{26}$
            example: ver_01HXYZ33333RSTUVWXYZAB
          required: true
          name: vid
          in: path
      responses:
        '201':
          description: Version restored as a new save; returns the updated notebook
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookMeta'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/duplicate:
    post:
      operationId: notebooks.duplicate
      tags:
        - Notebooks
      summary: Duplicate a notebook
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: false
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  minLength: 1
                  example: Revenue Analysis (copy)
      responses:
        '201':
          description: Notebook duplicated; returns the new notebook
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/NotebookMeta'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/sessions/{sid}/change-requests:
    post:
      operationId: notebooks.change-requests.open
      tags:
        - Source control publishing
      summary: Publish notebook changes to a new or existing change request
      description: A proposal is an immutable set of notebook changes captured with
        its exact source revision. This operation captures a proposal from a
        running persistent editor session and publishes it as a pull request,
        merge request, or equivalent through the configured source-control
        provider. Set target_proposal_id to update the change request published
        by that proposal; omit it to create a new change request. The
        Idempotency-Key header is required; retry with the same key to resume
        the same operation. If the error code is PROPOSAL_RETRY_REQUIRED, retry
        with a new key instead.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^sess-[0-9a-z]{16}$
            example: sess-9qm4xz7rp3w8h2k9
          required: true
          name: sid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: true
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OpenNotebookChangeRequestBody'
      responses:
        '201':
          description: Change request published
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/OpenNotebookChangeRequestResult'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/sessions:
    get:
      operationId: sessions.list
      tags:
        - Sessions
      summary: List active sessions for a project
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: Active sessions for the project, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/SessionPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/sessions/{sid}:
    get:
      operationId: sessions.get
      tags:
        - Sessions
      summary: Get a session (status + kernel URL)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^sess-[0-9a-z]{16}$
            example: sess-9qm4xz7rp3w8h2k9
          required: true
          name: sid
          in: path
      responses:
        '200':
          description: Session
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Session'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: sessions.terminate
      tags:
        - Sessions
      summary: Terminate a session and destroy sandbox
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^sess-[0-9a-z]{16}$
            example: sess-9qm4xz7rp3w8h2k9
          required: true
          name: sid
          in: path
      responses:
        '200':
          description: Session terminated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/editor-session:
    get:
      operationId: sessions.editor.get
      tags:
        - Sessions
      summary: Inspect persistent editor ownership
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      responses:
        '200':
          description: Persistent editor ownership and current activity
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/EditorSessionState'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/editor-session/takeover:
    post:
      operationId: sessions.editor.takeover
      x-cli-destructive: true
      tags:
        - Sessions
      summary: Gracefully take over an exclusive editor session
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditorTakeoverBody'
      responses:
        '200':
          description: The prior editor was saved and stopped
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/sessions:
    post:
      operationId: sessions.create
      tags:
        - Sessions
      summary: Create a session and provision a sandbox
      description: Create or reuse a notebook sandbox. Edit-session reuse follows the
        configured editor sandbox-sharing policy. App-session reuse is shared
        per notebook.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: false
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      requestBody:
        required: false
        description: Optional; omit for an edit session.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SessionCreateBody'
      responses:
        '200':
          description: Session created or reused
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/SessionCreateResult'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/sessions/{sid}/heartbeat:
    post:
      operationId: sessions.heartbeat
      tags:
        - Sessions
      summary: Update session heartbeat
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^sess-[0-9a-z]{16}$
            example: sess-9qm4xz7rp3w8h2k9
          required: true
          name: sid
          in: path
      responses:
        '200':
          description: Heartbeat updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Session'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/sessions/{sid}/surfaces/{surface}:
    post:
      operationId: sessions.surfaces.ensure
      tags:
        - Sessions
      summary: Start or reuse a session surface
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^sess-[0-9a-z]{16}$
            example: sess-9qm4xz7rp3w8h2k9
          required: true
          name: sid
          in: path
        - schema:
            type: string
            enum:
              - vscode
              - opencode
          required: true
          name: surface
          in: path
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SurfaceStartBody'
      responses:
        '200':
          description: Surface ready
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    allOf:
                      - $ref: '#/components/schemas/Surface'
                      - type: object
                        properties:
                          id:
                            type: string
                            enum:
                              - vscode
                              - opencode
                        required:
                          - id
                required:
                  - success
                  - data
        '202':
          description: Surface starting
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    allOf:
                      - $ref: '#/components/schemas/Surface'
                      - type: object
                        properties:
                          id:
                            type: string
                            enum:
                              - vscode
                              - opencode
                        required:
                          - id
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    get:
      operationId: sessions.surfaces.get
      tags:
        - Sessions
      summary: Get a session surface
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^sess-[0-9a-z]{16}$
            example: sess-9qm4xz7rp3w8h2k9
          required: true
          name: sid
          in: path
        - schema:
            type: string
            enum:
              - vscode
              - opencode
          required: true
          name: surface
          in: path
      responses:
        '200':
          description: Surface status
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    allOf:
                      - $ref: '#/components/schemas/Surface'
                      - type: object
                        properties:
                          id:
                            type: string
                            enum:
                              - vscode
                              - opencode
                        required:
                          - id
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: sessions.surfaces.stop
      tags:
        - Sessions
      summary: Stop a secondary session surface
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^sess-[0-9a-z]{16}$
            example: sess-9qm4xz7rp3w8h2k9
          required: true
          name: sid
          in: path
        - schema:
            type: string
            enum:
              - vscode
              - opencode
          required: true
          name: surface
          in: path
      responses:
        '200':
          description: Surface stopped
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/jobs:
    get:
      operationId: jobs.list
      tags:
        - Jobs
      summary: List a notebook’s jobs
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: Job definitions, oldest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/JobPage'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      operationId: jobs.create
      tags:
        - Jobs
      summary: Create a job
      description: A job runs the notebook headlessly with `marimo export html` — on a
        cron schedule, or on demand via `jobs.runs.trigger`. Runs execute with
        the project’s resolved integration secrets and federated credentials, so
        this requires the editor role like starting a session.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: false
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobCreateBody'
      responses:
        '201':
          description: Job created
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Job'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/jobs/{jid}:
    get:
      operationId: jobs.get
      tags:
        - Jobs
      summary: Get a job
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
      responses:
        '200':
          description: Job
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Job'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      operationId: jobs.update
      tags:
        - Jobs
      summary: Update a job
      description: Partial update. `null` clears an optional field (schedule,
        parameters, retry, timeout, notifications).
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobUpdateBody'
      responses:
        '200':
          description: Job updated
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/Job'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: jobs.delete
      x-cli-destructive: true
      tags:
        - Jobs
      summary: Delete a job and its run history
      description: Active runs are cancelled and their sandboxes destroyed first.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: true
          name: if-match
          in: header
      responses:
        '200':
          description: Job deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/jobs/{jid}/runs:
    post:
      operationId: jobs.runs.trigger
      tags:
        - Jobs
      summary: Run a job now
      description: Enqueues a run; the scheduler on the maintenance replica dispatches
        it within one tick. Returns the queued run — poll `jobs.runs.get` for
        progress.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            description: Stable client-generated key reused for retries of the same
              operation.
            example: a1b2c3d4-e5f6-7890
          required: false
          description: Stable client-generated key reused for retries of the same operation.
          name: idempotency-key
          in: header
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobRunTriggerBody'
      responses:
        '201':
          description: Run queued
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/JobRun'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    get:
      operationId: jobs.runs.list
      tags:
        - Jobs
      summary: List a job’s runs
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: Runs, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/JobRunPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/jobs/{jid}/runs/{rid}:
    get:
      operationId: jobs.runs.get
      tags:
        - Jobs
      summary: Get a run
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: string
            pattern: ^run_[0-9A-HJKMNP-TV-Z]{26}$
            example: run_01HXYZ33333RSTUVWXYZABCDEF
          required: true
          name: rid
          in: path
      responses:
        '200':
          description: Run
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/JobRun'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/jobs/{jid}/runs/{rid}/cancel:
    post:
      operationId: jobs.runs.cancel
      x-cli-destructive: true
      tags:
        - Jobs
      summary: Cancel a run
      description: Marks the run cancelled and destroys its sandbox when one exists.
        Runs are history and are never deleted individually.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: string
            pattern: ^run_[0-9A-HJKMNP-TV-Z]{26}$
            example: run_01HXYZ33333RSTUVWXYZABCDEF
          required: true
          name: rid
          in: path
      responses:
        '200':
          description: Run cancelled (or already terminal)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/JobRun'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/jobs/{jid}/runs/{rid}/html:
    get:
      operationId: jobs.runs.html
      tags:
        - Jobs
      summary: Rendered notebook output of a run
      description: Serves the HTML the run exported, raw. 404 with code
        `NO_RUN_OUTPUT` when the run captured none (still running, cancelled, or
        failed before exporting).
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: string
            pattern: ^run_[0-9A-HJKMNP-TV-Z]{26}$
            example: run_01HXYZ33333RSTUVWXYZABCDEF
          required: true
          name: rid
          in: path
      responses:
        '200':
          description: The rendered output, served sandboxed (CSP forces an opaque origin)
          content:
            text/html:
              schema:
                type: string
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/notebooks/{nid}/jobs/{jid}/runs/{rid}/logs:
    get:
      operationId: jobs.runs.logs
      tags:
        - Jobs
      summary: stdout/stderr of a run
      description: 'Raw text, editor-only: logs can echo environment values and
        tracebacks the viewer role cannot otherwise read. 404 with code
        `NO_RUN_OUTPUT` when none were captured.'
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^nb-[0-9a-z]{16}$
            example: nb-3w8h2k9qm4xz7rp3
          required: true
          name: nid
          in: path
        - schema:
            type: string
            pattern: ^job-[0-9a-z]{16}$
            example: job-7h2k9qm4xz7rp3w8
          required: true
          name: jid
          in: path
        - schema:
            type: string
            pattern: ^run_[0-9A-HJKMNP-TV-Z]{26}$
            example: run_01HXYZ33333RSTUVWXYZABCDEF
          required: true
          name: rid
          in: path
      responses:
        '200':
          description: Captured logs
          content:
            text/plain:
              schema:
                type: string
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/integrations/kinds:
    get:
      operationId: integrations.kinds.list
      tags:
        - Integrations
      summary: List available integration kinds (schemas drive the config forms)
      responses:
        '200':
          description: Registered integration kinds
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/IntegrationKind'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations:
    get:
      operationId: integrations.project.list
      tags:
        - Integrations
      summary: List a project's integrations
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: Integration instances (no config)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      operationId: integrations.project.create
      tags:
        - Integrations
      summary: Create an integration (manager only)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                kind:
                  type: string
                  minLength: 1
                name:
                  type: string
                  pattern: ^[a-z][a-z0-9-]{0,31}$
                  example: prod
                config:
                  type: object
                  additionalProperties: {}
                change_note:
                  type: string
                  maxLength: 500
              required:
                - kind
                - name
                - config
              additionalProperties: false
      responses:
        '201':
          description: Integration created (config redacted)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDetail'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}:
    get:
      operationId: integrations.project.get
      tags:
        - Integrations
      summary: Get an integration with its redacted config
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
      responses:
        '200':
          description: Integration detail (config redacted)
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      operationId: integrations.project.update
      tags:
        - Integrations
      summary: Update an integration (manager only); a config change appends a version
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  pattern: ^[a-z][a-z0-9-]{0,31}$
                enabled:
                  type: boolean
                config:
                  type: object
                  additionalProperties: {}
                change_note:
                  type: string
                  maxLength: 500
              additionalProperties: false
      responses:
        '200':
          description: Integration updated (config redacted)
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: integrations.project.delete
      tags:
        - Integrations
      summary: Delete an integration and its version history (manager only)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      responses:
        '200':
          description: Integration deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/versions:
    get:
      operationId: integrations.project.versions
      tags:
        - Integrations
      summary: List an integration's config versions (metadata only)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: Version history, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationVersionPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/copy:
    post:
      operationId: integrations.project.copy
      tags:
        - Integrations
      summary: Copy an integration from another project (manager of both projects)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IntegrationCopyRequest'
      responses:
        '201':
          description: Integration copied (inline secrets re-encrypted; external
            references preserved)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/test:
    post:
      operationId: integrations.project.test
      tags:
        - Integrations
      summary: Probe connectivity for an unsaved config or a stored instance (manager
        only)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IntegrationTestRequest'
      responses:
        '200':
          description: Probe outcome (never secret material)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationTestResult'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/query-readiness:
    post:
      operationId: integrations.project.query-readiness
      tags:
        - Integrations
      summary: Evaluate SQL readiness for an unsaved integration config (manager only)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IntegrationQueryReadinessRequest'
      responses:
        '200':
          description: All SQL readiness checks
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/IntegrationQueryReadinessCheck'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse:
    get:
      operationId: integrations.project.browse.get
      tags:
        - Integrations
      summary: Whether this integration instance can be browsed (editor or above)
      description: Browse routes resolve the id against the project tier first, then
        the inherited org tier; a shadowed org instance reads as absent. All
        browse operations are strictly read-only against the upstream.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
      responses:
        '200':
          description: Instance browse capability
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationBrowseCapability'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/namespaces:
    get:
      operationId: integrations.project.browse.namespaces
      tags:
        - Integrations
      summary: List catalog namespaces (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 500
            default: 100
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            example: 'false'
          required: false
          name: fresh
          in: query
        - schema:
            type: string
            minLength: 1
            description: Namespace parts joined by U+001F (percent-encoded as %1F).
            example: sales
          required: false
          description: Namespace parts joined by U+001F (percent-encoded as %1F).
          name: parent
          in: query
      responses:
        '200':
          description: Namespaces, with upstream pagination passed through
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationBrowseNamespacePage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/tables:
    get:
      operationId: integrations.project.browse.tables
      tags:
        - Integrations
      summary: List tables in a namespace (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 500
            default: 100
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            example: 'false'
          required: false
          name: fresh
          in: query
        - schema:
            type: string
            minLength: 1
            description: Namespace parts joined by U+001F (percent-encoded as %1F).
            example: sales
          required: true
          description: Namespace parts joined by U+001F (percent-encoded as %1F).
          name: namespace
          in: query
      responses:
        '200':
          description: Table names, with upstream pagination passed through
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationBrowseTablePage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/schema:
    get:
      operationId: integrations.project.browse.schema
      tags:
        - Integrations
      summary: Get a table's schema (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            minLength: 1
            description: Namespace parts joined by U+001F (percent-encoded as %1F).
            example: sales
          required: true
          description: Namespace parts joined by U+001F (percent-encoded as %1F).
          name: namespace
          in: query
        - schema:
            type: string
            minLength: 1
            example: orders
          required: true
          name: table
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            example: 'false'
          required: false
          name: fresh
          in: query
      responses:
        '200':
          description: Column names, types, and partitioning
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationTableSchema'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/preview:
    post:
      operationId: integrations.project.browse.preview
      tags:
        - Integrations
      summary: Preview a table's rows (editor or above)
      description: Runs a bounded read-only scan. HTTP-native integrations execute
        through the guarded browse probe; other integrations use a fresh,
        isolated preview sandbox.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                namespace:
                  type: array
                  items:
                    type: string
                    minLength: 1
                  minItems: 1
                table:
                  type: string
                  minLength: 1
                limit:
                  type: integer
                  exclusiveMinimum: 0
                  maximum: 100
                  default: 20
              required:
                - namespace
                - table
      responses:
        '200':
          description: Column names and a bounded row sample
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationTablePreview'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/query:
    post:
      operationId: integrations.project.browse.query
      tags:
        - Integrations
      summary: Run SQL against one integration (manager or above)
      description: SQL execution gated by deployment configuration. Each request uses
        a fresh isolated worker with hard execution, row, and byte limits.
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                sql:
                  type: string
                  minLength: 1
              required:
                - sql
              additionalProperties: false
      responses:
        '200':
          description: Bounded query result
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDataQueryResult'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/query/schema:
    get:
      operationId: integrations.project.browse.query-schema
      tags:
        - Integrations
      summary: Get bounded SQL completion schema (manager or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            minLength: 1
          required: false
          name: focus_namespace
          in: query
        - schema:
            type: string
            minLength: 1
          required: false
          name: focus_table
          in: query
      responses:
        '200':
          description: Bounded table and column schema for SQL tools
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationQuerySchema'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/query/generate:
    post:
      operationId: integrations.project.browse.generate-query
      tags:
        - Integrations
      summary: Generate or revise SQL with managed AI (manager or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  type: string
                  enum:
                    - generate
                    - revise
                instruction:
                  type: string
                  minLength: 1
                  maxLength: 4000
                sql:
                  type: string
              required:
                - mode
                - instruction
              additionalProperties: false
      responses:
        '200':
          description: Generated DuckDB SQL
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      sql:
                        type: string
                    required:
                      - sql
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/objects/buckets:
    get:
      operationId: integrations.project.browse.object-buckets
      tags:
        - Integrations
      summary: List object-store buckets (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            default: 50
            example: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            example: 'false'
          required: false
          name: fresh
          in: query
      responses:
        '200':
          description: Buckets visible through the integration
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/IntegrationObjectBucket'
                      next_cursor:
                        type:
                          - string
                          - 'null'
                    required:
                      - items
                      - next_cursor
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/objects:
    get:
      operationId: integrations.project.browse.objects
      tags:
        - Integrations
      summary: List direct object-store children (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            default: 50
            example: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            example: 'false'
          required: false
          name: fresh
          in: query
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            example: analytics-lake
          required: true
          name: bucket
          in: query
        - schema:
            type: string
            example: events/2026/
          required: false
          name: prefix
          in: query
      responses:
        '200':
          description: Direct prefixes and objects
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/IntegrationObjectEntry'
                      next_cursor:
                        type:
                          - string
                          - 'null'
                    required:
                      - items
                      - next_cursor
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/objects/search:
    get:
      operationId: integrations.project.browse.search-objects
      tags:
        - Integrations
      summary: Run a bounded object-key search (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            default: 50
            example: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            example: analytics-lake
          required: true
          name: bucket
          in: query
        - schema:
            type: string
            example: events/2026/
          required: false
          name: prefix
          in: query
        - schema:
            type: string
            minLength: 2
            maxLength: 1024
          required: true
          name: query
          in: query
        - schema:
            type: string
          required: false
          name: formats
          in: query
        - schema:
            type: string
            format: date-time
          required: false
          name: modified_after
          in: query
        - schema:
            type: string
            format: date-time
          required: false
          name: modified_before
          in: query
        - schema:
            type:
              - number
              - 'null'
            minimum: 0
          required: false
          name: min_size
          in: query
        - schema:
            type:
              - number
              - 'null'
            minimum: 0
          required: false
          name: max_size
          in: query
      responses:
        '200':
          description: Bounded object-key search results
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/IntegrationObjectEntry'
                      next_cursor:
                        type:
                          - string
                          - 'null'
                      scanned:
                        type: integer
                        minimum: 0
                      complete:
                        type: boolean
                    required:
                      - items
                      - next_cursor
                      - scanned
                      - complete
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/objects/head:
    get:
      operationId: integrations.project.browse.object-head
      tags:
        - Integrations
      summary: Read object metadata and tags (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            example: analytics-lake
          required: true
          name: bucket
          in: query
        - schema:
            type: string
            minLength: 1
            example: events/2026/part-001.jsonl
          required: true
          name: key
          in: query
        - schema:
            type: string
            minLength: 1
            maxLength: 2048
          required: false
          name: version_id
          in: query
      responses:
        '200':
          description: Object metadata
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationObjectDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/objects/versions:
    get:
      operationId: integrations.project.browse.object-versions
      tags:
        - Integrations
      summary: List object versions and delete markers (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            maximum: 100
            default: 50
            example: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            example: 'false'
          required: false
          name: fresh
          in: query
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            example: analytics-lake
          required: true
          name: bucket
          in: query
        - schema:
            type: string
            minLength: 1
            example: events/2026/part-001.jsonl
          required: true
          name: key
          in: query
        - schema:
            type: string
            minLength: 1
            maxLength: 2048
          required: false
          name: version_id
          in: query
      responses:
        '200':
          description: Object versions and delete markers
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/IntegrationObjectVersion'
                      next_cursor:
                        type:
                          - string
                          - 'null'
                    required:
                      - items
                      - next_cursor
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/objects/preview:
    post:
      operationId: integrations.project.browse.preview-object
      tags:
        - Integrations
      summary: Preview bounded object content (editor or above)
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                bucket:
                  type: string
                  minLength: 1
                  maxLength: 255
                  example: analytics-lake
                key:
                  type: string
                  minLength: 1
                  example: events/2026/part-001.jsonl
                version_id:
                  type: string
                  minLength: 1
                  maxLength: 2048
                limit:
                  type: integer
                  exclusiveMinimum: 0
                  maximum: 100
                  default: 20
              required:
                - bucket
                - key
      responses:
        '200':
          description: Bounded object preview
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationObjectPreview'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/projects/{pid}/integrations/{iid}/browse/objects/content:
    get:
      operationId: integrations.project.browse.object-content
      tags:
        - Integrations
      summary: Stream object content (editor or above)
      description: 'Streams the object bytes raw — the target of the `content_url`
        embedded in preview responses. `inline=true` serves a sandboxed inline
        rendering (CSP forces an opaque origin); otherwise the response is a
        download (`Content-Disposition: attachment`). Supports single-part
        `Range` requests and an `etag` precondition (412 on mismatch).'
      parameters:
        - schema:
            type: string
            pattern: ^proj-[0-9a-z]{16}$
            example: proj-7h2k9qm4xz7rp3w8
          required: true
          name: pid
          in: path
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            minLength: 1
            maxLength: 255
            example: analytics-lake
          required: true
          name: bucket
          in: query
        - schema:
            type: string
            minLength: 1
            example: events/2026/part-001.jsonl
          required: true
          name: key
          in: query
        - schema:
            type: string
            minLength: 1
            maxLength: 2048
          required: false
          name: version_id
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'false'
          required: false
          name: inline
          in: query
        - schema:
            type: string
            maxLength: 1024
          required: false
          name: etag
          in: query
        - schema:
            type: string
            example: bytes=0-1023
          required: false
          name: range
          in: header
      responses:
        '200':
          description: The object bytes, streamed
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        '206':
          description: The requested byte range (`Content-Range` identifies it)
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '416':
          description: Range not satisfiable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/org/integrations:
    get:
      operationId: integrations.org.list
      tags:
        - Integrations
      summary: List org-wide integrations (super admin only)
      parameters:
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: Org integration instances (no config)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      operationId: integrations.org.create
      tags:
        - Integrations
      summary: Create an org-wide integration (super admin only)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                kind:
                  type: string
                  minLength: 1
                name:
                  type: string
                  pattern: ^[a-z][a-z0-9-]{0,31}$
                  example: prod
                config:
                  type: object
                  additionalProperties: {}
                change_note:
                  type: string
                  maxLength: 500
              required:
                - kind
                - name
                - config
              additionalProperties: false
      responses:
        '201':
          description: Integration created (config redacted)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/org/integrations/{iid}:
    get:
      operationId: integrations.org.get
      tags:
        - Integrations
      summary: Get an org-wide integration with its redacted config (super admin only)
      parameters:
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
      responses:
        '200':
          description: Integration detail (config redacted)
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      operationId: integrations.org.update
      tags:
        - Integrations
      summary: Update an org-wide integration (super admin only)
      parameters:
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  pattern: ^[a-z][a-z0-9-]{0,31}$
                enabled:
                  type: boolean
                config:
                  type: object
                  additionalProperties: {}
                change_note:
                  type: string
                  maxLength: 500
              additionalProperties: false
      responses:
        '200':
          description: Integration updated (config redacted)
          headers:
            ETag:
              schema:
                type: string
                description: Strong validator (the resource version). Echo as `If-Match` to
                  guard a write.
                example: '"2025-03-05T14:00:00Z"'
              required: true
              description: Strong validator (the resource version). Echo as `If-Match` to
                guard a write.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationDetail'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      operationId: integrations.org.delete
      tags:
        - Integrations
      summary: Delete an org-wide integration and its version history (super admin only)
      parameters:
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: string
            example: '"2025-03-05T14:00:00Z"'
          required: false
          name: if-match
          in: header
      responses:
        '200':
          description: Integration deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '412':
          description: Precondition failed (If-Match did not match the current version)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/org/integrations/{iid}/versions:
    get:
      operationId: integrations.org.versions
      tags:
        - Integrations
      summary: List an org-wide integration's config versions (super admin only)
      parameters:
        - schema:
            type: string
            pattern: ^intg-[0-9a-z]{16}$
            example: intg-7h2k9qm4xz7rp3w8
          required: true
          name: iid
          in: path
        - schema:
            type: integer
            exclusiveMinimum: 0
            example: 100
          required: false
          name: limit
          in: query
        - schema:
            type: string
            example: WyIyMDI1LTAzLTA1VDE0OjAwOjAwWiIsIm5iLTEiXQ
          required: false
          name: cursor
          in: query
      responses:
        '200':
          description: Version history, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationVersionPage'
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/org/integrations/test:
    post:
      operationId: integrations.org.test
      tags:
        - Integrations
      summary: Probe connectivity for an unsaved or stored org config (super admin only)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IntegrationTestRequest'
      responses:
        '200':
          description: Probe outcome (never secret material)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/IntegrationTestResult'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/org/integrations/query-readiness:
    post:
      operationId: integrations.org.query-readiness
      tags:
        - Integrations
      summary: Evaluate SQL readiness for an unsaved org config (super admin only)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IntegrationQueryReadinessRequest'
      responses:
        '200':
          description: All SQL readiness checks
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/IntegrationQueryReadinessCheck'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/users/search:
    get:
      operationId: users.search
      tags:
        - Users
      summary: Search the user directory
      description: Case-insensitive substring search over email, name, and id, for the
        add-member picker. Only users who have signed in at least once are in
        the directory. Under MARIMOHUB_DEFAULT_ROLE=none the caller must own or
        belong to at least one project — a signed-in account with no involvement
        cannot enumerate the directory; with a default role set, every
        authenticated user may search.
      parameters:
        - schema:
            type: string
            minLength: 1
            maxLength: 200
            example: ada
          required: true
          name: q
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 25
            default: 10
          required: false
          name: limit
          in: query
      responses:
        '200':
          description: Matching users, name-sorted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/users:
    get:
      operationId: users.resolve
      tags:
        - Users
      summary: Resolve user ids to display identities
      description: Batch-resolve opaque user ids (the auth `sub` stored as a notebook
        `author` or session `user_id`) into `{ id, email, name, picture_url }`.
        Ids with no recorded identity are omitted from the result map.
      parameters:
        - schema:
            type: string
            description: Comma-separated user ids.
            example: user,sub-abc123
          required: false
          description: Comma-separated user ids.
          name: ids
          in: query
      responses:
        '200':
          description: Map of user id → resolved identity (unknown ids omitted)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    additionalProperties:
                      $ref: '#/components/schemas/User'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/tokens:
    post:
      operationId: auth.tokens.create
      tags:
        - Auth
      summary: Create a personal access token
      description: 'Mint a machine credential that acts as the calling user (CI,
        scripts, the CLI): send it as `Authorization: Bearer mhub_pat_…`. The
        plaintext token is returned once, in this response, and never again.
        Requires session (SSO) auth — a token cannot mint tokens.'
      security: *a3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 100
                  example: ci-deploy
                expires_in_days:
                  type: integer
                  minimum: 1
                  maximum: 3650
                  description: Days until expiry; omit for a non-expiring token.
                  example: 90
              required:
                - name
              additionalProperties: false
      responses:
        '201':
          description: The new token — copy it now; it is never shown again
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/ApiTokenCreated'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    get:
      operationId: auth.tokens.list
      tags:
        - Auth
      summary: List the caller's personal access tokens
      description: Metadata only — the secret is never retrievable after creation.
      security: *a3
      responses:
        '200':
          description: Tokens, newest first
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ApiToken'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/tokens/scoped:
    post:
      operationId: auth.tokens.createScoped
      tags:
        - Auth
      summary: Create a scoped personal access token
      description: Mint a v2 personal access token with an immutable action and
        project grant. Selected projects must be visible to the caller when the
        token is created.
      security: *a3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 100
                  example: ci-deploy
                expires_in_days:
                  type: integer
                  minimum: 1
                  maximum: 3650
                  description: Days until expiry; omit for a non-expiring token.
                  example: 90
                grant:
                  type: object
                  properties:
                    actions:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            enum:
                              - project.create
                              - admin.access
                              - org-integration.manage
                              - audit.global.read
                              - directory.search
                              - project.read
                              - project.update
                              - project.delete
                              - project.members.manage
                              - project.events.read
                              - project.alerts.manage
                              - notebook.write
                              - notebook.manage
                              - integration.read
                              - integration.use
                              - integration.manage
                              - change-request.publish
                              - security-labels.raise
                              - security-labels.lower
                              - session.attach
                              - session.stop
                              - session.surface
                              - session.proxy
                              - session.start
                          uniqueItems: true
                    projects:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            pattern: ^proj-[0-9a-z]{16}$
                          minItems: 1
                          maxItems: 100
                          uniqueItems: true
                  required:
                    - actions
                    - projects
                  additionalProperties: false
              required:
                - name
                - grant
              additionalProperties: false
      responses:
        '201':
          description: The new token — copy it now; it is never shown again
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    $ref: '#/components/schemas/ApiTokenCreated'
                required:
                  - success
                  - data
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/tokens/{tokenId}:
    delete:
      operationId: auth.tokens.revoke
      tags:
        - Auth
      summary: Revoke a personal access token
      description: Deletes the token; API requests using it fail within the
        verification-cache TTL (~30 seconds) on other replicas, immediately on
        this one.
      security: *a3
      parameters:
        - schema:
            type: string
            pattern: ^[0-9A-Z]{26}$
            example: 01HXY0S6GWMBASVAG3PZ7Y2K5T
          required: true
          name: tokenId
          in: path
      responses:
        '200':
          description: Token revoked
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/cli-authorizations:
    post:
      operationId: auth.cli.approve
      x-cli-hidden: true
      tags:
        - Auth
      summary: Approve a CLI login
      description: Creates a one-time code that is bound to the CLI PKCE challenge.
        Requires a browser session. Exchange creates the personal access token.
      security: *a3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                callback_uri:
                  type: string
                  maxLength: 300
                  format: uri
                  description: HTTP loopback callback using 127.0.0.1 or [::1], an explicit port,
                    and the exact /callback path.
                  example: http://127.0.0.1:49152/callback
                state:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{32,128}$
                  description: Opaque base64url CSRF state generated by the CLI.
                code_challenge:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{43}$
                  description: Base64url-encoded SHA-256 PKCE challenge generated by the CLI.
                token_name:
                  type: string
                  minLength: 1
                  maxLength: 100
                  description: Name shown in the user's personal access token list.
                expires_in_days:
                  type: integer
                  minimum: 1
                  maximum: 3650
                  description: Lifetime of the personal access token minted during exchange.
              required:
                - callback_uri
                - state
                - code_challenge
                - token_name
                - expires_in_days
              additionalProperties: false
      responses:
        '201':
          description: Loopback callback carrying the one-time authorization code
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      redirect_uri:
                        type: string
                        format: uri
                      expires_at:
                        type: string
                        format: date-time
                    required:
                      - redirect_uri
                      - expires_at
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/cli-authorizations/scoped:
    post:
      operationId: auth.cli.approveScoped
      x-cli-hidden: true
      tags:
        - Auth
      summary: Approve a scoped CLI login
      security: *a3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                callback_uri:
                  type: string
                  maxLength: 300
                  format: uri
                  description: HTTP loopback callback using 127.0.0.1 or [::1], an explicit port,
                    and the exact /callback path.
                  example: http://127.0.0.1:49152/callback
                state:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{32,128}$
                  description: Opaque base64url CSRF state generated by the CLI.
                code_challenge:
                  type: string
                  pattern: ^[A-Za-z0-9_-]{43}$
                  description: Base64url-encoded SHA-256 PKCE challenge generated by the CLI.
                token_name:
                  type: string
                  minLength: 1
                  maxLength: 100
                  description: Name shown in the user's personal access token list.
                expires_in_days:
                  type: integer
                  minimum: 1
                  maximum: 3650
                  description: Lifetime of the personal access token minted during exchange.
                requested_grant:
                  type: object
                  properties:
                    actions:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            enum:
                              - project.create
                              - admin.access
                              - org-integration.manage
                              - audit.global.read
                              - directory.search
                              - project.read
                              - project.update
                              - project.delete
                              - project.members.manage
                              - project.events.read
                              - project.alerts.manage
                              - notebook.write
                              - notebook.manage
                              - integration.read
                              - integration.use
                              - integration.manage
                              - change-request.publish
                              - security-labels.raise
                              - security-labels.lower
                              - session.attach
                              - session.stop
                              - session.surface
                              - session.proxy
                              - session.start
                          uniqueItems: true
                    projects:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            pattern: ^proj-[0-9a-z]{16}$
                          minItems: 1
                          maxItems: 100
                          uniqueItems: true
                  required:
                    - actions
                    - projects
                  additionalProperties: false
                grant:
                  type: object
                  properties:
                    actions:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            enum:
                              - project.create
                              - admin.access
                              - org-integration.manage
                              - audit.global.read
                              - directory.search
                              - project.read
                              - project.update
                              - project.delete
                              - project.members.manage
                              - project.events.read
                              - project.alerts.manage
                              - notebook.write
                              - notebook.manage
                              - integration.read
                              - integration.use
                              - integration.manage
                              - change-request.publish
                              - security-labels.raise
                              - security-labels.lower
                              - session.attach
                              - session.stop
                              - session.surface
                              - session.proxy
                              - session.start
                          uniqueItems: true
                    projects:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            pattern: ^proj-[0-9a-z]{16}$
                          minItems: 1
                          maxItems: 100
                          uniqueItems: true
                  required:
                    - actions
                    - projects
                  additionalProperties: false
              required:
                - callback_uri
                - state
                - code_challenge
                - token_name
                - expires_in_days
                - requested_grant
                - grant
              additionalProperties: false
      responses:
        '201':
          description: Loopback callback carrying the one-time authorization code
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      redirect_uri:
                        type: string
                        format: uri
                      expires_at:
                        type: string
                        format: date-time
                    required:
                      - redirect_uri
                      - expires_at
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/cli-device-authorizations:
    post:
      operationId: auth.cli.device.approve
      x-cli-hidden: true
      tags:
        - Auth
      summary: Approve a CLI device login
      description: Approves a short-lived device code for the signed-in user. Requires
        a browser session. Personal access tokens cannot approve device logins.
      security: *a3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_code:
                  type: string
                  minLength: 8
                  maxLength: 20
                token_name:
                  type: string
                  minLength: 1
                  maxLength: 100
                  description: Name shown in the user's personal access token list.
                expires_in_days:
                  type: integer
                  minimum: 1
                  maximum: 3650
                  description: Lifetime of the personal access token minted during exchange.
              required:
                - user_code
                - token_name
                - expires_in_days
              additionalProperties: false
      responses:
        '200':
          description: Device authorization approved
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      expires_at:
                        type: string
                        format: date-time
                    required:
                      - expires_at
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/cli-device-authorizations/{userCode}:
    get:
      operationId: auth.cli.device.preview
      x-cli-hidden: true
      tags:
        - Auth
      summary: Preview a CLI device login
      security: *a3
      parameters:
        - schema:
            type: string
            minLength: 8
            maxLength: 20
          required: true
          name: userCode
          in: path
      responses:
        '200':
          description: CLI device authorization type and requested grant
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    oneOf:
                      - type: object
                        properties:
                          status:
                            type: string
                            enum:
                              - legacy
                          expires_at:
                            type: string
                            format: date-time
                        required:
                          - status
                          - expires_at
                      - type: object
                        properties:
                          status:
                            type: string
                            enum:
                              - scoped
                          requested_grant:
                            type: object
                            properties:
                              actions:
                                anyOf:
                                  - type: string
                                    enum:
                                      - '*'
                                  - type: array
                                    items:
                                      type: string
                                      enum:
                                        - project.create
                                        - admin.access
                                        - org-integration.manage
                                        - audit.global.read
                                        - directory.search
                                        - project.read
                                        - project.update
                                        - project.delete
                                        - project.members.manage
                                        - project.events.read
                                        - project.alerts.manage
                                        - notebook.write
                                        - notebook.manage
                                        - integration.read
                                        - integration.use
                                        - integration.manage
                                        - change-request.publish
                                        - security-labels.raise
                                        - security-labels.lower
                                        - session.attach
                                        - session.stop
                                        - session.surface
                                        - session.proxy
                                        - session.start
                                    uniqueItems: true
                              projects:
                                anyOf:
                                  - type: string
                                    enum:
                                      - '*'
                                  - type: array
                                    items:
                                      type: string
                                      pattern: ^proj-[0-9a-z]{16}$
                                    minItems: 1
                                    maxItems: 100
                                    uniqueItems: true
                            required:
                              - actions
                              - projects
                            additionalProperties: false
                          expires_at:
                            type: string
                            format: date-time
                        required:
                          - status
                          - requested_grant
                          - expires_at
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/me/cli-device-authorizations/scoped:
    post:
      operationId: auth.cli.device.approveScoped
      x-cli-hidden: true
      tags:
        - Auth
      summary: Approve a scoped CLI device login
      security: *a3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_code:
                  type: string
                  minLength: 8
                  maxLength: 20
                token_name:
                  type: string
                  minLength: 1
                  maxLength: 100
                  description: Name shown in the user's personal access token list.
                expires_in_days:
                  type: integer
                  minimum: 1
                  maximum: 3650
                  description: Lifetime of the personal access token minted during exchange.
                grant:
                  type: object
                  properties:
                    actions:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            enum:
                              - project.create
                              - admin.access
                              - org-integration.manage
                              - audit.global.read
                              - directory.search
                              - project.read
                              - project.update
                              - project.delete
                              - project.members.manage
                              - project.events.read
                              - project.alerts.manage
                              - notebook.write
                              - notebook.manage
                              - integration.read
                              - integration.use
                              - integration.manage
                              - change-request.publish
                              - security-labels.raise
                              - security-labels.lower
                              - session.attach
                              - session.stop
                              - session.surface
                              - session.proxy
                              - session.start
                          uniqueItems: true
                    projects:
                      anyOf:
                        - type: string
                          enum:
                            - '*'
                        - type: array
                          items:
                            type: string
                            pattern: ^proj-[0-9a-z]{16}$
                          minItems: 1
                          maxItems: 100
                          uniqueItems: true
                  required:
                    - actions
                    - projects
                  additionalProperties: false
              required:
                - user_code
                - token_name
                - expires_in_days
                - grant
              additionalProperties: false
      responses:
        '200':
          description: Device authorization approved
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    enum:
                      - true
                  data:
                    type: object
                    properties:
                      expires_at:
                        type: string
                        format: date-time
                    required:
                      - expires_at
                required:
                  - success
                  - data
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Access forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request body too large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Resource limit reached
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Service unavailable
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying.
                example: '5'
              required: true
              description: Seconds to wait before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
webhooks: {}
