openapi: 3.1.0
info:
  title: Clearway Investor Read API
  version: '2.0'
  description: |
    Machine-certified pull lane for LP fund models. All routes use POST via the GCF gateway.
    Key management routes require Clerk session JWT (Governance scope).
servers:
  - url: "https://api-dev.clearway.to"
    description: "Investor Read API (dev)"
paths:
  /GET_INVESTOR_READ_GROWTH_SERIES:
    post:
      summary: Certified GMV growth series
      security:
        - InvestorReadApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                months:
                  type: integer
                brandSlug:
                  type: string
      responses:
        '200':
          description: Certified pull envelope v2
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvestorReadApiEnvelope'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/CertificationBlocked'
  /GET_INVESTOR_READ_PAGE_BUNDLE:
    post:
      summary: Certified overview page bundle
      security:
        - InvestorReadApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                months:
                  type: integer
                responseProfile:
                  type: string
                  enum: [full, excel]
      responses:
        '200':
          description: Certified pull envelope v2
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvestorReadApiEnvelope'
  /GET_INVESTOR_READ_UNIT_ECONOMICS:
    post:
      summary: Certified unit economics take-rate trend
      security:
        - InvestorReadApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                months:
                  type: integer
                brandSlug:
                  type: string
      responses:
        '200':
          description: Certified pull envelope v2
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvestorReadApiEnvelope'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/CertificationBlocked'
  /GET_INVESTOR_READ_VALUATION_MC:
    post:
      summary: Certified valuation Monte Carlo bands (projection-bound; includes reproductionPack)
      security:
        - InvestorReadApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        '200':
          description: Certified pull envelope v2 with projectionBindingHash
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvestorReadApiEnvelope'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: MC embed unavailable
        '409':
          description: MC embed stale
  /GET_INVESTOR_READ_COHORTS:
    post:
      summary: Certified brand retention cohort matrix
      security:
        - InvestorReadApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                months:
                  type: integer
                cohortMode:
                  type: string
                  enum: [vintage, observation]
                brandSlug:
                  type: string
      responses:
        '200':
          description: Certified pull envelope v2
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvestorReadApiEnvelope'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/CertificationBlocked'
  /GET_INVESTOR_VERIFY_READ_RECEIPT:
    post:
      summary: Public receipt verification (no secret)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [receiptId]
              properties:
                receiptId:
                  type: string
                  format: uuid
      responses:
        '200':
          description: Verified read-api receipt metadata
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReadReceiptVerifyResponse'
        '404':
          description: Receipt not found
components:
  securitySchemes:
    InvestorReadApiKey:
      type: http
      scheme: bearer
      description: clwy_inv_test_* or clwy_inv_live_* key
  schemas:
    InvestorReadApiCertification:
      type: object
      required:
        - receiptId
        - manifestHash
        - pulledAt
        - keyPrefix
        - scopeManifestHash
      properties:
        receiptId:
          type: string
          format: uuid
        manifestHash:
          type: string
        snapshotId:
          type: string
          format: uuid
          nullable: true
        contentHash:
          type: string
          nullable: true
        scopeManifestHash:
          type: string
          minLength: 64
          maxLength: 64
        snapshotLineageHash:
          type: string
          nullable: true
          minLength: 64
          maxLength: 64
        projectionBindingHash:
          type: string
          nullable: true
          minLength: 64
          maxLength: 64
        dataQualityScore:
          type: number
          nullable: true
        signatureVerified:
          type: boolean
          nullable: true
        dataSource:
          type: string
          nullable: true
        pulledAt:
          type: string
          format: date-time
        keyPrefix:
          type: string
        idempotentReplay:
          type: boolean
    InvestorReadApiEnvelope:
      type: object
      required: [success, readApiVersion, certification, data]
      properties:
        success:
          type: boolean
          enum: [true]
        readApiVersion:
          type: integer
          enum: [2]
        certification:
          $ref: '#/components/schemas/InvestorReadApiCertification'
        data:
          type: object
        responseProfile:
          type: string
          enum: [full, excel]
    ReadReceiptVerifyResponse:
      type: object
      properties:
        success:
          type: boolean
        verified:
          type: boolean
        receiptId:
          type: string
          format: uuid
        manifestHash:
          type: string
        snapshotId:
          type: string
          format: uuid
          nullable: true
        pulledAt:
          type: string
          format: date-time
        readApiVersion:
          type: integer
          nullable: true
        scopeManifestHash:
          type: string
          nullable: true
        contentHash:
          type: string
          nullable: true
        snapshotLineageHash:
          type: string
          nullable: true
        resource:
          type: string
        projectionBindingHash:
          type: string
          nullable: true
          minLength: 64
          maxLength: 64
  responses:
    Forbidden:
      description: IP, scope, or capability denied
      content:
        application/json:
          schema:
            type: object
            properties:
              code:
                type: string
                enum: [FORBIDDEN, IP_NOT_ALLOWED, SCOPE_DRIFT]
    CertificationBlocked:
      description: Snapshot stale or unsigned
