openapi: 3.1.0
info:
  title: Aginera Takeoff & Estimation API
  version: 1.0.0-rc.1
  description: |-
    REST surface of the Aginera Developer Platform — structured construction quantities, routes and schedules.

    The Aginera Developer Platform exposes the same capabilities through MCP (for agents, at https://mcp.aginera.ai) and this REST API (for backend integrations). Both call the same services, so results, permissions and billing are identical.

    **Versioning.** This document describes `v1` (contract 1.0.0-rc.1, status **current**). Additive changes are non-breaking; breaking changes ship as a new path version with a 12-month overlap and `Deprecation`/`Sunset` headers.

    **Authentication.** OAuth 2.0: backends use client credentials (token URL shown in your portal); agents and humans use authorization code + PKCE via https://auth.aginera.ai. Send `Authorization: Bearer <token>`.

    **Long-running operations** return `202 Accepted` with a job resource; poll `GET` or register a webhook. **Errors** are RFC 7807 `application/problem+json` with a stable `code`.

    Each operation carries `x-aginera-cut`: `core` (first release), `beta`, or `commercial` (later).
  termsOfService: https://aginera.ai/legal/developer-terms
  contact:
    name: Aginera Developer Support
    email: developers@aginera.ai
    url: https://aginera.ai/docs/developer
  license:
    name: Proprietary — Aginera Developer Platform Terms
    url: https://aginera.ai/legal/developer-terms
servers:
  - url: https://api.aginera.ai/partner/v1
    description: Production and sandbox (environment is per credential)
security:
  - oauth2: []
tags:
  - name: Projects
    description: Foundation — containers for documents and takeoffs.
  - name: Documents
    description: Foundation — drawing ingestion.
  - name: Takeoffs
    description: Takeoff API — run MEP quantity takeoffs and read items, routes and schedules.
  - name: Exports
    description: Takeoff API — export results.
  - name: Estimates
    description: Estimation API (commercial cut).
  - name: Billing
    description: Account — credits.
  - name: Usage
    description: Account — usage reporting.
  - name: Webhooks
    description: Account — webhook endpoints (beta cut).
  - name: Events
    description: Account — event log (beta cut).
  - name: Clients
    description: Account — the calling credential and capabilities.
  - name: Reference
    description: Public taxonomy and enumerations.
components:
  schemas:
    Problem:
      type: object
      properties:
        type:
          type: string
        title:
          type: string
        status:
          type: integer
        code:
          type: string
        detail:
          type: string
        request_id:
          type: string
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
            required:
              - field
              - message
        required_credits:
          type: number
        available_credits:
          type: number
        quota:
          type: string
        retry_after:
          type: integer
        next_step:
          type: string
      required:
        - type
        - title
        - status
        - code
        - detail
        - request_id
    ProjectId:
      type: string
      pattern: ^prj_[0-9A-Za-z]{22}$
      example: prj_4kR9sT2vWx7yZa1bCd3eFg
    Project:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/ProjectId"
        name:
          type: string
        reference:
          type:
            - string
            - "null"
        end_customer_ref:
          type:
            - string
            - "null"
        external_ref:
          type:
            - string
            - "null"
        address:
          type:
            - string
            - "null"
        metadata:
          type: object
          additionalProperties:
            type: string
        document_count:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type:
            - string
            - "null"
          format: date-time
      required:
        - id
        - name
        - reference
        - end_customer_ref
        - external_ref
        - address
        - metadata
        - document_count
        - created_at
        - updated_at
    Metadata:
      type: object
      additionalProperties:
        type: string
        maxLength: 500
    ProjectCreate:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        reference:
          type: string
          maxLength: 100
        end_customer_ref:
          type: string
          maxLength: 128
          description: Identifier of your customer, used in usage reports.
        external_ref:
          type: string
          minLength: 1
          maxLength: 128
          description: Your own identifier for this resource; unique per tenant.
        address:
          type: string
          maxLength: 500
        metadata:
          $ref: "#/components/schemas/Metadata"
      required:
        - name
      additionalProperties: false
    ProjectList:
      type: object
      properties:
        next_cursor:
          type:
            - string
            - "null"
        has_more:
          type: boolean
        data:
          type: array
          items:
            $ref: "#/components/schemas/Project"
      required:
        - next_cursor
        - has_more
        - data
    ProjectUpdate:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
        reference:
          type: string
          maxLength: 100
        end_customer_ref:
          type: string
          maxLength: 128
          description: Identifier of your customer, used in usage reports.
        external_ref:
          type: string
          minLength: 1
          maxLength: 128
          description: Your own identifier for this resource; unique per tenant.
        address:
          type: string
          maxLength: 500
        metadata:
          $ref: "#/components/schemas/Metadata"
      additionalProperties: false
    DocumentId:
      type: string
      pattern: ^doc_[0-9A-Za-z]{22}$
      example: doc_4kR9sT2vWx7yZa1bCd3eFg
    DocumentStatus:
      type: string
      enum:
        - awaiting_upload
        - ingesting
        - ready
        - failed
    Trade:
      type: string
      enum:
        - electrical
        - mechanical
        - plumbing
        - fire_protection
        - structural
        - architectural
        - civil
        - other
    DocumentPage:
      type: object
      properties:
        number:
          type: integer
        sheet_number:
          type:
            - string
            - "null"
        sheet_title:
          type:
            - string
            - "null"
        has_text:
          type: boolean
        rotation:
          type: integer
        size_pt:
          type: object
          properties:
            width:
              type: number
            height:
              type: number
          required:
            - width
            - height
          additionalProperties: false
        disciplines_detected:
          type: array
          items:
            $ref: "#/components/schemas/Trade"
      required:
        - number
        - sheet_number
        - sheet_title
        - has_text
        - rotation
        - size_pt
    Failure:
      type: object
      properties:
        code:
          type: string
          enum:
            - document_unreadable
            - unsupported_content
            - no_pages_selected
            - capacity
            - cancelled
            - internal
        message:
          type: string
      required:
        - code
        - message
    Document:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/DocumentId"
        project_id:
          $ref: "#/components/schemas/ProjectId"
        filename:
          type: string
        kind:
          type: string
          enum: &a1
            - drawing
            - specification
            - schedule
        status:
          $ref: "#/components/schemas/DocumentStatus"
        external_ref:
          type:
            - string
            - "null"
        page_count:
          type:
            - integer
            - "null"
        pages:
          type: array
          items:
            $ref: "#/components/schemas/DocumentPage"
        size_bytes:
          type:
            - integer
            - "null"
        failure:
          $ref: "#/components/schemas/Failure"
        metadata:
          type: object
          additionalProperties:
            type: string
        created_at:
          type: string
          format: date-time
        ready_at:
          type:
            - string
            - "null"
          format: date-time
        retain_until:
          type:
            - string
            - "null"
          format: date-time
      required:
        - id
        - project_id
        - filename
        - kind
        - status
        - external_ref
        - page_count
        - size_bytes
        - metadata
        - created_at
        - ready_at
        - retain_until
    DocumentWithUpload:
      type: object
      properties:
        document:
          $ref: "#/components/schemas/Document"
        upload:
          type: object
          properties:
            url:
              type: string
              format: uri
            method:
              type: string
              enum:
                - PUT
            headers:
              type: object
              additionalProperties:
                type: string
            expires_at:
              type: string
              format: date-time
          required:
            - url
            - method
            - headers
            - expires_at
      required:
        - document
        - upload
    Discipline:
      type: string
      enum:
        - electrical
        - mechanical
        - plumbing
        - fire_protection
        - multi_discipline
    DocumentCreate:
      type: object
      properties:
        project_id:
          $ref: "#/components/schemas/ProjectId"
        filename:
          type: string
          minLength: 1
          maxLength: 255
        source:
          oneOf:
            - type: object
              properties:
                type:
                  type: string
                  enum:
                    - url
                url:
                  type: string
                  maxLength: 2048
                  format: uri
              required:
                - type
                - url
              additionalProperties: false
            - type: object
              properties:
                type:
                  type: string
                  enum:
                    - upload
                size_bytes:
                  type: integer
                  exclusiveMinimum: 0
                content_type:
                  type: string
                  enum:
                    - application/pdf
                    - image/vnd.dwg
                    - application/dxf
                    - image/png
                    - image/jpeg
              required:
                - type
              additionalProperties: false
        kind:
          type: string
          enum: *a1
          default: drawing
        discipline_hint:
          $ref: "#/components/schemas/Discipline"
        external_ref:
          type: string
          minLength: 1
          maxLength: 128
          description: Your own identifier for this resource; unique per tenant.
        metadata:
          $ref: "#/components/schemas/Metadata"
      required:
        - project_id
        - filename
        - source
      additionalProperties: false
    DocumentList:
      type: object
      properties:
        next_cursor:
          type:
            - string
            - "null"
        has_more:
          type: boolean
        data:
          type: array
          items:
            $ref: "#/components/schemas/Document"
      required:
        - next_cursor
        - has_more
        - data
    TakeoffId:
      type: string
      pattern: ^tko_[0-9A-Za-z]{22}$
      example: tko_4kR9sT2vWx7yZa1bCd3eFg
    JobStatus:
      type: string
      enum:
        - queued
        - processing
        - completed
        - failed
        - cancelled
    Progress:
      type: object
      properties:
        percent:
          type: integer
          minimum: 0
          maximum: 100
        pages_processed:
          type: integer
        pages_total:
          type: integer
      required:
        - percent
    Warning:
      type: object
      properties:
        code:
          type: string
          enum:
            - discipline_mismatch
            - scanned_pages_low_quality
            - pages_skipped_no_content
            - no_items_found
            - partial_pages_failed
        message:
          type: string
        pages:
          type: array
          items:
            type: integer
      required:
        - code
        - message
    Takeoff:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/TakeoffId"
        document_id:
          $ref: "#/components/schemas/DocumentId"
        project_id:
          $ref: "#/components/schemas/ProjectId"
        discipline:
          $ref: "#/components/schemas/Discipline"
        status:
          $ref: "#/components/schemas/JobStatus"
        external_ref:
          type:
            - string
            - "null"
        progress:
          $ref: "#/components/schemas/Progress"
        queue_position:
          type: integer
        pages_requested:
          type: integer
        estimated_credits:
          type: number
          description: Maximum that will be charged; the final charge never exceeds it.
        result_summary:
          type: object
          properties:
            item_count:
              type: integer
            sheet_count:
              type: integer
            pages_processed:
              type: integer
            credits_charged:
              type: number
            route_count:
              type: integer
            schedule_count:
              type: integer
            by_trade:
              type: object
              additionalProperties:
                type: integer
          required:
            - item_count
            - sheet_count
            - credits_charged
        warnings:
          type: array
          items:
            $ref: "#/components/schemas/Warning"
        failure:
          $ref: "#/components/schemas/Failure"
        metadata:
          type: object
          additionalProperties:
            type: string
        created_at:
          type: string
          format: date-time
        started_at:
          type:
            - string
            - "null"
          format: date-time
        completed_at:
          type:
            - string
            - "null"
          format: date-time
      required:
        - id
        - document_id
        - project_id
        - discipline
        - status
        - external_ref
        - progress
        - pages_requested
        - estimated_credits
        - warnings
        - metadata
        - created_at
        - started_at
        - completed_at
    UnitSystemPref:
      type: string
      enum:
        - imperial
        - metric
        - as_drawn
      default: as_drawn
    TakeoffCreate:
      type: object
      properties:
        document_id:
          $ref: "#/components/schemas/DocumentId"
        discipline:
          $ref: "#/components/schemas/Discipline"
        pages:
          type: array
          items:
            type: integer
            minimum: 1
          maxItems: 500
          description: 1-based page numbers. Omit for all pages.
        scope:
          type: string
          enum:
            - full
            - pages
          default: full
        external_ref:
          type: string
          minLength: 1
          maxLength: 128
          description: Your own identifier for this resource; unique per tenant.
        options:
          type: object
          properties:
            include_schedules:
              type: boolean
              default: true
            units:
              $ref: "#/components/schemas/UnitSystemPref"
            depth:
              type: string
              enum:
                - standard
                - deep
              default: standard
          default: {}
          additionalProperties: false
        metadata:
          $ref: "#/components/schemas/Metadata"
      required:
        - document_id
        - discipline
      additionalProperties: false
    TakeoffList:
      type: object
      properties:
        next_cursor:
          type:
            - string
            - "null"
        has_more:
          type: boolean
        data:
          type: array
          items:
            $ref: "#/components/schemas/Takeoff"
      required:
        - next_cursor
        - has_more
        - data
    ItemId:
      type: string
      pattern: ^itm_[0-9A-Za-z]{22}$
      example: itm_4kR9sT2vWx7yZa1bCd3eFg
    MeasureType:
      type: string
      enum:
        - count
        - length
        - area
        - volume
        - weight
        - time
    Unit:
      type: string
      pattern: ^[A-Z0-9]{1,6}$
      description: Canonical unit code from /reference/units (extensible; not a closed enum). Examples EA, LF, FT, IN, SF, SY, CF, CY, LB, TON, HR, GAL, M, MM, M2, M3, KG, T, L, LS.
      example: LF
    NormPoint:
      type: array
      prefixItems:
        - type: number
          minimum: 0
          maximum: 1
        - type: number
          minimum: 0
          maximum: 1
    Scale:
      type: object
      properties:
        units_per_normalized_x:
          type: number
          description: Real-world units spanned by the full normalized page width.
        unit:
          $ref: "#/components/schemas/Unit"
        source:
          type: string
          enum:
            - title_block
            - scale_bar
            - declared
      required:
        - units_per_normalized_x
        - unit
        - source
    Geometry:
      oneOf:
        - type: object
          properties:
            type:
              type: string
              enum:
                - point
            page_number:
              type: integer
              minimum: 1
            coordinate_space:
              type: string
              enum:
                - page_normalized
            coordinates:
              $ref: "#/components/schemas/NormPoint"
          required:
            - type
            - page_number
            - coordinate_space
            - coordinates
        - type: object
          properties:
            type:
              type: string
              enum:
                - bbox
            page_number:
              type: integer
              minimum: 1
            coordinate_space:
              type: string
              enum:
                - page_normalized
            coordinates:
              type: array
              prefixItems:
                - type: number
                - type: number
                - type: number
                - type: number
          required:
            - type
            - page_number
            - coordinate_space
            - coordinates
        - type: object
          properties:
            type:
              type: string
              enum:
                - polyline
            page_number:
              type: integer
              minimum: 1
            coordinate_space:
              type: string
              enum:
                - page_normalized
            coordinates:
              type: array
              items:
                $ref: "#/components/schemas/NormPoint"
              minItems: 2
            scale:
              $ref: "#/components/schemas/Scale"
          required:
            - type
            - page_number
            - coordinate_space
            - coordinates
        - type: object
          properties:
            type:
              type: string
              enum:
                - polygon
            page_number:
              type: integer
              minimum: 1
            coordinate_space:
              type: string
              enum:
                - page_normalized
            coordinates:
              type: array
              items:
                $ref: "#/components/schemas/NormPoint"
              minItems: 3
            holes:
              type: array
              items:
                type: array
                items:
                  $ref: "#/components/schemas/NormPoint"
                minItems: 3
            scale:
              $ref: "#/components/schemas/Scale"
          required:
            - type
            - page_number
            - coordinate_space
            - coordinates
      description: Measured shape in page_normalized space (x, y in 0..1, origin top-left, page as displayed after rotation). bbox = [x_min, y_min, x_max, y_max].
    Evidence:
      type: object
      properties:
        page_number:
          type: integer
          minimum: 1
        bbox:
          type: array
          prefixItems:
            - type: number
            - type: number
            - type: number
            - type: number
          description: "[x_min, y_min, x_max, y_max] normalised to page size, origin top-left."
      required:
        - page_number
        - bbox
    ConfidenceBand:
      type: string
      enum:
        - high
        - medium
        - low
    ReviewStatus:
      type: string
      enum:
        - extracted
        - accepted
        - rejected
        - modified
    TakeoffItem:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/ItemId"
        takeoff_id:
          $ref: "#/components/schemas/TakeoffId"
        group_id:
          type:
            - string
            - "null"
        description:
          type: string
        trade:
          $ref: "#/components/schemas/Trade"
        category:
          type: string
        item_type:
          type: string
        measure_type:
          $ref: "#/components/schemas/MeasureType"
        extracted_quantity:
          type: number
        quantity_override:
          type:
            - number
            - "null"
        effective_quantity:
          type: number
        unit:
          $ref: "#/components/schemas/Unit"
        tag:
          type:
            - string
            - "null"
        attributes:
          type: object
          additionalProperties:
            anyOf:
              - type: string
              - type: number
              - type: boolean
        sheet:
          type: object
          properties:
            number:
              type:
                - string
                - "null"
            title:
              type:
                - string
                - "null"
          required:
            - number
            - title
        page_number:
          type: integer
        geometry:
          $ref: "#/components/schemas/Geometry"
        evidence:
          type: array
          items:
            $ref: "#/components/schemas/Evidence"
        confidence:
          $ref: "#/components/schemas/ConfidenceBand"
        review_status:
          $ref: "#/components/schemas/ReviewStatus"
        source:
          type: string
          enum:
            - plan
            - schedule
            - legend
            - manual
        note:
          type:
            - string
            - "null"
      required:
        - id
        - takeoff_id
        - description
        - trade
        - category
        - item_type
        - measure_type
        - extracted_quantity
        - quantity_override
        - effective_quantity
        - unit
        - tag
        - attributes
        - sheet
        - page_number
        - evidence
        - confidence
        - review_status
        - source
        - note
    TakeoffItemList:
      type: object
      properties:
        next_cursor:
          type:
            - string
            - "null"
        has_more:
          type: boolean
        data:
          type: array
          items:
            $ref: "#/components/schemas/TakeoffItem"
      required:
        - next_cursor
        - has_more
        - data
    TakeoffItemUpdate:
      type: object
      properties:
        review_status:
          type: string
          enum:
            - accepted
            - rejected
            - modified
        quantity_override:
          type:
            - number
            - "null"
          minimum: 0
        note:
          type: string
          maxLength: 500
      additionalProperties: false
      description: Review an item. The extracted quantity is never changed; set quantity_override instead.
    TakeoffSummary:
      type: object
      properties:
        takeoff_id:
          $ref: "#/components/schemas/TakeoffId"
        totals:
          type: array
          items:
            type: object
            properties:
              trade:
                $ref: "#/components/schemas/Trade"
              category:
                type: string
              unit:
                $ref: "#/components/schemas/Unit"
              quantity:
                type: number
              item_count:
                type: integer
            required:
              - trade
              - category
              - unit
              - quantity
              - item_count
      required:
        - takeoff_id
        - totals
    ScheduleId:
      type: string
      pattern: ^sch_[0-9A-Za-z]{22}$
      example: sch_4kR9sT2vWx7yZa1bCd3eFg
    Schedule:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/ScheduleId"
        kind:
          type: string
          enum:
            - panel
            - fixture
            - equipment
            - motor
            - mechanical
            - plumbing
            - other
        title:
          type:
            - string
            - "null"
        sheet:
          type: object
          properties:
            number:
              type:
                - string
                - "null"
            title:
              type:
                - string
                - "null"
          required:
            - number
            - title
        page_number:
          type: integer
        columns:
          type: array
          items:
            type: string
        rows:
          type: array
          items:
            type: object
            properties:
              tag:
                type: string
              description:
                type: string
              attributes:
                type: object
                additionalProperties:
                  anyOf:
                    - type: string
                    - type: number
                    - type: boolean
            required:
              - tag
              - description
              - attributes
      required:
        - id
        - kind
        - title
        - sheet
        - page_number
        - columns
        - rows
    ScheduleList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Schedule"
      required:
        - data
    RouteId:
      type: string
      pattern: ^rte_[0-9A-Za-z]{22}$
      example: rte_4kR9sT2vWx7yZa1bCd3eFg
    RouteSystem:
      type: string
      enum:
        - conduit
        - feeder
        - branch_circuit
        - cable_tray
        - duct
        - pipe
        - other
    RouteEndpoint:
      type: object
      properties:
        type:
          type: string
          enum:
            - panel
            - equipment
            - device
            - device_group
            - junction
            - riser
            - unknown
        tag:
          type:
            - string
            - "null"
        item_id:
          $ref: "#/components/schemas/ItemId"
        count:
          type: integer
      required:
        - type
    Route:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/RouteId"
        takeoff_id:
          $ref: "#/components/schemas/TakeoffId"
        item_id:
          $ref: "#/components/schemas/ItemId"
        trade:
          $ref: "#/components/schemas/Trade"
        system:
          $ref: "#/components/schemas/RouteSystem"
        quantity:
          type: number
        unit:
          $ref: "#/components/schemas/Unit"
        from:
          $ref: "#/components/schemas/RouteEndpoint"
        to:
          $ref: "#/components/schemas/RouteEndpoint"
        segments:
          type: integer
        page_number:
          type: integer
        geometry:
          $ref: "#/components/schemas/Geometry"
        attributes:
          type: object
          additionalProperties:
            anyOf:
              - type: string
              - type: number
              - type: boolean
        confidence:
          $ref: "#/components/schemas/ConfidenceBand"
      required:
        - id
        - takeoff_id
        - trade
        - system
        - quantity
        - unit
        - page_number
        - attributes
        - confidence
    RouteList:
      type: object
      properties:
        next_cursor:
          type:
            - string
            - "null"
        has_more:
          type: boolean
        data:
          type: array
          items:
            $ref: "#/components/schemas/Route"
      required:
        - next_cursor
        - has_more
        - data
    ExportId:
      type: string
      pattern: ^exp_[0-9A-Za-z]{22}$
      example: exp_4kR9sT2vWx7yZa1bCd3eFg
    ExportFormat:
      type: string
      enum:
        - csv
        - xlsx
        - json
        - accubid
        - mccormick
        - intellibid
        - bluebeam_ost
        - procore
    Export:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/ExportId"
        takeoff_id:
          $ref: "#/components/schemas/TakeoffId"
        format:
          $ref: "#/components/schemas/ExportFormat"
        status:
          $ref: "#/components/schemas/JobStatus"
        external_ref:
          type:
            - string
            - "null"
        credits_charged:
          type: number
        download:
          type: object
          properties:
            url:
              type: string
              format: uri
            filename:
              type: string
            expires_at:
              type: string
              format: date-time
          required:
            - url
            - filename
            - expires_at
        failure:
          $ref: "#/components/schemas/Failure"
        created_at:
          type: string
          format: date-time
        completed_at:
          type:
            - string
            - "null"
          format: date-time
      required:
        - id
        - format
        - status
        - external_ref
        - credits_charged
        - created_at
        - completed_at
    ExportCreate:
      type: object
      properties:
        takeoff_id:
          $ref: "#/components/schemas/TakeoffId"
        estimate_id:
          type: string
        format:
          $ref: "#/components/schemas/ExportFormat"
        external_ref:
          type: string
          minLength: 1
          maxLength: 128
          description: Your own identifier for this resource; unique per tenant.
        options:
          type: object
          properties:
            accepted_only:
              type: boolean
              default: false
            include_evidence:
              type: boolean
              default: false
            units:
              $ref: "#/components/schemas/UnitSystemPref"
          default: {}
          additionalProperties: false
      required:
        - format
      additionalProperties: false
    Environment:
      type: string
      enum:
        - sandbox
        - production
    Credits:
      type: object
      properties:
        available:
          type: number
        held:
          type: number
        purchased_total:
          type: number
        consumed_total:
          type: number
        environment:
          $ref: "#/components/schemas/Environment"
        billing_mode:
          type: string
          enum:
            - ledger
            - artifact
        low_balance_threshold:
          type: number
        rate_card:
          type: array
          items:
            type: object
            properties:
              operation:
                type: string
              credits:
                type: number
            required:
              - operation
              - credits
      required:
        - available
        - held
        - environment
        - billing_mode
        - rate_card
    UsageReport:
      type: object
      properties:
        from:
          type: string
        to:
          type: string
        group_by:
          type: string
        rows:
          type: array
          items:
            type: object
            properties:
              key:
                type: string
              requests:
                type: integer
              errors:
                type: integer
              units:
                type: number
              credits:
                type: number
              p95_ms:
                type:
                  - integer
                  - "null"
            required:
              - key
              - requests
              - errors
              - units
              - credits
              - p95_ms
      required:
        - from
        - to
        - group_by
        - rows
    ClientId:
      type:
        - string
        - "null"
      pattern: ^(pc|oc)_[0-9A-Za-z]{22}$
    UsageEvent:
      type: object
      properties:
        occurred_at:
          type: string
          format: date-time
        request_id:
          type: string
        client_id:
          $ref: "#/components/schemas/ClientId"
        surface:
          type: string
          enum:
            - rest
            - mcp
        agent:
          type:
            - string
            - "null"
        operation:
          type: string
        status_code:
          type:
            - integer
            - "null"
        error_code:
          type:
            - string
            - "null"
        latency_ms:
          type: integer
        units:
          type: number
        credits:
          type: number
        end_customer_ref:
          type:
            - string
            - "null"
      required:
        - occurred_at
        - request_id
        - client_id
        - surface
        - agent
        - operation
        - status_code
        - error_code
        - latency_ms
        - units
        - credits
        - end_customer_ref
    UsageEventList:
      type: object
      properties:
        next_cursor:
          type:
            - string
            - "null"
        has_more:
          type: boolean
        data:
          type: array
          items:
            $ref: "#/components/schemas/UsageEvent"
      required:
        - next_cursor
        - has_more
        - data
    ClientInfo:
      type: object
      properties:
        id:
          allOf:
            - $ref: "#/components/schemas/ClientId"
            - type: string
        name:
          type: string
        environment:
          $ref: "#/components/schemas/Environment"
        mode:
          type: string
          enum:
            - service
            - delegated
        agent:
          type:
            - string
            - "null"
        billing_mode:
          type: string
          enum:
            - ledger
            - artifact
        tier:
          type: string
          enum:
            - sandbox
            - standard
            - enterprise
        scopes:
          type: array
          items:
            type: string
        products:
          type: object
          additionalProperties:
            type: boolean
        rate_limits:
          type: object
          additionalProperties:
            type: object
            properties:
              per_minute:
                type: integer
              burst:
                type: integer
            required:
              - per_minute
              - burst
        quotas:
          type: object
          additionalProperties:
            type: number
        secret_expires_at:
          type:
            - string
            - "null"
          format: date-time
      required:
        - id
        - name
        - environment
        - mode
        - agent
        - billing_mode
        - tier
        - scopes
        - products
        - rate_limits
        - quotas
        - secret_expires_at
    Capabilities:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        capabilities:
          type: array
          items:
            type: object
            properties:
              capability:
                type: string
              description:
                type: string
              tools:
                type: array
                items:
                  type: string
              status:
                type: string
                enum:
                  - available
                  - coming_soon
                  - not_enabled
            required:
              - capability
              - description
              - tools
              - status
        example_requests:
          type: array
          items:
            type: string
        environment:
          $ref: "#/components/schemas/Environment"
        billing_mode:
          type: string
          enum:
            - ledger
            - artifact
        products:
          type: object
          additionalProperties:
            type: boolean
        disciplines:
          type: array
          items:
            $ref: "#/components/schemas/Discipline"
        export_formats:
          type: array
          items:
            $ref: "#/components/schemas/ExportFormat"
        limits:
          type: object
          additionalProperties:
            type: number
        credits_available:
          type:
            - number
            - "null"
        unit_system:
          type: string
          enum:
            - imperial
            - metric
        api_version:
          type: string
        taxonomy_version:
          type: string
      required:
        - name
        - description
        - capabilities
        - example_requests
        - environment
        - billing_mode
        - products
        - disciplines
        - export_formats
        - limits
        - credits_available
        - unit_system
        - api_version
        - taxonomy_version
    Taxonomy:
      type: object
      properties:
        version:
          type: string
        trades:
          type: array
          items:
            type: object
            properties:
              code:
                $ref: "#/components/schemas/Trade"
              name:
                type: string
              categories:
                type: array
                items:
                  type: object
                  properties:
                    code:
                      type: string
                    name:
                      type: string
                    item_types:
                      type: array
                      items:
                        type: object
                        properties:
                          code:
                            type: string
                          name:
                            type: string
                          default_unit:
                            $ref: "#/components/schemas/Unit"
                          attribute_keys:
                            type: array
                            items:
                              type: string
                        required:
                          - code
                          - name
                          - default_unit
                  required:
                    - code
                    - name
                    - item_types
            required:
              - code
              - name
              - categories
      required:
        - version
        - trades
    UnitList:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              code:
                $ref: "#/components/schemas/Unit"
              name:
                type: string
              measure_type:
                $ref: "#/components/schemas/MeasureType"
              system:
                type: string
                enum:
                  - imperial
                  - metric
                  - either
              si_factor:
                type: number
            required:
              - code
              - name
              - measure_type
              - system
              - si_factor
      required:
        - data
    DisciplineList:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              code:
                $ref: "#/components/schemas/Discipline"
              name:
                type: string
            required:
              - code
              - name
      required:
        - data
    ExportFormatList:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              code:
                $ref: "#/components/schemas/ExportFormat"
              name:
                type: string
              credits:
                type: number
            required:
              - code
              - name
              - credits
      required:
        - data
  parameters: {}
  securitySchemes:
    oauth2:
      type: oauth2
      description: Client credentials (service mode, Microsoft Entra ID tenant of Aginera; request scope=api://<aginera-api-app-id>/.default; granular scopes are attached to the credential) or authorization code + PKCE (delegated mode via the Aginera authorization server; scopes are consented by the user).
      flows:
        clientCredentials:
          tokenUrl: https://login.microsoftonline.com/65f567a9-6e6a-4f81-863c-aea4ece1f8eb/oauth2/v2.0/token
          scopes: &a2
            projects:read: View projects
            projects:write: Create and update projects
            projects:delete: Delete projects
            documents:read: View and download documents
            documents:write: Upload drawings
            documents:delete: Delete documents
            takeoffs:read: View takeoffs, items, routes and schedules
            takeoffs:run: Run takeoffs (uses credits)
            takeoffs:review: Accept, reject or adjust takeoff items
            takeoffs:delete: Delete takeoffs
            estimates:read: View estimates
            estimates:generate: Generate estimates (uses credits)
            exports:read: Download exports
            exports:create: Create exports
            billing:read: View credits and usage
            billing:write: Purchase credits
            events:read: Read the event log
            webhooks:manage: Manage webhook endpoints
        authorizationCode:
          authorizationUrl: https://auth.aginera.ai/oauth/authorize
          tokenUrl: https://auth.aginera.ai/oauth/token
          refreshUrl: https://auth.aginera.ai/oauth/token
          scopes: *a2
paths:
  /projects:
    post:
      operationId: projects.create
      summary: Create a project
      tags:
        - Projects
      security:
        - oauth2:
            - projects:write
      x-aginera-cut: core
      parameters:
        - schema:
            type: string
            description: Replays within 24 hours return the original response.
          required: false
          name: Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProjectCreate"
      responses:
        "201":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Project"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
    get:
      operationId: projects.list
      summary: List projects
      tags:
        - Projects
      security:
        - oauth2:
            - projects:read
      x-aginera-cut: core
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
            maxLength: 512
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            maxLength: 128
          required: false
          name: end_customer_ref
          in: query
        - schema:
            type: string
            maxLength: 128
          required: false
          name: external_ref
          in: query
        - schema:
            type: string
            maxLength: 200
          required: false
          name: q
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProjectList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /projects/{project_id}:
    get:
      operationId: projects.get
      summary: Get a project
      tags:
        - Projects
      security:
        - oauth2:
            - projects:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/ProjectId"
          required: true
          name: project_id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Project"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
    patch:
      operationId: projects.update
      summary: Update a project
      tags:
        - Projects
      security:
        - oauth2:
            - projects:write
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/ProjectId"
          required: true
          name: project_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProjectUpdate"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Project"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
    delete:
      operationId: projects.delete
      summary: Delete a project and its documents
      tags:
        - Projects
      security:
        - oauth2:
            - projects:delete
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/ProjectId"
          required: true
          name: project_id
          in: path
      responses:
        "204":
          description: No content
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /documents:
    post:
      operationId: documents.create
      summary: Add a drawing document (from a URL, or prepare a direct upload)
      description: 'source.type = "url": Aginera fetches the file (HTTPS, ≤ 50 MB) and returns 202 with status "ingesting". source.type = "upload": returns 201 with a 15-minute upload URL; PUT the bytes, then call /documents/{id}/complete. Supported: PDF, DWG, DXF, PNG, JPEG.'
      tags:
        - Documents
      security:
        - oauth2:
            - documents:write
      x-aginera-cut: core
      parameters:
        - schema:
            type: string
            description: Replays within 24 hours return the original response.
          required: false
          name: Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DocumentCreate"
      responses:
        "201":
          description: OK
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: "#/components/schemas/DocumentWithUpload"
                  - $ref: "#/components/schemas/Document"
        "202":
          description: Ingesting from URL
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
    get:
      operationId: documents.list
      summary: List documents
      tags:
        - Documents
      security:
        - oauth2:
            - documents:read
      x-aginera-cut: core
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
            maxLength: 512
          required: false
          name: cursor
          in: query
        - schema:
            $ref: "#/components/schemas/ProjectId"
          required: false
          name: project_id
          in: query
        - schema:
            $ref: "#/components/schemas/DocumentStatus"
          required: false
          name: status
          in: query
        - schema:
            type: string
            maxLength: 128
          required: false
          name: external_ref
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /documents/{document_id}:
    get:
      operationId: documents.get
      summary: Get a document (with sheets when ready)
      tags:
        - Documents
      security:
        - oauth2:
            - documents:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/DocumentId"
          required: true
          name: document_id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Document"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
    delete:
      operationId: documents.delete
      summary: Delete a document and its takeoffs
      tags:
        - Documents
      security:
        - oauth2:
            - documents:delete
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/DocumentId"
          required: true
          name: document_id
          in: path
      responses:
        "204":
          description: No content
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /documents/{document_id}/complete:
    post:
      operationId: documents.complete
      summary: Signal that a direct upload has finished
      tags:
        - Documents
      security:
        - oauth2:
            - documents:write
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/DocumentId"
          required: true
          name: document_id
          in: path
      responses:
        "202":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Document"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /documents/{document_id}/download:
    get:
      operationId: documents.download
      summary: Download the original file (302 to a 10-minute signed URL)
      tags:
        - Documents
      security:
        - oauth2:
            - documents:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/DocumentId"
          required: true
          name: document_id
          in: path
      responses:
        "302":
          description: Redirect
          headers:
            Location:
              schema:
                type: string
              required: true
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs:
    post:
      operationId: takeoffs.create
      summary: Start a takeoff on a document
      description: Places a credit hold for the maximum plausible cost (estimated_credits) and queues the job. The final charge never exceeds the hold. 402 insufficient_credits if the hold cannot be placed.
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:run
      x-aginera-cut: core
      parameters:
        - schema:
            type: string
            description: Replays within 24 hours return the original response.
          required: false
          name: Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TakeoffCreate"
      responses:
        "202":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Takeoff"
        "402":
          description: Insufficient credits
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
    get:
      operationId: takeoffs.list
      summary: List takeoffs
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:read
      x-aginera-cut: core
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
            maxLength: 512
          required: false
          name: cursor
          in: query
        - schema:
            $ref: "#/components/schemas/DocumentId"
          required: false
          name: document_id
          in: query
        - schema:
            $ref: "#/components/schemas/ProjectId"
          required: false
          name: project_id
          in: query
        - schema:
            $ref: "#/components/schemas/JobStatus"
          required: false
          name: status
          in: query
        - schema:
            type: string
            maxLength: 128
          required: false
          name: external_ref
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TakeoffList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs/{takeoff_id}:
    get:
      operationId: takeoffs.get
      summary: Get takeoff status and summary (read-only)
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/TakeoffId"
          required: true
          name: takeoff_id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Takeoff"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs/{takeoff_id}/cancel:
    post:
      operationId: takeoffs.cancel
      summary: Cancel a queued or running takeoff
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:run
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/TakeoffId"
          required: true
          name: takeoff_id
          in: path
      responses:
        "202":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Takeoff"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs/{takeoff_id}/items:
    get:
      operationId: takeoffs.items.list
      summary: List extracted items
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/TakeoffId"
          required: true
          name: takeoff_id
          in: path
        - schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
            maxLength: 512
          required: false
          name: cursor
          in: query
        - schema:
            $ref: "#/components/schemas/Trade"
          required: false
          name: trade
          in: query
        - schema:
            type: string
            maxLength: 64
          required: false
          name: category
          in: query
        - schema:
            type: string
            maxLength: 64
          required: false
          name: item_type
          in: query
        - schema:
            type: integer
            minimum: 1
          required: false
          name: page_number
          in: query
        - schema:
            $ref: "#/components/schemas/ReviewStatus"
          required: false
          name: review_status
          in: query
        - schema:
            $ref: "#/components/schemas/MeasureType"
          required: false
          name: measure_type
          in: query
        - schema:
            $ref: "#/components/schemas/UnitSystemPref"
          required: false
          name: units
          in: query
        - schema:
            type:
              - boolean
              - "null"
            default: false
          required: false
          name: consolidated
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/TakeoffItemList"
                  - type: object
                    properties:
                      consolidated:
                        type: boolean
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs/{takeoff_id}/items/{item_id}:
    patch:
      operationId: takeoffs.items.update
      summary: Accept, reject or override an item (extraction stays immutable)
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:review
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/TakeoffId"
          required: true
          name: takeoff_id
          in: path
        - schema:
            $ref: "#/components/schemas/ItemId"
          required: true
          name: item_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TakeoffItemUpdate"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TakeoffItem"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs/{takeoff_id}/summary:
    get:
      operationId: takeoffs.summary
      summary: Totals by trade, category and unit
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/TakeoffId"
          required: true
          name: takeoff_id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TakeoffSummary"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs/{takeoff_id}/schedules:
    get:
      operationId: takeoffs.schedules
      summary: Detected schedules (panels, fixtures, equipment)
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/TakeoffId"
          required: true
          name: takeoff_id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScheduleList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /takeoffs/{takeoff_id}/routes:
    get:
      operationId: takeoffs.routes
      summary: Measured routes (conduit, feeder, duct, pipe, tray) with endpoints and geometry
      tags:
        - Takeoffs
      security:
        - oauth2:
            - takeoffs:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/TakeoffId"
          required: true
          name: takeoff_id
          in: path
        - schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
            maxLength: 512
          required: false
          name: cursor
          in: query
        - schema:
            $ref: "#/components/schemas/Trade"
          required: false
          name: trade
          in: query
        - schema:
            $ref: "#/components/schemas/RouteSystem"
          required: false
          name: system
          in: query
        - schema:
            type: integer
            minimum: 1
          required: false
          name: page_number
          in: query
        - schema:
            type:
              - boolean
              - "null"
            default: true
          required: false
          name: include_geometry
          in: query
        - schema:
            $ref: "#/components/schemas/UnitSystemPref"
          required: false
          name: units
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/RouteList"
                  - type: object
                    properties:
                      totals_by_system:
                        type: object
                        additionalProperties:
                          type: object
                          properties:
                            quantity:
                              type: number
                            unit:
                              $ref: "#/components/schemas/Unit"
                          required:
                            - quantity
                            - unit
                    required:
                      - totals_by_system
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /exports:
    post:
      operationId: exports.create
      summary: Export a takeoff (csv, xlsx, json)
      tags:
        - Exports
      security:
        - oauth2:
            - exports:create
      x-aginera-cut: core
      parameters:
        - schema:
            type: string
            description: Replays within 24 hours return the original response.
          required: false
          name: Idempotency-Key
          in: header
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ExportCreate"
      responses:
        "202":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Export"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /exports/{export_id}:
    get:
      operationId: exports.get
      summary: Get export status and download link
      tags:
        - Exports
      security:
        - oauth2:
            - exports:read
      x-aginera-cut: core
      parameters:
        - schema:
            $ref: "#/components/schemas/ExportId"
          required: true
          name: export_id
          in: path
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Export"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /credits:
    get:
      operationId: credits.get
      summary: Current credit balance (in credits)
      tags:
        - Billing
      security:
        - oauth2:
            - billing:read
      x-aginera-cut: core
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Credits"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /usage:
    get:
      operationId: usage.get
      summary: Aggregated usage
      tags:
        - Usage
      security:
        - oauth2:
            - billing:read
      x-aginera-cut: core
      parameters:
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
          required: true
          name: from
          in: query
        - schema:
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
          required: true
          name: to
          in: query
        - schema:
            type: string
            enum:
              - day
              - surface
              - agent
              - client
              - user
              - operation
              - end_customer
            default: day
          required: false
          name: group_by
          in: query
        - schema:
            type: string
            enum:
              - rest
              - mcp
          required: false
          name: surface
          in: query
        - schema:
            type: string
            maxLength: 128
          required: false
          name: end_customer_ref
          in: query
        - schema:
            type: string
            enum:
              - json
              - csv
            default: json
          required: false
          name: format
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageReport"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /usage/events:
    get:
      operationId: usage.events.list
      summary: Per-request usage records (90 days)
      tags:
        - Usage
      security:
        - oauth2:
            - billing:read
      x-aginera-cut: core
      parameters:
        - schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
          required: false
          name: limit
          in: query
        - schema:
            type: string
            maxLength: 512
          required: false
          name: cursor
          in: query
        - schema:
            type: string
            format: date-time
          required: false
          name: from
          in: query
        - schema:
            type: string
            format: date-time
          required: false
          name: to
          in: query
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageEventList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /clients/me:
    get:
      operationId: clients.me
      summary: Information about the calling credential
      tags:
        - Clients
      security:
        - oauth2: []
      x-aginera-cut: core
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ClientInfo"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /capabilities:
    get:
      operationId: capabilities.get
      summary: What this account can do right now
      tags:
        - Clients
      security:
        - oauth2: []
      x-aginera-cut: core
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Capabilities"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /reference/taxonomy:
    get:
      operationId: reference.taxonomy
      summary: Public item taxonomy (trades → categories → item types)
      tags:
        - Reference
      security:
        - oauth2: []
      x-aginera-cut: core
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Taxonomy"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /reference/units:
    get:
      operationId: reference.units
      summary: Unit registry (codes, measure types, systems, SI factors)
      tags:
        - Reference
      security:
        - oauth2: []
      x-aginera-cut: core
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UnitList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /reference/disciplines:
    get:
      operationId: reference.disciplines
      summary: Takeoff disciplines
      tags:
        - Reference
      security:
        - oauth2: []
      x-aginera-cut: core
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DisciplineList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
  /reference/export-formats:
    get:
      operationId: reference.exportFormats
      summary: Export formats and their credit cost
      tags:
        - Reference
      security:
        - oauth2: []
      x-aginera-cut: core
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ExportFormatList"
        default:
          description: Error (RFC 7807)
          content:
            application/problem+json:
              schema:
                type: object
                properties: {}
                $ref: "#/components/schemas/Problem"
webhooks: {}
