Skip to content

Remittance API Specification

Owner Classification Review Date Status
CDO Office Internal April 2027 Active
openapi: 3.1.0
info:
  title: Simpaisa Remittance API
  version: 3.0.0
  description: |
    Simpaisa Remittance API enables licensed remittance partners to send
    cross-border transfers to recipients in Pakistan, Bangladesh, Nepal,
    and Iraq. The platform provides real-time FX rates, quote
    confirmation, beneficiary management and end-to-end transaction tracking.

    Processing 270M+ transactions and over $1B in volume, the remittance
    corridor supports bank account credits, mobile wallet top-ups and
    cash pick-up disbursements with full regulatory compliance.

    All requests must be signed using RSA-SHA256.
  contact:
    name: Simpaisa Platform Engineering
    url: https://www.simpaisa.com
    email: [email protected]
  license:
    name: Proprietary
    url: https://www.simpaisa.com/terms
  x-logo:
    url: https://www.simpaisa.com/logo.png

servers:
  - url: https://api.simpaisa.com
    description: Production
  - url: https://sandbox.simpaisa.com
    description: Sandbox

security:
  - rsaSha256Signature: []

paths:
  /v3/remittances/{merchantId}/fx-rates:
    get:
      operationId: getFXRates
      summary: Retrieve current FX rates
      description: |
        Returns indicative foreign exchange rates for available currency
        corridors. Rates are refreshed periodically and include a validity
        window. Use the quote confirmation endpoint to lock a rate.
      tags:
        - Foreign Exchange
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
        - name: sourceCurrency
          in: query
          description: Filter by source currency (ISO 4217)
          schema:
            type: string
            example: GBP
        - name: destinationCurrency
          in: query
          description: Filter by destination currency (ISO 4217)
          schema:
            type: string
            example: PKR
      responses:
        '200':
          description: FX rates retrieved
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FXRateResponse'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /v3/remittances/{merchantId}/quotes/confirm:
    post:
      operationId: confirmQuote
      summary: Confirm and lock an FX quote
      description: |
        Locks an FX rate for a specified duration, creating a confirmed quote
        that can be used to initiate a remittance transaction. The quote
        includes the guaranteed exchange rate and the calculated receive amount.
      tags:
        - Foreign Exchange
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteConfirmRequest'
      responses:
        '201':
          description: Quote confirmed and locked
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteConfirmResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /v3/remittances/{merchantId}/transactions/initiate:
    post:
      operationId: initiateRemittance
      summary: Initiate a remittance transaction
      description: |
        Creates a new cross-border remittance using a confirmed quote. The
        transaction is processed asynchronously; status updates are delivered
        via webhook or can be polled.
      tags:
        - Transactions
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RemittanceRequest'
      responses:
        '201':
          description: Remittance initiated
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RemittanceResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      callbacks:
        remittanceStatusUpdate:
          '{$request.body#/callbackUrl}':
            post:
              summary: Remittance status webhook
              requestBody:
                required: true
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/WebhookPayload'
              responses:
                '200':
                  description: Webhook acknowledged

  /v3/remittances/{merchantId}/transactions/{transactionId}:
    get:
      operationId: getRemittance
      summary: Retrieve a remittance transaction
      description: Returns the current state of a remittance transaction.
      tags:
        - Transactions
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/TransactionIdPath'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
      responses:
        '200':
          description: Remittance retrieved
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RemittanceResponse'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /v3/remittances/{merchantId}/transactions:
    get:
      operationId: listRemittances
      summary: List remittance transactions
      description: Returns a paginated list of remittance transactions.
      tags:
        - Transactions
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
        - name: cursor
          in: query
          description: Opaque cursor for pagination
          schema:
            type: string
        - name: limit
          in: query
          description: Maximum records to return
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: status
          in: query
          description: Filter by transaction status
          schema:
            type: string
            enum:
              - INITIATED
              - COMPLIANCE_HOLD
              - PROCESSING
              - COMPLETED
              - FAILED
              - RETURNED
        - name: fromDate
          in: query
          schema:
            type: string
            format: date-time
        - name: toDate
          in: query
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Transaction list retrieved
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                type: object
                required:
                  - transactions
                  - pagination
                  - traceId
                properties:
                  transactions:
                    type: array
                    items:
                      $ref: '#/components/schemas/RemittanceResponse'
                  pagination:
                    $ref: '#/components/schemas/CursorPagination'
                  traceId:
                    type: string
                    format: uuid
        '401':
          $ref: '#/components/responses/Unauthorised'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /v3/remittances/{merchantId}/balance:
    get:
      operationId: getRemittanceBalance
      summary: Retrieve remittance balance
      description: Returns the merchant's remittance corridor balances.
      tags:
        - Balance
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
      responses:
        '200':
          description: Balance retrieved
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalanceResponse'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /v3/remittances/{merchantId}/banks:
    get:
      operationId: listRemittanceBanks
      summary: List banks for remittance corridors
      description: |
        Returns the list of receiving banks and payout channels available
        in the merchant's configured remittance corridors.
      tags:
        - Reference Data
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
        - name: country
          in: query
          description: Filter by destination country (ISO 3166-1 alpha-2)
          schema:
            type: string
            example: PK
      responses:
        '200':
          description: Bank list retrieved
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankListResponse'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

  /v3/remittances/{merchantId}/beneficiaries:
    post:
      operationId: createRemittanceBeneficiary
      summary: Register a remittance beneficiary
      description: |
        Creates a saved beneficiary for recurring remittances. Includes
        mandatory KYC fields required for cross-border compliance.
      tags:
        - Beneficiaries
      parameters:
        - $ref: '#/components/parameters/MerchantIdPath'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/XMerchantId'
        - $ref: '#/components/parameters/XTimestamp'
        - $ref: '#/components/parameters/XSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BeneficiaryRequest'
      responses:
        '201':
          description: Beneficiary created
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BeneficiaryResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'

