openapi: 3.1.0
info:
  title: ThruWire API Service
  description: 'ThruWire is a hybrid intelligence platform for building

    versioned, executable reasoning graphs. The API enables

    programmatic access to projects, versions, blocks,

    compilation workflows, and agent execution streams.'
  version: 0.1.0
  contact:
    name: ThruWire developer support
    email: hello@thruwire.ai
    url: https://thruwire.ai/contact
  x-deprecation-policy: https://thruwire.ai/developers/versioning
  x-logo:
    url: https://thruwire.ai/Thruwire-300.png
    altText: ThruWire
externalDocs:
  description: ThruWire developer portal
  url: https://thruwire.ai/developers
x-mcp:
  endpoint: https://api.thruwire.ai/mcp
  transport: streamable-http
  authorizationMetadata: https://api.thruwire.ai/.well-known/oauth-authorization-server
  requiredScopes:
  - mcp
tags:
- name: Auth
  description: Exchange a ThruWire identity token for API access.
- name: User
  description: Read and update state associated with the authenticated user.
- name: Projects
  description: Create and manage projects, members, and version snapshots.
- name: Blocks
  description: Read, write, structure, and execute blocks in a project graph.
- name: Schemas
  description: Discover typed block and artifact schemas.
- name: Compile
  description: Compile a project graph and stream compilation events.
