openapi: 3.0.3
info:
  title: Vaultfire Partner API
  version: 1.0.0
  description: |
    The Vaultfire Partner API powers belief-aligned integrations. All endpoints reinforce ethics-first guardrails
    and belief telemetry. JWT bearer tokens issued via `/auth/login` are required for every route.
servers:
  - url: https://api.vaultfire.network
    description: Production
  - url: http://localhost:4002
    description: Local development using the sample Express server
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        Partner JWTs issued by Vaultfire. The following scopes are recognised:
          • `activation:trigger` – partners, admins
          • `rewards:read` – partners, admins, auditors
          • `rewards:plan` – admins, partner_ops
          • `belief:sync` – partners, admins
          • `belief:triggers` – admins, partner_ops
          • `telemetry:read` – admins, auditors
        Include the scope matching the partner role assigned to the token.
      x-roles:
        partner:
          - activation:trigger
          - rewards:read
          - belief:sync
        partner_ops:
          - rewards:plan
          - belief:triggers
        admin:
          - activation:trigger
          - rewards:read
          - rewards:plan
          - belief:sync
          - belief:triggers
          - telemetry:read
        auditor:
          - rewards:read
          - telemetry:read
  schemas:
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          required: [code, message]
          properties:
            code:
              type: string
            message:
              type: string
            correlationId:
              type: string
              format: uuid
            retryAfter:
              type: string
              format: date-time
    ActivationRequest:
      type: object
      required: [walletId, activationChannel]
      properties:
        walletId:
          type: string
        ens:
          type: string
        activationChannel:
          type: string
        metadata:
          type: object
          additionalProperties: true
    ActivationResponse:
      type: object
      properties:
        status:
          type: string
        walletId:
          type: string
        tierLevel:
          type: string
        activatedAt:
          type: string
          format: date-time
        modules:
          type: array
          items:
            type: object
            properties:
              moduleId:
                type: string
              state:
                type: string
    RewardsResponse:
      type: object
      properties:
        walletId:
          type: string
        currentYield:
          type: object
          properties:
            apr:
              type: number
            multiplier:
              type: number
            tierLevel:
              type: string
        pendingEvents:
          type: array
          items:
            type: object
            properties:
              eventId:
                type: string
              amount:
                type: string
              multiplier:
                type: number
              sourceProtocol:
                type: string
              timestamp:
                type: string
                format: date-time
    MirrorRequest:
      type: object
      required: [walletId, beliefScore, consent]
      properties:
        walletId:
          type: string
        beliefScore:
          type: number
        sourceProtocol:
          type: string
        mirroredAt:
          type: string
          format: date-time
        signals:
          type: array
          items:
            type: object
            properties:
              signalId:
                type: string
              weight:
                type: number
              confidence:
                type: number
        consent:
          type: object
          required: [tag, version, attestedAt]
          properties:
            tag:
              type: string
            version:
              type: string
            attestedAt:
              type: string
              format: date-time
    RewardStreamPreviewRequest:
      type: object
      required: [streamId, horizonMinutes]
      properties:
        streamId:
          type: string
        horizonMinutes:
          type: integer
          minimum: 5
        walletFilters:
          type: array
          items:
            type: string
        includeBacklog:
          type: boolean
          default: false
    RewardStreamPreviewResponse:
      type: object
      properties:
        streamId:
          type: string
        totalProjected:
          type: string
        nextEmissionAt:
          type: string
          format: date-time
        sampleRecipients:
          type: array
          items:
            type: object
            properties:
              walletId:
                type: string
              projectedAmount:
                type: string
    BeliefTriggerPlanRequest:
      type: object
      required: [triggerId, intent]
      properties:
        triggerId:
          type: string
        intent:
          type: string
        predicate:
          type: string
          description: Vaultfire rule syntax (planned)
        webhookUrl:
          type: string
        metadata:
          type: object
          additionalProperties: true
    BeliefTriggerPlanResponse:
      type: object
      properties:
        triggerId:
          type: string
        status:
          type: string
        reviewAt:
          type: string
          format: date-time
    MirrorResponse:
      type: object
      properties:
        status:
          type: string
        walletId:
          type: string
        beliefScore:
          type: number
        alignmentState:
          type: string
        nextReviewAt:
          type: string
          format: date-time
    LoginRequest:
      type: object
      required: [userId]
      properties:
        userId:
          type: string
        role:
          type: string
          enum: [admin, partner, contributor]
        partnerId:
          type: string
        scopes:
          type: array
          items:
            type: string
    LoginResponse:
      type: object
      properties:
        accessToken:
          type: string
        refreshToken:
          type: string
        refreshExpiresAt:
          type: string
          format: date-time
    RefreshRequest:
      type: object
      required: [refreshToken]
      properties:
        refreshToken:
          type: string
    RefreshResponse:
      type: object
      properties:
        accessToken:
          type: string
        expiresIn:
          type: integer