components:
  securitySchemes:
    rsaSha256Signature:
      type: apiKey
      in: header
      name: X-Signature
      description: |
        RSA-SHA256 signature computed over the canonical request string.
  parameters:
    MerchantIdPath:
      name: merchantId
      in: path
      required: true
      description: Unique merchant identifier
      schema:
        type: string
        example: MCH-00123
    TransactionIdPath:
      name: transactionId
      in: path
      required: true
      description: Unique transaction identifier
      schema:
        type: string
        format: uuid
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: Client-generated unique key for idempotent processing
      schema:
        type: string
        format: uuid
    XMerchantId:
      name: X-Merchant-Id
      in: header
      required: true
      schema:
        type: string
    XTimestamp:
      name: X-Timestamp
      in: header
      required: true
      schema:
        type: string
        format: date-time
    XSignature:
      name: X-Signature
      in: header
      required: true
      schema:
        type: string
  headers:
    XTraceId:
      description: Unique trace identifier
      schema:
        type: string
        format: uuid
    XRateLimitLimit:
      description: Maximum requests per window
      schema:
        type: integer
    XRateLimitRemaining:
      description: Requests remaining in current window
      schema:
        type: integer
    XRateLimitReset:
      description: Unix epoch when rate limit resets
      schema:
        type: integer
  schemas:
    FXRateResponse:
      type: object
      required:
        - rates
        - traceId
      properties:
        rates:
          type: array
          items:
            type: object
            required:
              - sourceCurrency
              - destinationCurrency
              - rate
              - validUntil
            properties:
              sourceCurrency:
                type: string
                example: GBP
              destinationCurrency:
                type: string
                example: PKR
              rate:
                type: number
                format: double
                description: Exchange rate (1 unit of source = rate units of destination)
                example: 365.50
              inverseRate:
                type: number
                format: double
              spread:
                type: number
                format: double
              validUntil:
                type: string
                format: date-time
        traceId:
          type: string
          format: uuid
    QuoteConfirmRequest:
      type: object
      required:
        - sourceCurrency
        - destinationCurrency
        - sendAmount
      properties:
        sourceCurrency:
          type: string
          pattern: '^[A-Z]{3}$'
          example: GBP
        destinationCurrency:
          type: string
          pattern: '^[A-Z]{3}$'
          example: PKR
        sendAmount:
          type: number
          format: double
          example: 1000.00
        receiveAmount:
          type: number
          format: double
          description: |
            Desired receive amount in destination currency. Provide either
            sendAmount or receiveAmount, not both.
    QuoteConfirmResponse:
      type: object
      required:
        - quoteId
        - sourceCurrency
        - destinationCurrency
        - sendAmount
        - receiveAmount
        - rate
        - expiresAt
        - traceId
      properties:
        quoteId:
          type: string
          format: uuid
        sourceCurrency:
          type: string
        destinationCurrency:
          type: string
        sendAmount:
          type: number
          format: double
        receiveAmount:
          type: number
          format: double
        rate:
          type: number
          format: double
        fee:
          type: number
          format: double
        totalDebit:
          type: number
          format: double
        expiresAt:
          type: string
          format: date-time
        traceId:
          type: string
          format: uuid
    RemittanceRequest:
      type: object
      required:
        - quoteId
        - beneficiaryAccountNumber
        - beneficiaryName
        - beneficiaryBankCode
        - senderName
        - purpose
        - merchantTransactionId
      properties:
        quoteId:
          type: string
          format: uuid
        beneficiaryAccountNumber:
          type: string
          example: PK36SCBL0000001123456702
        beneficiaryName:
          type: string
          example: Ahmed Khan
        beneficiaryBankCode:
          type: string
          example: HBL
        beneficiaryId:
          type: string
        senderName:
          type: string
          example: John Smith
        senderIdType:
          type: string
          enum:
            - PASSPORT
            - NATIONAL_ID
            - DRIVING_LICENCE
        senderIdNumber:
          type: string
        senderCountry:
          type: string
          example: GB
        purpose:
          type: string
          example: Family maintenance
        merchantTransactionId:
          type: string
          maxLength: 64
          example: REM-2026-00456
        deliveryMethod:
          type: string
          enum:
            - BANK_ACCOUNT
            - MOBILE_WALLET
            - CASH_PICKUP
          default: BANK_ACCOUNT
        callbackUrl:
          type: string
          format: uri
        metadata:
          type: object
          additionalProperties:
            type: string
    RemittanceResponse:
      type: object
      required:
        - transactionId
        - merchantTransactionId
        - status
        - sendAmount
        - sendCurrency
        - receiveAmount
        - receiveCurrency
        - rate
        - traceId
      properties:
        transactionId:
          type: string
          format: uuid
        merchantTransactionId:
          type: string
        quoteId:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - INITIATED
            - COMPLIANCE_HOLD
            - COMPLIANCE_APPROVED
            - PROCESSING
            - COMPLETED
            - FAILED
            - RETURNED
        sendAmount:
          type: number
          format: double
        sendCurrency:
          type: string
        receiveAmount:
          type: number
          format: double
        receiveCurrency:
          type: string
        rate:
          type: number
          format: double
        fee:
          type: number
          format: double
        beneficiaryName:
          type: string
        beneficiaryAccountNumber:
          type: string
        beneficiaryBankCode:
          type: string
        deliveryMethod:
          type: string
        bankTransactionId:
          type: string
        complianceNote:
          type: string
        completedAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        metadata:
          type: object
          additionalProperties:
            type: string
        traceId:
          type: string
          format: uuid
    BalanceResponse:
      type: object
      required:
        - balances
        - traceId
      properties:
        balances:
          type: array
          items:
            type: object
            required:
              - currency
              - availableBalance
            properties:
              currency:
                type: string
                example: GBP
              availableBalance:
                type: number
                format: double
                example: 250000.00
              pendingBalance:
                type: number
                format: double
                example: 15000.00
              corridor:
                type: string
                example: GBP-PKR
        lastUpdatedAt:
          type: string
          format: date-time
        traceId:
          type: string
          format: uuid
    BankListResponse:
      type: object
      required:
        - banks
        - traceId
      properties:
        banks:
          type: array
          items:
            type: object
            required:
              - bankCode
              - name
              - country
              - status
            properties:
              bankCode:
                type: string
                example: HBL
              name:
                type: string
                example: Habib Bank Limited
              country:
                type: string
                example: PK
              type:
                type: string
                enum:
                  - BANK
                  - MOBILE_WALLET
                  - CASH_PICKUP_AGENT
              supportedDeliveryMethods:
                type: array
                items:
                  type: string
                  enum:
                    - BANK_ACCOUNT
                    - MOBILE_WALLET
                    - CASH_PICKUP
              accountNumberFormat:
                type: string
              status:
                type: string
                enum:
                  - ACTIVE
                  - DEGRADED
                  - INACTIVE
        traceId:
          type: string
          format: uuid
    BeneficiaryRequest:
      type: object
      required:
        - name
        - accountNumber
        - bankCode
        - country
        - relationship
      properties:
        name:
          type: string
          example: Fatima Bibi
        accountNumber:
          type: string
          example: PK36SCBL0000001123456702
        bankCode:
          type: string
          example: SCB
        country:
          type: string
          example: PK
        msisdn:
          type: string
        idType:
          type: string
          enum:
            - CNIC
            - PASSPORT
            - NATIONAL_ID
        idNumber:
          type: string
        relationship:
          type: string
          example: Spouse
        address:
          type: string
        city:
          type: string
        metadata:
          type: object
          additionalProperties:
            type: string
    BeneficiaryResponse:
      type: object
      required:
        - beneficiaryId
        - name
        - accountNumber
        - bankCode
        - country
        - traceId
      properties:
        beneficiaryId:
          type: string
          format: uuid
        name:
          type: string
        accountNumber:
          type: string
        bankCode:
          type: string
        country:
          type: string
        msisdn:
          type: string
        relationship:
          type: string
        createdAt:
          type: string
          format: date-time
        traceId:
          type: string
          format: uuid
    CursorPagination:
      type: object
      required:
        - hasMore
      properties:
        cursor:
          type: string
        hasMore:
          type: boolean
        totalCount:
          type: integer
    WebhookPayload:
      type: object
      required:
        - event
        - transactionId
        - merchantTransactionId
        - status
        - timestamp
        - signature
      properties:
        event:
          type: string
          enum:
            - REMITTANCE_COMPLETED
            - REMITTANCE_FAILED
            - REMITTANCE_RETURNED
            - COMPLIANCE_HOLD
            - COMPLIANCE_APPROVED
        transactionId:
          type: string
          format: uuid
        merchantTransactionId:
          type: string
        status:
          type: string
        sendAmount:
          type: number
          format: double
        sendCurrency:
          type: string
        receiveAmount:
          type: number
          format: double
        receiveCurrency:
          type: string
        bankTransactionId:
          type: string
        complianceNote:
          type: string
        timestamp:
          type: string
          format: date-time
        signature:
          type: string
          description: RSA-SHA256 signature for webhook verification
    ErrorResponse:
      type: object
      required:
        - error
        - traceId
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              example: QUOTE_EXPIRED
            message:
              type: string
              example: The confirmed quote has expired. Please request a new quote.
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  reason:
                    type: string
        traceId:
          type: string
          format: uuid
  responses:
    BadRequest:
      description: Invalid request parameters
      headers:
        X-Trace-Id:
          $ref: '#/components/headers/XTraceId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorised:
      description: Authentication failed
      headers:
        X-Trace-Id:
          $ref: '#/components/headers/XTraceId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Resource not found
      headers:
        X-Trace-Id:
          $ref: '#/components/headers/XTraceId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Conflict:
      description: Duplicate Idempotency-Key with different payload
      headers:
        X-Trace-Id:
          $ref: '#/components/headers/XTraceId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnprocessableEntity:
      description: Request understood but cannot be processed
      headers:
        X-Trace-Id:
          $ref: '#/components/headers/XTraceId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    TooManyRequests:
      description: Rate limit exceeded
      headers:
        X-Trace-Id:
          $ref: '#/components/headers/XTraceId'
        X-RateLimit-Limit:
          $ref: '#/components/headers/XRateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/XRateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/XRateLimitReset'
        Retry-After:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: Unexpected server error
      headers:
        X-Trace-Id:
          $ref: '#/components/headers/XTraceId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

tags:
  - name: Foreign Exchange
    description: FX rates and quote management
  - name: Transactions
    description: Remittance transaction lifecycle
  - name: Balance
    description: Corridor balance enquiries
  - name: Reference Data
    description: Bank and payout channel discovery
  - name: Beneficiaries
    description: Saved beneficiary management