openapi: 3.0.3
info:
  title: DBIS Nostro/Vostro API
  version: 1.0.0
  description: |
    Standardized API for Nostro/Vostro accounts, balances, transfers,
    and reconciliations between Central Banks and regulated Financial Institutions under DBIS.
    
    This API provides a harmonized integration layer for:
    - Cross-border settlement
    - Liquidity management
    - FX and GRU-based settlement
    - GAS → Ω-Layer finality via DBIS
    
  contact:
    name: DBIS API Support
    email: api-support@dbis.org
  license:
    name: Proprietary
    url: https://dbis.org/license

servers:
  - url: https://api.scb.example.com/api/v1/nostro-vostro
    description: Production
  - url: https://sandbox.scb.example.com/api/v1/nostro-vostro
    description: Sandbox

security:
  - OAuth2MTLS: []

tags:
  - name: Nostro/Vostro
    description: Core Nostro/Vostro operations
  - name: GRU/FX
    description: GRU/FX rate discovery and conversion

paths:
  /participants:
    get:
      summary: List participants
      description: Retrieve a paginated list of participants (SCBs, FIs)
      operationId: listParticipants
      tags: [Nostro/Vostro]
      parameters:
        - $ref: '#/components/parameters/RegulatoryTier'
        - $ref: '#/components/parameters/Country'
        - $ref: '#/components/parameters/Status'
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
      responses:
        '200':
          description: List of participants
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantListResponse'
              examples:
                success:
                  value:
                    success: true
                    data:
                      data:
                        - participantId: "PART-123"
                          name: "Central Bank of Example"
                          bic: "CBEXUS33"
                          lei: "5493000X9ZXSQ9B6Y815"
                          country: "US"
                          regulatoryTier: "SCB"
                          status: "active"
                          createdAt: "2024-01-01T00:00:00Z"
                          updatedAt: "2024-01-01T00:00:00Z"
                      pagination:
                        page: 1
                        pageSize: 50
                        total: 1
                        totalPages: 1
                    timestamp: "2024-01-15T10:30:00Z"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
    
    post:
      summary: Create participant
      description: Register a new participant (SCB or FI)
      operationId: createParticipant
      tags: [Nostro/Vostro]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParticipantCreateRequest'
            examples:
              centralBank:
                value:
                  name: "Central Bank of Example"
                  bic: "CBEXUS33"
                  lei: "5493000X9ZXSQ9B6Y815"
                  country: "US"
                  regulatoryTier: "SCB"
              financialInstitution:
                value:
                  name: "Example Bank Ltd"
                  bic: "EXMPGB22"
                  lei: "213800LBQA1Y9L22CC55"
                  country: "GB"
                  regulatoryTier: "Tier1"
      responses:
        '201':
          description: Participant created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'

  /participants/{participantId}:
    get:
      summary: Get participant details
      description: Retrieve details for a specific participant
      operationId: getParticipant
      tags: [Nostro/Vostro]
      parameters:
        - $ref: '#/components/parameters/ParticipantId'
      responses:
        '200':
          description: Participant details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /accounts:
    get:
      summary: List Nostro/Vostro accounts
      description: Retrieve a paginated list of accounts
      operationId: listAccounts
      tags: [Nostro/Vostro]
      parameters:
        - name: ownerParticipantId
          in: query
          schema:
            type: string
          description: Filter by owner participant ID
        - name: counterpartyParticipantId
          in: query
          schema:
            type: string
          description: Filter by counterparty participant ID
        - name: accountType
          in: query
          schema:
            type: string
            enum: [NOSTRO, VOSTRO]
          description: Filter by account type
        - name: currency
          in: query
          schema:
            type: string
          description: Filter by currency (ISO 4217)
        - name: status
          in: query
          schema:
            type: string
            enum: [ACTIVE, SUSPENDED, CLOSED]
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
      responses:
        '200':
          description: List of accounts
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
    
    post:
      summary: Create Nostro/Vostro account
      description: Create a new Nostro or Vostro account
      operationId: createAccount
      tags: [Nostro/Vostro]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AccountCreateRequest'
            example:
              ownerParticipantId: "PART-123"
              counterpartyParticipantId: "PART-456"
              ibanOrLocalAccount: "US64SVBKUS6S3300958879"
              currency: "USD"
              accountType: "NOSTRO"
      responses:
        '201':
          description: Account created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'

  /accounts/{accountId}:
    get:
      summary: Get account details
      description: Retrieve details for a specific account
      operationId: getAccount
      tags: [Nostro/Vostro]
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
          description: Account ID
      responses:
        '200':
          description: Account details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /accounts/{accountId}/balances:
    get:
      summary: Get balances and liquidity
      description: Retrieve current balance, available liquidity, and hold amounts
      operationId: getAccountBalances
      tags: [Nostro/Vostro]
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Balance details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalanceResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /transfers:
    post:
      summary: Initiate a transfer/settlement instruction
      description: Create a new transfer with idempotency support
      operationId: createTransfer
      tags: [Nostro/Vostro]
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
          description: Idempotency key for duplicate request prevention
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransferCreateRequest'
            example:
              fromAccountId: "ACC-123"
              toAccountId: "ACC-456"
              amount: "1000.00"
              currency: "USD"
              settlementAsset: "FIAT"
              valueDate: "2024-01-15"
              reference: "PAYMENT-REF-001"
      responses:
        '201':
          description: Transfer created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '409':
          description: Duplicate request (idempotency key conflict)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    
    get:
      summary: List transfers
      description: Retrieve a paginated list of transfers with optional filters
      operationId: listTransfers
      tags: [Nostro/Vostro]
      parameters:
        - name: fromAccountId
          in: query
          schema:
            type: string
        - name: toAccountId
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
            enum: [PENDING, ACCEPTED, SETTLED, REJECTED, CANCELLED]
        - name: settlementAsset
          in: query
          schema:
            type: string
            enum: [FIAT, GRU, SSU, CBDC]
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
      responses:
        '200':
          description: List of transfers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferListResponse'

  /transfers/{transferId}:
    get:
      summary: Get transfer status
      description: Retrieve transfer details and current status
      operationId: getTransfer
      tags: [Nostro/Vostro]
      parameters:
        - name: transferId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Transfer details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /reconciliations:
    post:
      summary: Request reconciliation report
      description: Generate a reconciliation report for a participant as of a specific date
      operationId: requestReconciliation
      tags: [Nostro/Vostro]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReconciliationRequest'
            example:
              participantId: "PART-123"
              asOfDate: "2024-01-15"
      responses:
        '202':
          description: Reconciliation request accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'

  /reconciliations/{reportId}:
    get:
      summary: Get reconciliation report
      description: Retrieve a reconciliation report by ID
      operationId: getReconciliation
      tags: [Nostro/Vostro]
      parameters:
        - name: reportId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Reconciliation report
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /webhooks/subscriptions:
    post:
      summary: Create webhook subscription
      description: Subscribe to webhook events for a participant
      operationId: createWebhookSubscription
      tags: [Nostro/Vostro]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookSubscriptionCreateRequest'
            example:
              participantId: "PART-123"
              webhookUrl: "https://example.com/webhooks"
              eventTypes: ["TRANSFER_CREATED", "TRANSFER_SETTLED"]
      responses:
        '201':
          description: Webhook subscription created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSubscriptionResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
    
    get:
      summary: List webhook subscriptions
      description: List webhook subscriptions for a participant
      operationId: listWebhookSubscriptions
      tags: [Nostro/Vostro]
      parameters:
        - name: participantId
          in: query
          required: true
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
            enum: [ACTIVE, SUSPENDED, INACTIVE]
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PageSize'
      responses:
        '200':
          description: List of webhook subscriptions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSubscriptionListResponse'

  /webhooks/subscriptions/{subscriptionId}:
    get:
      summary: Get webhook subscription
      description: Retrieve webhook subscription details
      operationId: getWebhookSubscription
      tags: [Nostro/Vostro]
      parameters:
        - name: subscriptionId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Webhook subscription details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSubscriptionResponse'
        '404':
          $ref: '#/components/responses/NotFound'

  /webhooks/events:
    post:
      summary: Receive webhook events (FI side)
      description: Endpoint implemented by FI to receive notifications. This is a reference endpoint - FIs should implement their own.
      operationId: receiveWebhookEvent
      tags: [Nostro/Vostro]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEvent'
      responses:
        '200':
          description: Webhook event received

  /gru-fx/rates:
    get:
      summary: Get real-time GRU/FX rate
      description: Retrieve current exchange rate for a currency pair (including GRU pairs)
      operationId: getGruFxRate
      tags: [GRU/FX]
      parameters:
        - name: pair
          in: query
          required: true
          schema:
            type: string
          description: Currency pair (e.g., "USD/GRU", "GRU/EUR", "USD/EUR")
          example: "USD/GRU"
      responses:
        '200':
          description: Current exchange rate
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GruFxRateResponse'
        '400':
          $ref: '#/components/responses/BadRequest'

  /gru-fx/rates/history:
    get:
      summary: Get rate history
      description: Retrieve historical exchange rates for a currency pair
      operationId: getGruFxRateHistory
      tags: [GRU/FX]
      parameters:
        - name: pair
          in: query
          required: true
          schema:
            type: string
        - name: startDate
          in: query
          required: true
          schema:
            type: string
            format: date
        - name: endDate
          in: query
          required: true
          schema:
            type: string
            format: date
        - name: interval
          in: query
          schema:
            type: string
            enum: [1h, 1d, 1w]
            default: 1d
      responses:
        '200':
          description: Rate history
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GruFxRateHistoryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'

  /gru-fx/convert:
    post:
      summary: Convert currency using GRU/FX rates
      description: Convert between currencies using GRU as intermediary or direct rates
      operationId: convertCurrency
      tags: [GRU/FX]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GruFxConversionRequest'
            example:
              fromCurrency: "USD"
              toCurrency: "EUR"
              amount: "1000.00"
              settlementAsset: "FIAT"
              valueDate: "2024-01-15"
      responses:
        '200':
          description: Conversion result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GruFxConversionResponse'
        '400':
          $ref: '#/components/responses/BadRequest'

  /gru-fx/pairs:
    get:
      summary: Get available currency pairs
      description: List all available currency pairs (including GRU pairs)
      operationId: getAvailablePairs
      tags: [GRU/FX]
      responses:
        '200':
          description: List of available pairs
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      pairs:
                        type: array
                        items:
                          type: string
                        example: ["USD/GRU", "EUR/GRU", "USD/EUR"]