paths:
  /api/v1/healthz:
    get:
      tags:
      - User
      summary: Healthz
      operationId: healthz_api_v1_healthz_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security: []
      x-internal: true
  /api/v1/login:
    post:
      tags:
      - Auth
      summary: Login
      description: 'Verify a Thruwire auth token.


        Obtain an ID token from auth.thruwire.ai, then pass it in the request body.'
      operationId: login_api_v1_login_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            example:
              id_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
              example:
                user_id: user_123
                default_project_id: b3f1c6a8-7f4a-4e3d-9b8b-2e5f9c0a1234
                email: user@example.com
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security: []
  /api/v1/user/current-project:
    get:
      tags:
      - User
      summary: Get Current Project
      description: Return the project currently selected by the authenticated user.
      operationId: get_current_project_api_v1_user_current_project_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrentProjectResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    put:
      tags:
      - User
      summary: Set Current Project
      description: Set the authenticated user's current project and return the updated selection.
      operationId: set_current_project_api_v1_user_current_project_put
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CurrentProjectRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrentProjectResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/members:
    post:
      tags:
      - Projects
      summary: Add Project Member
      description: Add an email address to the project's membership list.
      operationId: add_project_member_api_v1_projects__project_id__members_post
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddProjectMemberRequest'
            example:
              email: member@example.com
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                status: ok
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    get:
      tags:
      - Projects
      summary: List Project Members
      description: List the email addresses that have access to the project.
      operationId: list_project_members_api_v1_projects__project_id__members_get
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProjectMemberEmailResponse'
              example:
              - email: member@example.com
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      tags:
      - Projects
      summary: Remove Project Member
      description: Remove an email address from the project's membership list.
      operationId: remove_project_member_api_v1_projects__project_id__members_delete
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RemoveProjectMemberRequest'
            example:
              email: member@example.com
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
              example:
                status: ok
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/config:
    get:
      tags:
      - User
      summary: Config
      operationId: config_api_v1_config_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConsoleConfigResponse'
              example:
                firebase_project_id: thruwire-prod
                firebase_api_key: api-key
                firebase_auth_domain: auth.thruwire.ai
                firebase_storage_bucket: bucket
                firebase_messaging_sender_id: sender
                firebase_app_id: app-id
                firebase_measurement_id: measurement-id
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/projects:
    get:
      tags:
      - Projects
      summary: List Projects
      description: List projects visible to the authenticated user with offset-based pagination.
      operationId: list_projects_projects_get
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 200
          minimum: 1
          default: 50
          title: Limit
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          minimum: 0
          default: 0
          title: Offset
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectListResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      tags:
      - Projects
      summary: Create Project
      description: Create a project owned by the authenticated user.
      operationId: create_project_projects_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProjectCreateRequest'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}:
    put:
      tags:
      - Projects
      summary: Update Project
      description: Update a project (currently only supports renaming).
      operationId: update_project_projects__project_id__put
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProjectUpdateRequest'
            example:
              name: Renamed Project
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
              example:
                id: b3f1c6a8-7f4a-4e3d-9b8b-2e5f9c0a1234
                name: Renamed Project
                created_at: '2026-02-23T12:00:00Z'
                updated_at: '2026-02-23T12:00:00Z'
                status: active
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    get:
      tags:
      - Projects
      summary: Get Project
      description: Return project metadata.
      operationId: get_project_projects__project_id__get
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
              example:
                id: b3f1c6a8-7f4a-4e3d-9b8b-2e5f9c0a1234
                name: Demo Project
                created_at: '2026-02-23T12:00:00Z'
                updated_at: '2026-02-23T12:00:00Z'
                status: active
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      tags:
      - Projects
      summary: Delete Project
      description: Delete a project and all its associated data (versions, blocks,
        etc.).
      operationId: delete_project_projects__project_id__delete
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      responses:
        '204':
          description: Successful Response
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/versions/{version_id}/blocks:
    get:
      tags:
      - Blocks
      summary: List Blocks
      description: List blocks for a version and state.
      operationId: list_blocks_projects__project_id__versions__version_id__blocks_get
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: version_id
        in: path
        required: true
        schema:
          type: string
          title: Version Id
      - name: state
        in: query
        required: false
        schema:
          $ref: '#/components/schemas/BlockState'
          description: raw | compiled
          default: raw
        description: raw | compiled
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 200
          minimum: 1
          default: 50
          title: Limit
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          minimum: 0
          default: 0
          title: Offset
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlocksResponse'
              example:
                items:
                - id: overview
                  state: raw
                  updated_at: '2026-02-23T12:00:00Z'
                  size: 120
                - id: overview
                  state: compiled
                  updated_at: '2026-02-23T12:05:00Z'
                  size: 200
                pagination:
                  total: 2
                  limit: 50
                  offset: 0
                  count: 2
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/versions/{version_id}/blocks/{block_id}:
    get:
      tags:
      - Blocks
      summary: Get Block
      description: Get a block for a version and state.
      operationId: get_block_projects__project_id__versions__version_id__blocks__block_id__get
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: version_id
        in: path
        required: true
        schema:
          type: string
          title: Version Id
      - name: block_id
        in: path
        required: true
        schema:
          type: string
          title: Block Id
      - name: state
        in: query
        required: false
        schema:
          $ref: '#/components/schemas/BlockState'
          default: raw
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlockResponse'
              examples:
                raw:
                  summary: Raw block
                  value:
                    metadata:
                      id: overview
                      state: raw
                      updated_at: '2026-02-23T12:00:00Z'
                      size: 120
                    block:
                      name: Overview
                      body: '# Hello'
                compiled:
                  summary: Compiled block
                  value:
                    metadata:
                      id: overview
                      state: compiled
                      updated_at: '2026-02-23T12:10:00Z'
                      size: 200
                    compiled:
                      block:
                        name: Overview
                        body: '# Hello'
                      runtimes:
                        builder:
                          steps:
                          - id: summarize
                            name: Summarize
                            type: llm
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/versions/latest/blocks/{block_id}:
    put:
      tags:
      - Blocks
      summary: Write Block
      description: Write a raw block to the working set.
      operationId: write_block_projects__project_id__versions_latest_blocks__block_id__put
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: block_id
        in: path
        required: true
        schema:
          type: string
          description: Block identifier (lowercase, hyphen-separated)
          title: Block Id
        description: Block identifier (lowercase, hyphen-separated)
      - name: X-Expected-Revision
        in: header
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          title: X-Expected-Revision
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BlockWriteRequest'
            example:
              block:
                name: Overview
                body: '# Hello'
              expected_revision: 12
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlockMetadataResponse'
              example:
                metadata:
                  id: overview
                  state: raw
                  updated_at: '2026-02-23T12:00:00Z'
                  size: 120
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      tags:
      - Blocks
      summary: Delete Block
      description: Delete a raw block from the working set.
      operationId: delete_block_projects__project_id__versions_latest_blocks__block_id__delete
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: block_id
        in: path
        required: true
        schema:
          type: string
          title: Block Id
      - name: X-Expected-Revision
        in: header
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          title: X-Expected-Revision
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Body_delete_block_projects__project_id__versions_latest_blocks__block_id__delete'
            example:
              expected_revision: 12
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RevisionOnlyResponse'
              example:
                status: deleted
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/versions/latest/blocks/rename:
    post:
      tags:
      - Blocks
      summary: Rename Block
      description: Rename a raw block in the working set.
      operationId: rename_block_projects__project_id__versions_latest_blocks_rename_post
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: X-Expected-Revision
        in: header
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          title: X-Expected-Revision
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RenameBlockRequest'
            example:
              old_id: overview
              new_id: introduction
              expected_revision: 12
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BlockMetadataResponse'
              example:
                metadata:
                  id: introduction
                  state: raw
                  updated_at: '2026-02-23T12:00:00Z'
                  size: 120
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/versions:
    get:
      tags:
      - Projects
      summary: List Versions
      description: List version snapshots for a project with offset-based pagination.
      operationId: list_versions_projects__project_id__versions_get
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 200
          minimum: 1
          default: 50
          title: Limit
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          minimum: 0
          default: 0
          title: Offset
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionListResponse'
              example:
                items:
                - id: 1b2c3d4e-1111-2222-3333-444455556666
                  name: v3
                  status: compiled
                  created_at: '2026-02-23T12:00:00Z'
                  completed_at: '2026-02-23T12:10:00Z'
                pagination:
                  total: 2
                  limit: 50
                  offset: 0
                  count: 2
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    post:
      tags:
      - Projects
      summary: Create Version
      description: Create a new version by snapshotting the working set.
      operationId: create_version_projects__project_id__versions_post
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: X-Expected-Revision
        in: header
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          title: X-Expected-Revision
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionResponse'
              example:
                version:
                  id: 1b2c3d4e-1111-2222-3333-444455556666
                  name: v3
                  status: draft
                  created_at: '2026-02-23T12:00:00Z'
                  completed_at: null
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/projects/{project_id}/versions/{version_id}:
    get:
      tags:
      - Projects
      summary: Get Version
      description: Return one version snapshot and its current lifecycle state.
      operationId: get_version_projects__project_id__versions__version_id__get
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: version_id
        in: path
        required: true
        schema:
          type: string
          title: Version Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Version'
              example:
                id: 1b2c3d4e-1111-2222-3333-444455556666
                name: v3
                status: compiled
                created_at: '2026-02-23T12:00:00Z'
                completed_at: '2026-02-23T12:10:00Z'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
    delete:
      tags:
      - Projects
      summary: Delete Version
      operationId: delete_version_projects__project_id__versions__version_id__delete
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: version_id
        in: path
        required: true
        schema:
          type: string
          title: Version Id
      responses:
        '204':
          description: Successful Response
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/projects/{project_id}/versions/{version_id}/status:
    put:
      tags:
      - Projects
      summary: Update Version Status
      description: Update version status for a snapshot.
      operationId: update_version_status_projects__project_id__versions__version_id__status_put
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: version_id
        in: path
        required: true
        schema:
          type: string
          title: Version Id
      - name: X-Expected-Revision
        in: header
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          title: X-Expected-Revision
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Body_update_version_status_projects__project_id__versions__version_id__status_put'
            example:
              status: compiled
              compiler_version: thruwire-compiler-1.0.0
              expected_revision: 12
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionResponse'
              example:
                version:
                  id: 1b2c3d4e-1111-2222-3333-444455556666
                  name: v3
                  status: compiled
                  created_at: '2026-02-23T12:00:00Z'
                  completed_at: '2026-02-23T12:10:00Z'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/projects/{project_id}/blocks/{block_id}/execute:
    post:
      tags:
      - Blocks
      summary: Exectute Block
      description: Execute a compiled block and stream results via server-sent events.
      operationId: api_execute_block_projects__project_id__blocks__block_id__execute_post
      security:
      - bearerAuth: []
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: block_id
        in: path
        required: true
        schema:
          type: string
          title: Block Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecuteRequest'
            example:
              context:
                prompt: Do the thing
              inputs:
                foo: bar
      responses:
        '200':
          description: Successful Response
          content:
            text/event-stream:
              schema:
                type: string
                description: UTF-8 server-sent event stream containing control, narrative, artifact, result, or error events.
              examples:
                stream:
                  value: 'data: {"channel":"control","data":{"type":"run_started"}}

                    data: {"channel":"narrative","data":{"event":"start","narrative_id":"narrative-1","block_id":"overview","step_id":"step-1"}}

                    data: {"channel":"narrative","data":{"event":"delta","narrative_id":"narrative-1","delta":"Thinking
                    through the next step."}}

                    data: {"channel":"narrative","data":{"event":"end","narrative_id":"narrative-1"}}


                    data: {"channel":"artifact","data":{"event":"start","id":"artifact-1"}}

                    data: {"channel":"artifact","data":{"event":"delta","id":"artifact-1","content":"Hello"}}

                    data: {"channel":"artifact","data":{"event":"end","id":"artifact-1"}}

                    data: {"channel":"result","data":{"event":"delta","content":"Hel"}}

                    data: {"channel":"result","data":{"event":"delta","content":"lo"}}

                    data: {"channel":"result","data":{"event":"done","content":{"text":"Hello"}}}

                    event: error

                    data: {"error":{"code":"EXECUTION_ERROR","message":"Boom","details":{}}}


                    data: {"channel":"control","data":{"type":"run_completed"}}

                    '
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/blocks/{block_id}/structure:
    post:
      tags:
      - Blocks
      summary: Structure Block
      description: Generate or refine block structure and stream results via server-sent
        events.
      operationId: api_structure_block_projects__project_id__blocks__block_id__structure_post
      security:
      - bearerAuth: []
      parameters:
      - name: project_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
          title: Project Id
      - name: block_id
        in: path
        required: true
        schema:
          type: string
          title: Block Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StructureRequest'
            example:
              profile: refine_structure
              inputs:
                topic: demo
      responses:
        '200':
          description: Successful Response
          content:
            text/event-stream:
              schema:
                type: string
                description: UTF-8 server-sent event stream containing structure, narrative, action, or error events.
              examples:
                stream:
                  value: 'data: {"channel":"control","data":{"type":"structure_started"}}

                    data: {"channel":"narrative","data":{"event":"start","narrative_id":"narrative-1","block_id":"overview","step_id":"step-1"}}

                    data: {"channel":"narrative","data":{"event":"delta","narrative_id":"narrative-1","delta":"Planning
                    structure adjustments."}}

                    data: {"channel":"narrative","data":{"event":"end","narrative_id":"narrative-1"}}

                    data: {"channel":"action","data":{"action_id":"action-1","type":"create_block","block_path":"new-notebook","payload":{"name":"New
                    Notebook","goals":["Summarize the topic"],"context":{"topic":"demo"},"steps":[{"text":"Draft
                    outline"},{"text":"Write summary"}],"ancestors":[]}}}

                    data: {"channel":"action","data":{"action_id":"action-2","type":"update_block","block_path":"overview","payload":{"name":"Overview","goals":["Refine
                    structure"],"context":{},"steps":[{"text":"Update intro"}],"ancestors":[]}}}

                    data: {"channel":"action","data":{"action_id":"action-3","type":"rename_block","block_path":"introduction","payload":{"old_path":"overview","new_path":"introduction","new_name":"Introduction"}}}

                    data: {"channel":"action","data":{"action_id":"action-4","type":"create_block","block_path":"static-checklist","payload":{"name":"Static
                    Checklist","goals":[],"context":{"source":"static"},"steps":[{"text":"Capture
                    must-have items"}],"ancestors":[]}}}

                    data: {"channel":"action","data":{"action_id":"action-5","type":"update_block","block_path":"static-checklist","payload":{"name":"Static
                    Checklist","goals":[],"context":{"source":"static","revision":"bump"},"steps":[{"text":"Refresh
                    checklist"}],"ancestors":[]}}}


                    event: error

                    data: {"error":{"code":"EXECUTION_ERROR","message":"Boom","details":{}}}


                    data: {"channel":"control","data":{"type":"structure_completed"}}

                    '
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/agent/health:
    get:
      tags:
      - User
      summary: Api Health Check
      description: Health check endpoint accessible via ingress.
      operationId: api_health_check_health_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthStatus'
              example:
                status: healthy
                service: agent-framework
                mcp_ready: true
                tool_count: 12
                agents_ready: true
                background_init: false
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/agent/performance:
    get:
      tags:
      - User
      summary: Api Performance Metrics
      description: Get performance metrics for monitoring (via ingress).
      operationId: api_performance_metrics_performance_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PerformanceMetrics'
              example:
                active_agents: 3
                agent_configs_cache_age: 12.3
                pubsub_running: true
                initialization_successful: true
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
      - bearerAuth: []
      x-internal: true
  /api/v1/agent/runs:
    get:
      tags:
      - User
      summary: Api List Runs
      description: List recorded runs ordered by creation time (newest first).
      operationId: api_list_runs_runs_get
      security:
      - bearerAuth: []
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          default: 50
          title: Limit
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          default: 0
          title: Offset
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunListResponse'
              example:
                items: []
                pagination:
                  total: 0
                  limit: 50
                  offset: 0
                  count: 0
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/agent/runs/{run_id}:
    get:
      tags:
      - User
      summary: Api Get Run
      description: Return run metadata and optional trace payload.
      operationId: api_get_run_runs__run_id__get
      security:
      - bearerAuth: []
      parameters:
      - name: run_id
        in: path
        required: true
        schema:
          type: string
          title: Run Id
      - name: include_trace
        in: query
        required: false
        schema:
          type: boolean
          default: true
          title: Include Trace
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunDetailResponse'
              example:
                run:
                  id: run-123
                trace: null
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/agent/runs/{run_id}/assets/{asset_path}:
    get:
      tags:
      - User
      summary: Api Stream Run Asset
      description: Stream an asset referenced within a run trace.
      operationId: api_stream_run_asset_runs__run_id__assets__asset_path__get
      security:
      - bearerAuth: []
      parameters:
      - name: run_id
        in: path
        required: true
        schema:
          type: string
          title: Run Id
      - name: asset_path
        in: path
        required: true
        schema:
          type: string
          title: Asset Path
      responses:
        '200':
          description: Successful Response
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      x-internal: true
  /api/v1/schemas:
    get:
      tags:
      - Schemas
      summary: List Schemas
      description: List the schemas available for typed blocks and artifacts.
      operationId: list_schemas_schemas_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaListResponse'
              example:
                schemas:
                - schema:
                    name: block
                    version: 1.0.0
                  runtimes: {}
                  fields: {}
                  ui: {}
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/schemas/{schema_ref}:
    get:
      tags:
      - Schemas
      summary: Get Schema
      description: Return the schema payload identified by the supplied schema reference.
      operationId: get_schema_schemas__schema_ref__get
      parameters:
      - name: schema_ref
        in: path
        required: true
        schema:
          type: string
          title: Schema Ref
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaPayload'
              example:
                schema:
                  name: block
                  version: 1.0.0
                runtimes: {}
                fields: {}
                ui: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
  /api/v1/projects/{project_id}/compile:
    post:
      tags:
      - Compile
      summary: Compile
      description: Compile a project and stream results via server-sent events.
      operationId: compile_project
      security:
      - bearerAuth: []
      parameters:
      - name: rebuild_only
        in: query
        required: false
        schema:
          type: boolean
          description: If true, rebuild DAG and block definitions without creating
            a new version. Requires version_id.
          default: false
          title: Rebuild Only
        description: If true, rebuild DAG and block definitions without creating a
          new version. Requires version_id.
      - name: version_id
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Version ID to rebuild. Required if rebuild_only=true.
          oneOf:
          - type: string
            format: uuid
          - type: string
            enum:
            - latest
            - current
          title: Version Id
        description: Version ID to rebuild. Required if rebuild_only=true.
      responses:
        '200':
          description: Successful Response
          content:
            text/event-stream:
              schema:
                type: string
                description: UTF-8 server-sent event stream containing compilation lifecycle and error events.
              examples:
                stream:
                  value: 'event: started

                    data: {"project_id":"b3f1c6a8-7f4a-4e3d-9b8b-2e5f9c0a1234","message":"Compile
                    started"}


                    event: error

                    data: {"error":{"code":"COMPILE_ERROR","message":"Boom","details":{}}}


                    event: completed

                    data: {"version_id":"1b2c3d4e-1111-2222-3333-444455556666"}

                    '
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: ThruWire bearer token. Send it only in the Authorization header; project membership limits access to protected resources.
      x-permissions:
      - projects:read
      - projects:write
      - projects:admin
      - blocks:read
      - blocks:write
      - blocks:execute
    mcpOAuth:
      type: oauth2
      description: OAuth 2.1-compatible authorization for the ThruWire MCP Streamable HTTP endpoint.
      flows:
        authorizationCode:
          authorizationUrl: https://api.thruwire.ai/api/v1/oauth/authorize
          tokenUrl: https://api.thruwire.ai/api/v1/oauth/token
          refreshUrl: https://api.thruwire.ai/api/v1/oauth/token
          scopes:
            mcp: Connect to the ThruWire MCP server and call authorized tools and resources.
        clientCredentials:
          tokenUrl: https://api.thruwire.ai/api/v1/oauth/token
          scopes:
            mcp: Connect to the ThruWire MCP server and call authorized tools and resources.
  headers:
    RateLimit:
      description: Current quota limit, remaining quota, and reset time when supplied by the service.
      schema:
        type: string
    RateLimitPolicy:
      description: Policy governing the quota advertised in RateLimit when supplied by the service.
      schema:
        type: string
    RetryAfter:
      description: Delay in seconds or HTTP date after which the client may retry a throttled request.
      schema:
        type: string
  schemas:
    AddProjectMemberRequest:
      properties:
        email:
          type: string
          title: Email
      type: object
      required:
      - email
      title: AddProjectMemberRequest
    ConsoleConfigResponse:
      properties:
        firebase_project_id:
          type: string
          title: Firebase Project Id
        firebase_api_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Firebase Api Key
        firebase_auth_domain:
          anyOf:
          - type: string
          - type: 'null'
          title: Firebase Auth Domain
        firebase_storage_bucket:
          anyOf:
          - type: string
          - type: 'null'
          title: Firebase Storage Bucket
        firebase_messaging_sender_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Firebase Messaging Sender Id
        firebase_app_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Firebase App Id
        firebase_measurement_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Firebase Measurement Id
      type: object
      required:
      - firebase_project_id
      - firebase_api_key
      - firebase_auth_domain
      - firebase_storage_bucket
      - firebase_messaging_sender_id
      - firebase_app_id
      - firebase_measurement_id
      title: ConsoleConfigResponse
    CurrentProjectRequest:
      properties:
        project_id:
          type: string
          format: uuid
          title: Project Id
      type: object
      required:
      - project_id
      title: CurrentProjectRequest
    CurrentProjectResponse:
      properties:
        project_id:
          anyOf:
          - type: string
            format: uuid
          - type: 'null'
          title: Project Id
      type: object
      required:
      - project_id
      title: CurrentProjectResponse
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    LoginRequest:
      properties:
        id_token:
          type: string
          title: Id Token
          description: Thruwire auth token
      type: object
      required:
      - id_token
      title: LoginRequest
    LoginResponse:
      properties:
        user_id:
          type: string
          title: User Id
        default_project_id:
          anyOf:
          - type: string
            format: uuid
          - type: 'null'
          title: Default Project Id
        email:
          anyOf:
          - type: string
          - type: 'null'
          title: Email
      type: object
      required:
      - user_id
      - default_project_id
      - email
      title: LoginResponse
    Pagination:
      properties:
        total:
          type: integer
          title: Total
        limit:
          type: integer
          title: Limit
        offset:
          type: integer
          title: Offset
        count:
          type: integer
          title: Count
      type: object
      required:
      - total
      - limit
      - offset
      - count
      title: Pagination
    Project:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        name:
          type: string
          title: Name
        created_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Created At
        updated_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Updated At
        status:
          type: string
          title: Status
          default: active
      type: object
      required:
      - id
      - name
      title: Project
    ProjectCreateRequest:
      properties:
        name:
          anyOf:
          - type: string
          - type: 'null'
          title: Name
      type: object
      title: ProjectCreateRequest
    ProjectListResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/ProjectSummary'
          type: array
          title: Items
        pagination:
          $ref: '#/components/schemas/Pagination'
      type: object
      required:
      - items
      - pagination
      title: ProjectListResponse
    ProjectMemberEmailResponse:
      properties:
        email:
          type: string
          title: Email
      type: object
      required:
      - email
      title: ProjectMemberEmailResponse
    ProjectSummary:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        name:
          type: string
          title: Name
        created_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Created At
        updated_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Updated At
        status:
          type: string
          title: Status
          default: active
      type: object
      required:
      - id
      - name
      title: ProjectSummary
    RemoveProjectMemberRequest:
      properties:
        email:
          type: string
          title: Email
      type: object
      required:
      - email
      title: RemoveProjectMemberRequest
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    BlockMetadata:
      properties:
        id:
          type: string
          pattern: ^[a-z0-9\-]+$
          title: Id
        state:
          $ref: '#/components/schemas/BlockState'
        updated_at:
          type: string
          format: date-time
          title: Updated At
        size:
          type: integer
          title: Size
      type: object
      required:
      - id
      - state
      - updated_at
      - size
      title: BlockMetadata
    BlockMetadataResponse:
      properties:
        metadata:
          $ref: '#/components/schemas/BlockMetadata'
      type: object
      required:
      - metadata
      title: BlockMetadataResponse
    BlockResponse:
      properties:
        metadata:
          $ref: '#/components/schemas/BlockMetadata'
        block:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Block
          description: Structured raw block definition
        compiled:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Compiled
          description: Structured compiled block artifact
      type: object
      required:
      - metadata
      title: BlockResponse
    BlockState:
      type: string
      enum:
      - raw
      - compiled
      title: BlockState
    BlockWriteRequest:
      properties:
        block:
          additionalProperties: true
          type: object
          title: Block
          description: Structured block definition as JSON
        expected_revision:
          anyOf:
          - type: integer
          - type: 'null'
          title: Expected Revision
      type: object
      required:
      - block
      title: BlockWriteRequest
    BlocksResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/BlockMetadata'
          type: array
          title: Items
        pagination:
          $ref: '#/components/schemas/Pagination'
        revision:
          anyOf:
          - type: integer
          - type: 'null'
          title: Revision
      type: object
      required:
      - items
      - pagination
      title: BlocksResponse
    Body_delete_block_projects__project_id__versions_latest_blocks__block_id__delete:
      properties:
        expected_revision:
          anyOf:
          - type: integer
          - type: 'null'
          title: Expected Revision
      type: object
      title: Body_delete_block_projects__project_id__versions_latest_blocks__block_id__delete
    Body_update_version_status_projects__project_id__versions__version_id__status_put:
      properties:
        status:
          type: string
          title: Status
        compiler_version:
          anyOf:
          - type: string
          - type: 'null'
          title: Compiler Version
        expected_revision:
          anyOf:
          - type: integer
          - type: 'null'
          title: Expected Revision
      type: object
      required:
      - status
      title: Body_update_version_status_projects__project_id__versions__version_id__status_put
    CompiledWriteRequest:
      properties:
        compiled:
          additionalProperties: true
          type: object
          title: Compiled
          description: Structured compiled block artifact as JSON
        expected_revision:
          anyOf:
          - type: integer
          - type: 'null'
          title: Expected Revision
      type: object
      required:
      - compiled
      title: CompiledWriteRequest
    ProjectMemberResponse:
      properties:
        user_id:
          type: string
          title: User Id
      type: object
      required:
      - user_id
      title: ProjectMemberResponse
    ProjectUpdateRequest:
      properties:
        name:
          type: string
          title: Name
      type: object
      required:
      - name
      title: ProjectUpdateRequest
    RenameBlockRequest:
      properties:
        old_id:
          type: string
          pattern: ^[a-z0-9\-]+$
          title: Old Id
        new_id:
          type: string
          pattern: ^[a-z0-9\-]+$
          title: New Id
        expected_revision:
          anyOf:
          - type: integer
          - type: 'null'
          title: Expected Revision
      type: object
      required:
      - old_id
      - new_id
      title: RenameBlockRequest
    RevisionOnlyResponse:
      properties:
        status:
          anyOf:
          - type: string
          - type: 'null'
          title: Status
      type: object
      title: RevisionOnlyResponse
    SnapshotRawResponse:
      properties:
        status:
          type: string
          title: Status
        raw_count:
          type: integer
          title: Raw Count
        deleted_count:
          type: integer
          title: Deleted Count
      type: object
      required:
      - status
      - raw_count
      - deleted_count
      title: SnapshotRawResponse
    Tenant:
      properties:
        id:
          type: string
          title: Id
        name:
          type: string
          title: Name
        owner_email:
          type: string
          title: Owner Email
        created_at:
          type: string
          format: date-time
          title: Created At
      type: object
      required:
      - id
      - name
      - owner_email
      - created_at
      title: Tenant
    TenantCreateRequest:
      properties:
        name:
          type: string
          title: Name
        owner_email:
          type: string
          title: Owner Email
      type: object
      required:
      - name
      - owner_email
      title: TenantCreateRequest
    Version:
      properties:
        id:
          type: string
          title: Id
        name:
          type: string
          title: Name
        status:
          $ref: '#/components/schemas/VersionStatus'
        created_at:
          type: string
          format: date-time
          title: Created At
        completed_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Completed At
      type: object
      required:
      - id
      - name
      - status
      - created_at
      title: Version
    VersionIdResponse:
      properties:
        version_id:
          type: string
          title: Version Id
      type: object
      required:
      - version_id
      title: VersionIdResponse
    VersionListResponse:
      properties:
        items:
          items:
            $ref: '#/components/schemas/Version'
          type: array
          title: Items
        pagination:
          $ref: '#/components/schemas/Pagination'
      type: object
      required:
      - items
      - pagination
      title: VersionListResponse
    VersionResponse:
      properties:
        version:
          $ref: '#/components/schemas/Version'
      type: object
      required:
      - version
      title: VersionResponse
    VersionStatus:
      type: string
      enum:
      - draft
      - compiled
      - active
      - archived
      title: VersionStatus
    WriteAck:
      properties:
        id:
          type: string
          title: Id
        status:
          type: string
          title: Status
      type: object
      required:
      - id
      - status
      title: WriteAck
    ExecuteRequest:
      properties:
        context:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Context
        inputs:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Inputs
      type: object
      title: ExecuteRequest
      description: Execute request payload for block runs.
    HealthStatus:
      properties:
        status:
          type: string
          title: Status
        service:
          type: string
          title: Service
        mcp_ready:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Mcp Ready
        tool_count:
          anyOf:
          - type: integer
          - type: 'null'
          title: Tool Count
        agents_ready:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Agents Ready
        background_init:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Background Init
        error:
          anyOf:
          - type: string
          - type: 'null'
          title: Error
      type: object
      required:
      - status
      - service
      title: HealthStatus
    PerformanceMetrics:
      properties:
        active_agents:
          type: integer
          title: Active Agents
        agent_configs_cache_age:
          type: number
          title: Agent Configs Cache Age
        pubsub_running:
          type: boolean
          title: Pubsub Running
        initialization_successful:
          type: boolean
          title: Initialization Successful
      type: object
      required:
      - active_agents
      - agent_configs_cache_age
      - pubsub_running
      - initialization_successful
      title: PerformanceMetrics
    StructureRequest:
      properties:
        context:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Context
        inputs:
          anyOf:
          - additionalProperties: true
            type: object
          - type: 'null'
          title: Inputs
        profile:
          anyOf:
          - type: string
          - type: 'null'
          title: Profile
          description: Scaffolding profile. Use build_foundation, refine_structure,
            or explore_adjacent.
      type: object
      title: StructureRequest
      description: Structure request payload for scaffolding runs.
    RunDetailResponse:
      properties:
        run:
          additionalProperties: true
          type: object
          title: Run
        trace:
          anyOf:
          - items:
              additionalProperties: true
              type: object
            type: array
          - type: 'null'
          title: Trace
      type: object
      required:
      - run
      title: RunDetailResponse
    RunListResponse:
      properties:
        items:
          items:
            additionalProperties: true
            type: object
          type: array
          title: Items
        pagination:
          $ref: '#/components/schemas/Pagination'
      type: object
      required:
      - items
      - pagination
      title: RunListResponse
    SchemaListResponse:
      properties:
        schemas:
          items:
            $ref: '#/components/schemas/SchemaPayload'
          type: array
          title: Schemas
      type: object
      required:
      - schemas
      title: SchemaListResponse
    SchemaMeta:
      properties:
        name:
          anyOf:
          - type: string
          - type: 'null'
          title: Name
        version:
          anyOf:
          - type: string
          - type: 'null'
          title: Version
      type: object
      title: SchemaMeta
    SchemaPayload:
      properties:
        schema:
          $ref: '#/components/schemas/SchemaMeta'
        runtimes:
          anyOf:
          - additionalProperties: true
            type: object
          - items:
              type: string
            type: array
          title: Runtimes
        fields:
          additionalProperties: true
          type: object
          title: Fields
        ui:
          additionalProperties: true
          type: object
          title: Ui
      type: object
      required:
      - schema
      title: SchemaPayload
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          properties:
            code:
              type: string
            message:
              type: string
            details:
              type: object
              additionalProperties: true
  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Conflict:
      description: Conflict
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooManyRequests:
      description: Rate limited
      headers:
        RateLimit:
          $ref: '#/components/headers/RateLimit'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
servers:
- url: https://api.thruwire.ai
security:
- bearerAuth: []
