openapi: 3.1.0
info:
  title: BankFxApi
  summary: Reference exchange-rate API sourced from central banks and trusted public financial sources.
  description: |
    BankFxApi provides programmatic access to published reference exchange rates from supported
    central banks and public financial institutions.

    The API also includes blended and cross-calculated rates through BankFxApi's proprietary
    rate blender. Data is provided for informational use and is not suitable for trading,
    settlement, accounting, or valuation without independent verification from the original source.
  version: 1.0.0
  contact:
    name: BankFxApi Support
    email: samy@bankfxapi.com
    url: https://bankfxapi.com
  termsOfService: https://bankfxapi.com/terms
  license:
    name: Proprietary
servers:
  - url: https://api.bankfxapi.com
    description: Production API
externalDocs:
  description: BankFxApi Developer Documentation
  url: https://bankfxapi.com/docs
tags:
  - name: System
    description: API health and welcome endpoints.
  - name: Exchange Rates
    description: Latest blended rates and currency conversion endpoints.
  - name: Central Banks
    description: Supported bank list and central-bank-specific rates.
  - name: Reference Data
    description: Supported currency metadata.
security:
  - ApiKeyHeader: []
  - ApiKeyQuery: []
paths:
  /:
    get:
      tags:
        - System
      summary: API welcome
      description: Returns a basic welcome response. This endpoint does not require authentication.
      operationId: getWelcome
      security: []
      responses:
        '200':
          description: API welcome response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WelcomeResponse'
              examples:
                welcome:
                  value:
                    code: 200
                    message: Welcome to BankFXApi
  /v1/{base_currency}/latest:
    get:
      tags:
        - Exchange Rates
      summary: Get latest rates for a base currency
      description: |
        Returns the latest available blended rates for a base currency.

        If `amount` is omitted, `rates` is a simple object keyed by currency code.
        If `amount` is provided, `rates` contains per-currency rate and converted amount objects.
      operationId: getLatestRates
      parameters:
        - $ref: '#/components/parameters/BaseCurrencyPath'
        - $ref: '#/components/parameters/AmountQueryOptional'
      responses:
        '200':
          description: Latest rates for the requested base currency.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/LatestRatesResponse'
                  - $ref: '#/components/schemas/LatestRatesWithAmountResponse'
              examples:
                ratesOnly:
                  summary: Rates only
                  value:
                    code: 200
                    message: success
                    rates:
                      AED: 3.6725
                      EUR: 0.859107
                      MYR: 4.018
                withAmount:
                  summary: Rates with converted amounts
                  value:
                    code: 200
                    message: success
                    base: USD
                    amount: 100
                    rates:
                      AED:
                        rate: 3.6725
                        converted: 367.25
                      EUR:
                        rate: 0.859107
                        converted: 85.9107
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '422':
          $ref: '#/components/responses/ValidationError'
  /v1/rate/{base_currency}/{target_currency}:
    get:
      tags:
        - Exchange Rates
      summary: Convert one currency to another
      description: |
        Returns the latest fresh exchange rate from one currency to another.
        If `amount` is omitted, the API uses `1`.
      operationId: getCurrencyConversion
      parameters:
        - $ref: '#/components/parameters/BaseCurrencyPath'
        - $ref: '#/components/parameters/TargetCurrencyPath'
        - $ref: '#/components/parameters/AmountQueryOptional'
      responses:
        '200':
          description: Conversion response for the requested currency pair.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PairConversionResponse'
              examples:
                defaultAmount:
                  summary: Default amount
                  value:
                    code: 200
                    message: success
                    base: USD
                    target: EUR
                    rate: 0.859107
                    amount: 1
                    converted: 0.859107
                    last_update: '2026-06-04 15:26:44'
                customAmount:
                  summary: Custom amount
                  value:
                    code: 200
                    message: success
                    base: USD
                    target: EUR
                    rate: 0.859107
                    amount: 10
                    converted: 8.59107
                    last_update: '2026-06-04 15:26:44'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '404':
          description: No fresh rate is available for the requested pair.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                noFreshRate:
                  value:
                    code: 404
                    message: No fresh exchange rate is available for USD to EUR.
        '422':
          $ref: '#/components/responses/ValidationError'
  /v1/rates/convert:
    post:
      tags:
        - Exchange Rates
      summary: Bulk currency conversion
      description: |
        Converts one amount from a base currency into multiple target currencies in a single request.
        If `amount` is omitted, the API uses `1`.
      operationId: convertRates
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkConversionRequest'
            examples:
              bulkConversion:
                value:
                  base: USD
                  amount: 100
                  targets:
                    - EUR
                    - AED
                    - MYR
      responses:
        '200':
          description: Bulk conversion response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkConversionResponse'
              examples:
                success:
                  value:
                    code: 200
                    message: success
                    base: USD
                    amount: 100
                    rates:
                      EUR:
                        rate: 0.859107
                        converted: 85.9107
                        last_update: '2026-06-04 15:26:44'
                      AED:
                        rate: 3.6725
                        converted: 367.25
                        last_update: '2026-06-04 15:31:27'
                      MYR:
                        rate: 4.018
                        converted: 401.8
                        last_update: '2026-06-04 16:42:29'
                    missing: []
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '422':
          $ref: '#/components/responses/ValidationError'
  /v1/bank/{bank_code}:
    get:
      tags:
        - Central Banks
      summary: Get rates from a specific central bank
      description: |
        Returns rates published by a specific supported central bank or reference source.
        This endpoint is not available on the Starter plan.
      operationId: getCentralBankRates
      parameters:
        - name: bank_code
          in: path
          required: true
          description: Four-character BankFxApi bank code from the supported banks endpoint.
          schema:
            type: string
            minLength: 4
            maxLength: 4
            examples:
              - AECB
              - EUCB
              - BNMY
        - name: reciprocal
          in: query
          required: false
          description: Whether to return reciprocal stored rates.
          schema:
            type: boolean
        - name: format
          in: query
          required: false
          description: Use `full` for detailed row objects. Omit for a simple currency-to-rate map.
          schema:
            type: string
            enum:
              - full
      responses:
        '200':
          description: Rates for the requested central bank.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CentralBankRatesResponse'
              examples:
                full:
                  value:
                    code: 200
                    message: success
                    meta:
                      country_code: AE
                      bank_name: Central Bank of the U.A.E
                      base_currency: AED
                      last_update: '2026-06-04 15:31:27'
                    rates:
                      - currency: USD
                        rate: 0.272294
                        last_update: '2026-06-04 15:31:27'
                        bank_update: '2026-06-04 15:31:27'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          description: Endpoint is unavailable on the current plan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                starterPlan:
                  value:
                    code: 403
                    message: This endpoint is not available on the Starter plan. Please upgrade to a higher tier.
  /v1/banks:
    get:
      tags:
        - Central Banks
      summary: List supported banks
      description: Returns supported central banks and reference sources.
      operationId: getSupportedBanks
      responses:
        '200':
          description: Supported bank list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BanksResponse'
              examples:
                success:
                  value:
                    code: 200
                    message: success
                    banks:
                      - country_code: AE
                        country_name: United Arab Emirates
                        bank_code: AECB
                        currency: AED
                        bank_name: Central Bank of the U.A.E
                      - country_code: MY
                        country_name: Malaysia
                        bank_code: BNMY
                        currency: MYR
                        bank_name: Bank Negara Malaysia
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
  /v1/currencies:
    get:
      tags:
        - Reference Data
      summary: List supported currencies
      description: Returns supported currencies with country metadata.
      operationId: getSupportedCurrencies
      responses:
        '200':
          description: Supported currency list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrenciesResponse'
              examples:
                success:
                  value:
                    code: 200
                    message: success
                    currencies:
                      - country_code: AE
                        country_name: United Arab Emirates
                        currency: AED
                      - country_code: MY
                        country_name: Malaysia
                        currency: MYR
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
components:
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: Authorization
      description: API key passed directly in the `Authorization` header.
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
      description: API key passed as the `api_key` query parameter.
  parameters:
    BaseCurrencyPath:
      name: base_currency
      in: path
      required: true
      description: Three-letter ISO currency code used as the base currency.
      schema:
        $ref: '#/components/schemas/CurrencyCode'
      examples:
        usd:
          value: USD
        eur:
          value: EUR
    TargetCurrencyPath:
      name: target_currency
      in: path
      required: true
      description: Three-letter ISO currency code used as the target currency.
      schema:
        $ref: '#/components/schemas/CurrencyCode'
      examples:
        eur:
          value: EUR
        myr:
          value: MYR
    AmountQueryOptional:
      name: amount
      in: query
      required: false
      description: Positive numeric amount to convert. Defaults to `1` when omitted.
      schema:
        type: number
        exclusiveMinimum: 0
        default: 1
        examples:
          - 1
          - 10
          - 100
  responses:
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseWithData'
          examples:
            invalidApiKey:
              value:
                code: '401'
                message: Invalid API Key
                data: []
    PaymentRequired:
      description: Insufficient API points or expired plan.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseWithData'
          examples:
            noBalance:
              value:
                code: '402'
                message: Insufficient API points or your plan expired!
                data: []
    ValidationError:
      description: Invalid request parameters or body.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalidCurrency:
              value:
                code: 422
                message: Invalid currency code.
  schemas:
    CurrencyCode:
      type: string
      pattern: '^[A-Z]{3}$'
      minLength: 3
      maxLength: 3
      examples:
        - USD
        - EUR
        - MYR
    DateTimeString:
      type: string
      description: Server-local datetime string.
      examples:
        - '2026-06-04 15:26:44'
    NumericValue:
      type: number
      examples:
        - 0.859107
        - 100
    WelcomeResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
    ErrorResponse:
      type: object
      additionalProperties: true
      required:
        - code
        - message
      properties:
        code:
          oneOf:
            - type: integer
            - type: string
        message:
          type: string
    ErrorResponseWithData:
      allOf:
        - $ref: '#/components/schemas/ErrorResponse'
        - type: object
          properties:
            data:
              type: array
              items: {}
    LatestRatesResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - rates
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
          const: success
        rates:
          type: object
          description: Map of target currency code to rate relative to the base currency.
          propertyNames:
            $ref: '#/components/schemas/CurrencyCode'
          additionalProperties:
            $ref: '#/components/schemas/NumericValue'
    LatestRatesWithAmountResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - base
        - amount
        - rates
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
          const: success
        base:
          $ref: '#/components/schemas/CurrencyCode'
        amount:
          $ref: '#/components/schemas/NumericValue'
        rates:
          type: object
          propertyNames:
            $ref: '#/components/schemas/CurrencyCode'
          additionalProperties:
            $ref: '#/components/schemas/ConvertedAmount'
    ConvertedAmount:
      type: object
      additionalProperties: false
      required:
        - rate
        - converted
      properties:
        rate:
          $ref: '#/components/schemas/NumericValue'
        converted:
          $ref: '#/components/schemas/NumericValue'
    ConvertedAmountWithUpdate:
      type: object
      additionalProperties: false
      required:
        - rate
        - converted
        - last_update
      properties:
        rate:
          $ref: '#/components/schemas/NumericValue'
        converted:
          $ref: '#/components/schemas/NumericValue'
        last_update:
          $ref: '#/components/schemas/DateTimeString'
    PairConversionResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - base
        - target
        - rate
        - amount
        - converted
        - last_update
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
          const: success
        base:
          $ref: '#/components/schemas/CurrencyCode'
        target:
          $ref: '#/components/schemas/CurrencyCode'
        rate:
          $ref: '#/components/schemas/NumericValue'
        amount:
          $ref: '#/components/schemas/NumericValue'
        converted:
          $ref: '#/components/schemas/NumericValue'
        last_update:
          $ref: '#/components/schemas/DateTimeString'
    BulkConversionRequest:
      type: object
      additionalProperties: false
      required:
        - base
        - targets
      properties:
        base:
          $ref: '#/components/schemas/CurrencyCode'
        amount:
          type: number
          exclusiveMinimum: 0
          default: 1
        targets:
          type: array
          minItems: 1
          uniqueItems: true
          items:
            $ref: '#/components/schemas/CurrencyCode'
    BulkConversionResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - base
        - amount
        - rates
        - missing
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
          const: success
        base:
          $ref: '#/components/schemas/CurrencyCode'
        amount:
          $ref: '#/components/schemas/NumericValue'
        rates:
          type: object
          propertyNames:
            $ref: '#/components/schemas/CurrencyCode'
          additionalProperties:
            $ref: '#/components/schemas/ConvertedAmountWithUpdate'
        missing:
          type: array
          items:
            $ref: '#/components/schemas/CurrencyCode'
    CentralBankRatesResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - meta
        - rates
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
          const: success
        meta:
          type: object
          additionalProperties: true
          properties:
            country_code:
              type: string
            bank_name:
              type: string
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            last_update:
              $ref: '#/components/schemas/DateTimeString'
        rates:
          oneOf:
            - type: object
              propertyNames:
                $ref: '#/components/schemas/CurrencyCode'
              additionalProperties:
                $ref: '#/components/schemas/NumericValue'
            - type: array
              items:
                type: object
                additionalProperties: true
                required:
                  - currency
                  - rate
                properties:
                  currency:
                    $ref: '#/components/schemas/CurrencyCode'
                  rate:
                    $ref: '#/components/schemas/NumericValue'
                  last_update:
                    $ref: '#/components/schemas/DateTimeString'
                  bank_update:
                    $ref: '#/components/schemas/DateTimeString'
    Bank:
      type: object
      additionalProperties: false
      required:
        - country_code
        - country_name
        - bank_code
        - currency
        - bank_name
      properties:
        country_code:
          type: string
          minLength: 2
          maxLength: 2
        country_name:
          type: string
        bank_code:
          type: string
          minLength: 4
          maxLength: 4
        currency:
          $ref: '#/components/schemas/CurrencyCode'
        bank_name:
          type: string
    BanksResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - banks
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
          const: success
        banks:
          type: array
          items:
            $ref: '#/components/schemas/Bank'
    Currency:
      type: object
      additionalProperties: false
      required:
        - country_code
        - country_name
        - currency
      properties:
        country_code:
          type: string
          minLength: 2
          maxLength: 2
        country_name:
          type: string
        currency:
          $ref: '#/components/schemas/CurrencyCode'
    CurrenciesResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - currencies
      properties:
        code:
          type: integer
          const: 200
        message:
          type: string
          const: success
        currencies:
          type: array
          items:
            $ref: '#/components/schemas/Currency'