security:
  - bearerAuth: [rewards:read]

tags:
  - name: Authentication
  - name: Activation
  - name: Rewards
  - name: Belief Sync
  - name: Reward Streams
  - name: Belief Events

paths:
  /auth/login:
    post:
      tags: [Authentication]
      summary: Issue a short-lived Vaultfire JWT
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            example:
              userId: demo-partner
              role: partner
              partnerId: aurora-labs
      responses:
        '200':
          description: Authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LoginResponse'
              example:
                accessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                refreshToken: d9321af0...
                refreshExpiresAt: 2024-05-28T14:37:12Z
        '400':
          description: Invalid payload or role
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /auth/refresh:
    post:
      tags: [Authentication]
      summary: Rotate an access token using a refresh token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshRequest'
            example:
              refreshToken: d9321af0...
      responses:
        '200':
          description: Token refreshed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RefreshResponse'
        '401':
          description: Refresh token expired or invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /vaultfire/activate:
    post:
      tags: [Activation]
      summary: Trigger a Vaultfire activation sequence
      security:
        - bearerAuth: [activation:trigger]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActivationRequest'
            example:
              walletId: 0x8f1a...f93b
              activationChannel: guardian_link
              metadata:
                campaignId: spring-ignite
      responses:
        '201':
          description: Activation initiated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActivationResponse'
        '400':
          description: Invalid payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: Wallet already activated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '503':
          description: Maintenance window active
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /vaultfire/rewards/{walletId}:
    get:
      tags: [Rewards]
      summary: Fetch the latest loyalty yield metrics
      security:
        - bearerAuth: [rewards:read]
      parameters:
        - in: path
          name: walletId
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Yield metrics returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RewardsResponse'
        '400':
          description: Invalid wallet ID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Rewards not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /vaultfire/mirror:
    post:
      tags: [Belief Sync]
      summary: Mirror partner belief metadata
      security:
        - bearerAuth: [belief:sync]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MirrorRequest'
            example:
              walletId: 0x8f1a...f93b
              beliefScore: 0.87
              mirroredAt: 2024-05-28T14:43:18Z
              signals:
                - signalId: sig-9923
                  weight: 0.62
                  confidence: 0.94
              consent:
                tag: ethics-first
                version: 1.2.0
                attestedAt: 2024-05-28T14:42:57Z
      responses:
        '202':
          description: Belief metadata accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MirrorResponse'
        '400':
          description: Validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: Version conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '422':
          description: Alignment breach detected
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /vaultfire/rewards/streams/preview:
    post:
      tags: [Rewards, Reward Streams]
      summary: Preview a planned reward stream distribution
      description: |
        Calculates a projected emission window for an upcoming reward stream. This endpoint is in preview
        and returns indicative data so partners can align campaign messaging.
      security:
        - bearerAuth: [rewards:plan]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RewardStreamPreviewRequest'
            example:
              streamId: vaultfire-loyalty-q4
              horizonMinutes: 60
              walletFilters: ["0xabc...", "0xdef..."]
      responses:
        '202':
          description: Preview generated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RewardStreamPreviewResponse'
        '403':
          description: Scope missing for reward planning
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '501':
          description: Stream engine not yet enabled in this cluster
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /belief/events/triggers:
    post:
      tags: [Belief Events]
      summary: Register an intent-driven belief trigger (planned)
      description: |
        Creates a placeholder trigger for belief-based eventing. Partners can pre-stage automation intents
        which activate once the Vaultfire belief trigger engine ships to production.
      security:
        - bearerAuth: [belief:triggers]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BeliefTriggerPlanRequest'
            example:
              triggerId: loyalty-surge
              intent: notify-high-belief
              predicate: belief.score >= 0.9
              webhookUrl: https://partner.example.com/webhooks/belief
      responses:
        '202':
          description: Trigger registered for review
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BeliefTriggerPlanResponse'
        '409':
          description: Trigger already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '501':
          description: Belief trigger orchestration not yet active
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