components:
  securitySchemes:
    OAuth2MTLS:
      type: oauth2
      description: OAuth2 with Mutual TLS authentication
      flows:
        clientCredentials:
          tokenUrl: https://auth.scb.example.com/oauth/token
          scopes:
            nv.read: Read Nostro/Vostro data
            nv.write: Create Nostro/Vostro transactions
            nv.reconcile: Request reconciliation reports
            gru.read: Read GRU/FX rates
            gru.convert: Convert currencies

  parameters:
    ParticipantId:
      name: participantId
      in: path
      required: true
      schema:
        type: string
      description: Participant ID
    
    RegulatoryTier:
      name: regulatoryTier
      in: query
      schema:
        type: string
        enum: [SCB, Tier1, Tier2, PSP]
      description: Filter by regulatory tier
    
    Country:
      name: country
      in: query
      schema:
        type: string
      description: Filter by country (ISO 3166-1 alpha-2)
    
    Status:
      name: status
      in: query
      schema:
        type: string
        enum: [active, suspended, inactive]
      description: Filter by status
    
    Page:
      name: page
      in: query
      schema:
        type: integer
        default: 1
        minimum: 1
      description: Page number
    
    PageSize:
      name: pageSize
      in: query
      schema:
        type: integer
        default: 50
        minimum: 1
        maximum: 100
      description: Items per page

  schemas:
    Participant:
      type: object
      required: [participantId, name, country, regulatoryTier, status]
      properties:
        participantId:
          type: string
          example: "PART-123"
        name:
          type: string
          example: "Central Bank of Example"
        bic:
          type: string
          example: "CBEXUS33"
        lei:
          type: string
          example: "5493000X9ZXSQ9B6Y815"
        country:
          type: string
          pattern: '^[A-Z]{2}$'
          example: "US"
        regulatoryTier:
          type: string
          enum: [SCB, Tier1, Tier2, PSP]
          example: "SCB"
        sovereignBankId:
          type: string
        status:
          type: string
          enum: [active, suspended, inactive]
          example: "active"
        metadata:
          type: object
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    ParticipantCreateRequest:
      type: object
      required: [name, country, regulatoryTier]
      properties:
        participantId:
          type: string
          description: Auto-generated if not provided
        name:
          type: string
          example: "Central Bank of Example"
        bic:
          type: string
          pattern: '^[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?$'
          example: "CBEXUS33"
        lei:
          type: string
          pattern: '^[A-Z0-9]{18}[0-9]{2}$'
          example: "5493000X9ZXSQ9B6Y815"
        country:
          type: string
          pattern: '^[A-Z]{2}$'
          example: "US"
        regulatoryTier:
          type: string
          enum: [SCB, Tier1, Tier2, PSP]
          example: "SCB"
        sovereignBankId:
          type: string
        metadata:
          type: object

    ParticipantResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/Participant'
        timestamp:
          type: string
          format: date-time

    ParticipantListResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Participant'
            pagination:
              $ref: '#/components/schemas/Pagination'
        timestamp:
          type: string
          format: date-time

    Account:
      type: object
      required: [accountId, ownerParticipantId, counterpartyParticipantId, currency, accountType, status]
      properties:
        accountId:
          type: string
          example: "ACC-123"
        ownerParticipantId:
          type: string
        counterpartyParticipantId:
          type: string
        ibanOrLocalAccount:
          type: string
          example: "US64SVBKUS6S3300958879"
        currency:
          type: string
          pattern: '^[A-Z]{3}$'
          example: "USD"
        accountType:
          type: string
          enum: [NOSTRO, VOSTRO]
          example: "NOSTRO"
        status:
          type: string
          enum: [ACTIVE, SUSPENDED, CLOSED]
          example: "ACTIVE"
        currentBalance:
          type: string
          pattern: '^\d+\.\d{2}$'
          example: "1000000.00"
        availableLiquidity:
          type: string
          example: "950000.00"
        holdAmount:
          type: string
          example: "50000.00"
        lastUpdatedAt:
          type: string
          format: date-time
        metadata:
          type: object
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    AccountCreateRequest:
      type: object
      required: [ownerParticipantId, counterpartyParticipantId, currency, accountType]
      properties:
        ownerParticipantId:
          type: string
        counterpartyParticipantId:
          type: string
        ibanOrLocalAccount:
          type: string
        currency:
          type: string
          pattern: '^[A-Z]{3}$'
        accountType:
          type: string
          enum: [NOSTRO, VOSTRO]
        metadata:
          type: object

    AccountResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/Account'
        timestamp:
          type: string
          format: date-time

    AccountListResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Account'
            pagination:
              $ref: '#/components/schemas/Pagination'
        timestamp:
          type: string
          format: date-time

    BalanceResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: object
          properties:
            accountId:
              type: string
            currentBalance:
              type: string
            availableLiquidity:
              type: string
            holdAmount:
              type: string
            currency:
              type: string
            lastUpdatedAt:
              type: string
              format: date-time
        timestamp:
          type: string
          format: date-time

    Transfer:
      type: object
      required: [transferId, fromAccountId, toAccountId, amount, currency, status]
      properties:
        transferId:
          type: string
          example: "TRF-123"
        fromAccountId:
          type: string
        toAccountId:
          type: string
        fromParticipantId:
          type: string
        toParticipantId:
          type: string
        amount:
          type: string
          pattern: '^\d+\.\d{2}$'
          example: "1000.00"
        currency:
          type: string
          example: "USD"
        settlementAsset:
          type: string
          enum: [FIAT, GRU, SSU, CBDC]
          example: "FIAT"
        valueDate:
          type: string
          format: date
          example: "2024-01-15"
        fxDetails:
          type: object
          properties:
            rate:
              type: string
            fromCurrency:
              type: string
            toCurrency:
              type: string
            convertedAmount:
              type: string
        status:
          type: string
          enum: [PENDING, ACCEPTED, SETTLED, REJECTED, CANCELLED]
          example: "PENDING"
        rejectionReason:
          type: string
        idempotencyKey:
          type: string
        reference:
          type: string
        metadata:
          type: object
        settledAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    TransferCreateRequest:
      type: object
      required: [fromAccountId, toAccountId, amount, currency]
      properties:
        fromAccountId:
          type: string
        toAccountId:
          type: string
        amount:
          type: string
          pattern: '^\d+\.\d{2}$'
        currency:
          type: string
        settlementAsset:
          type: string
          enum: [FIAT, GRU, SSU, CBDC]
          default: FIAT
        valueDate:
          type: string
          format: date
        fxDetails:
          type: object
        reference:
          type: string
        metadata:
          type: object

    TransferResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/Transfer'
        timestamp:
          type: string
          format: date-time

    TransferListResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/Transfer'
            pagination:
              $ref: '#/components/schemas/Pagination'
        timestamp:
          type: string
          format: date-time

    ReconciliationRequest:
      type: object
      required: [participantId, asOfDate]
      properties:
        participantId:
          type: string
        asOfDate:
          type: string
          format: date
        accountId:
          type: string
          description: Optional: specific account reconciliation
        metadata:
          type: object

    Reconciliation:
      type: object
      properties:
        reportId:
          type: string
        participantId:
          type: string
        asOfDate:
          type: string
          format: date
        openingBalance:
          type: string
        closingBalance:
          type: string
        totalDebits:
          type: string
        totalCredits:
          type: string
        breakCount:
          type: integer
        status:
          type: string
          enum: [PENDING, COMPLETED, FAILED]
        breaks:
          type: array
          items:
            type: object
            properties:
              breakType:
                type: string
              description:
                type: string
              amount:
                type: string
              transactionId:
                type: string
        metadata:
          type: object
        completedAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    ReconciliationResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/Reconciliation'
        timestamp:
          type: string
          format: date-time

    WebhookSubscriptionCreateRequest:
      type: object
      required: [participantId, webhookUrl, eventTypes]
      properties:
        participantId:
          type: string
        webhookUrl:
          type: string
          format: uri
          example: "https://example.com/webhooks"
        eventTypes:
          type: array
          items:
            type: string
            enum: [TRANSFER_CREATED, TRANSFER_SETTLED, TRANSFER_REJECTED, ACCOUNT_UPDATED, BALANCE_CHANGED, RECONCILIATION_COMPLETED]
          example: ["TRANSFER_CREATED", "TRANSFER_SETTLED"]
        metadata:
          type: object

    WebhookSubscription:
      type: object
      properties:
        subscriptionId:
          type: string
        participantId:
          type: string
        webhookUrl:
          type: string
        eventTypes:
          type: array
          items:
            type: string
        status:
          type: string
          enum: [ACTIVE, SUSPENDED, INACTIVE]
        lastDeliveryAt:
          type: string
          format: date-time
        failureCount:
          type: integer
        metadata:
          type: object
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time

    WebhookSubscriptionResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/WebhookSubscription'
        timestamp:
          type: string
          format: date-time

    WebhookSubscriptionListResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: object
          properties:
            data:
              type: array
              items:
                $ref: '#/components/schemas/WebhookSubscription'
            pagination:
              $ref: '#/components/schemas/Pagination'
        timestamp:
          type: string
          format: date-time

    WebhookEvent:
      type: object
      properties:
        eventId:
          type: string
        eventType:
          type: string
        timestamp:
          type: string
          format: date-time
        payload:
          type: object

    GruFxRate:
      type: object
      properties:
        pair:
          type: string
          example: "USD/GRU"
        rate:
          type: string
          example: "0.6667"
        timestamp:
          type: string
          format: date-time
        source:
          type: string
          example: "DBIS_GRU"
        bid:
          type: string
        ask:
          type: string
        spread:
          type: string

    GruFxRateResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/GruFxRate'
        timestamp:
          type: string
          format: date-time

    GruFxRateHistory:
      type: object
      properties:
        pair:
          type: string
        rates:
          type: array
          items:
            type: object
            properties:
              rate:
                type: string
              timestamp:
                type: string
                format: date-time
        startDate:
          type: string
          format: date-time
        endDate:
          type: string
          format: date-time

    GruFxRateHistoryResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/GruFxRateHistory'
        timestamp:
          type: string
          format: date-time

    GruFxConversionRequest:
      type: object
      required: [fromCurrency, toCurrency, amount]
      properties:
        fromCurrency:
          type: string
          example: "USD"
        toCurrency:
          type: string
          example: "EUR"
        amount:
          type: string
          example: "1000.00"
        settlementAsset:
          type: string
          enum: [FIAT, GRU, SSU, CBDC]
        valueDate:
          type: string
          format: date

    GruFxConversionResponse:
      type: object
      properties:
        success:
          type: boolean
        data:
          type: object
          properties:
            conversionId:
              type: string
            fromCurrency:
              type: string
            toCurrency:
              type: string
            fromAmount:
              type: string
            toAmount:
              type: string
            rate:
              type: string
            settlementAsset:
              type: string
            timestamp:
              type: string
              format: date-time
        timestamp:
          type: string
          format: date-time

    Pagination:
      type: object
      properties:
        page:
          type: integer
        pageSize:
          type: integer
        total:
          type: integer
        totalPages:
          type: integer

    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              example: "VALIDATION_ERROR"
            message:
              type: string
              example: "Invalid request parameters"
            details:
              type: object
        timestamp:
          type: string
          format: date-time

  responses:
    BadRequest:
      description: Bad request - validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "VALIDATION_ERROR"
              message: "Invalid request parameters"
              details:
                field: "amount"
                reason: "Must be a positive number"
            timestamp: "2024-01-15T10:30:00Z"

    Unauthorized:
      description: Unauthorized - missing or invalid authentication
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "UNAUTHORIZED"
              message: "Missing or invalid Sovereign Identity Token"
            timestamp: "2024-01-15T10:30:00Z"

    Forbidden:
      description: Forbidden - insufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "FORBIDDEN"
              message: "Insufficient permissions for this operation"
            timestamp: "2024-01-15T10:30:00Z"

    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "NOT_FOUND"
              message: "Participant not found"
            timestamp: "2024-01-15T10:30:00Z"

    Conflict:
      description: Conflict - resource already exists
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "CONFLICT"
              message: "Participant with this BIC already exists"
            timestamp: "2024-01-15T10:30:00Z"

    UnprocessableEntity:
      description: Unprocessable entity - business logic error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "UNPROCESSABLE_ENTITY"
              message: "Insufficient balance"
              details:
                available: "500.00"
                required: "1000.00"
            timestamp: "2024-01-15T10:30:00Z"

    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            success: false
            error:
              code: "INTERNAL_ERROR"
              message: "An internal error occurred"
            timestamp: "2024-01-15T10:30:00Z"

