openapi: 3.1.0
info:
  title: currencyapi
  version: "3"
  summary: Current and historical foreign exchange (fiat, metal and crypto) rates, plus official central bank rates.
  description: >-
    currencyapi provides real-time and historical currency exchange rates for
    fiat, precious metal and crypto currencies. All endpoints are served over
    HTTPS and return JSON. Authenticate every request with your API key, either
    as the `apikey` query parameter or the `apikey` request header.


    `HEAD` answers 405 (`method_not_allowed`; `Allow` names the methods the
    endpoint takes) on every billed endpoint, without running or billing it.
    `/v3/status` and the other free endpoints answer it like `GET`.


    This document is generated from the currencyapi service implementation and is
    the machine-readable source of truth for the v3 REST API. A human-readable
    version is available at https://currencyapi.com/docs.
  contact:
    name: currencyapi support
    email: support@currencyapi.com
    url: https://support.currencyapi.com/
  x-logo:
    url: https://currencyapi.com/img/currencyapi_logo_color.svg
servers:
  - url: https://api.currencyapi.com
    description: Production
security:
  - ApiKeyQuery: []
  - ApiKeyHeader: []
tags:
  - name: Rates
    description: Live, historical and converted exchange rates.
  - name: Official rates
    description: >-
      Official exchange rates exactly as central banks publish them (ECB,
      Federal Reserve, Bank of England, ...), for accounting, invoicing, tax
      and compliance use.
  - name: Metadata
    description: Supported currencies, countries and account status.
paths:
  /v3/latest:
    get:
      tags:
        - Rates
      summary: Latest exchange rates
      operationId: getLatest
      description: >-
        Returns the latest exchange rates for a given base currency (default
        `USD`). The update interval of the returned data depends on your
        subscription plan (from daily down to minutely).


        Optional representations, none of which changes the default response:
        `shape=compact` for plain values (`"EUR": 0.918456`), `precision` to
        round, `inverse=true` for the value of one unit of each currency in
        the base currency, `include=change` for the change since the previous
        day's close, and `format=csv`.
      parameters:
        - $ref: '#/components/parameters/BaseCurrency'
        - $ref: '#/components/parameters/Currencies'
        - $ref: '#/components/parameters/Type'
        - name: include
          in: query
          required: false
          description: >-
            `change` adds `change` and `change_pct` to every rate: the
            difference to the close of the day before `last_updated_at`
            (`meta.change_since`), computed like `/v3/fluctuation`. Null when
            that close has no rate for the currency. Not with `shape=compact`.
          schema:
            type: string
            enum:
              - change
        - $ref: '#/components/parameters/Shape'
        - $ref: '#/components/parameters/Inverse'
        - $ref: '#/components/parameters/Precision'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: Latest exchange rates.
          headers:
            X-RateLimit-Limit-Quota-Month:
              $ref: '#/components/headers/RateLimitLimitQuotaMonth'
            X-RateLimit-Remaining-Quota-Month:
              $ref: '#/components/headers/RateLimitRemainingQuotaMonth'
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="latest.xlsx"`.
              schema:
                type: string
              example: attachment; filename="latest.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExchangeRatesResponse'
              example:
                meta:
                  last_updated_at: "2023-06-23T10:15:59Z"
                  base_currency: USD
                data:
                  AED:
                    code: AED
                    value: 3.67306
                  AFN:
                    code: AFN
                    value: 91.80254
                  EUR:
                    code: EUR
                    value: 0.918456
            text/csv:
              schema:
                type: string
              example: |
                datetime,base_currency,currency,value
                2023-06-23T10:15:59Z,USD,AED,3.67306
                2023-06-23T10:15:59Z,USD,EUR,0.918456
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/historical:
    get:
      tags:
        - Rates
      summary: Historical exchange rates
      operationId: getHistorical
      description: >-
        Returns the exchange rates for a specific date. Historical data is
        available back to 1999. The `date` must be at least one day in the past.


        Send `dates` instead of `date` for up to 31 days in one request: `data`
        is then keyed by date and the request costs one request per date (see
        `X-Cost`). Takes the same optional representations as `/v3/latest`
        (`shape`, `precision`, `inverse`, `format=csv`).
      parameters:
        - name: date
          in: query
          required: false
          description: >-
            Date to retrieve historical rates for (format `YYYY-MM-DD`).
            Required unless `dates` is sent; not together with `dates`.
          schema:
            type: string
            format: date
          example: "2022-01-01"
        - name: dates
          in: query
          required: false
          description: >-
            Up to 31 dates (format `YYYY-MM-DD`), comma-separated or as
            `dates[]=`. Each date is answered once, oldest first, and costs one
            request.
          style: form
          explode: false
          schema:
            type: array
            maxItems: 31
            items:
              type: string
              format: date
          example:
            - "2022-01-31"
            - "2022-02-28"
        - $ref: '#/components/parameters/BaseCurrency'
        - $ref: '#/components/parameters/Currencies'
        - $ref: '#/components/parameters/Type'
        - $ref: '#/components/parameters/Shape'
        - $ref: '#/components/parameters/Inverse'
        - $ref: '#/components/parameters/Precision'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: >-
            Historical exchange rates for the requested date, or keyed by date
            for `dates`.
          headers:
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="historical.xlsx"`.
              schema:
                type: string
              example: attachment; filename="historical.xlsx"
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ExchangeRatesResponse'
                  - $ref: '#/components/schemas/HistoricalDatesResponse'
              example:
                meta:
                  last_updated_at: "2022-01-01T23:59:59Z"
                  base_currency: USD
                  date: "2022-01-01"
                data:
                  AED:
                    code: AED
                    value: 3.67306
                  AFN:
                    code: AFN
                    value: 91.80254
            text/csv:
              schema:
                type: string
              example: |
                datetime,base_currency,currency,value
                2022-01-01T23:59:59Z,USD,AED,3.67306
                2022-01-01T23:59:59Z,USD,EUR,0.918456
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/convert:
    get:
      tags:
        - Rates
      summary: Convert a value between currencies
      operationId: getConvert
      description: >-
        Converts a value from the base currency into all (or a filtered set of)
        currencies, for today or for a given historical date. Requires a plan
        that includes the convert endpoint. Optional: `shape=compact`,
        `precision` and `format=csv`.


        Send `values` instead of `value` to convert up to 100 amounts in one
        request: `data` is then a list with one `{value, currencies}` entry
        per amount, in the order sent, and `meta.values` replaces
        `meta.value`. `datetime` converts at a moment within your plan's
        intraday history, like `/v3/rate` (the minute, quarter hour or hour it
        falls in: minutes for the last 7 days, hours for the last 3 months);
        it needs a plan with intraday updates.


        For shop prices, `round_step` or `price_ending` (with `round_mode`)
        add `rounded` to every converted value, and `locale` adds
        `formatted`, the amount as text for that locale (e.g.
        `"€ 1.233,99"` for `de_AT`). `value` itself always stays exact.
        Rounding and `locale` are not available with `shape=compact`.
      parameters:
        - name: value
          in: query
          required: false
          description: >-
            The value to convert. Must be greater than 0 and at most 10^18.
            Required unless `values` is sent; not together with `values`.
          schema:
            type: number
            exclusiveMinimum: 0
            maximum: 1000000000000000000
          example: 12
        - name: values
          in: query
          required: false
          description: >-
            Up to 100 values to convert (each greater than 0 and at most
            10^18), comma-separated or as `values[]=`. `data` becomes a list
            with one entry per value, in the order sent. The request costs one request.
          style: form
          explode: false
          schema:
            type: array
            minItems: 1
            maxItems: 100
            items:
              type: number
              exclusiveMinimum: 0
              maximum: 1000000000000000000
          example:
            - 9.99
            - 24.5
            - 100
        - name: date
          in: query
          required: false
          description: >-
            Optional date to convert against historical rates (format
            `YYYY-MM-DD`). Must be at least one day in the past. Omit for the
            latest rates. Not together with `datetime`.
          schema:
            type: string
            format: date
          example: "2022-01-01"
        - name: datetime
          in: query
          required: false
          description: >-
            Convert at this moment within your plan's intraday history (ISO
            8601): the rate of the minute, quarter hour or hour it falls in,
            as `/v3/rate` finds it. `meta.last_updated_at` is that point.
            Needs a plan with intraday updates (`403` on daily plans); moments
            beyond the plan's history return a `422`.
          schema:
            type: string
            format: date-time
          example: "2026-09-30T10:07:30Z"
        - $ref: '#/components/parameters/BaseCurrency'
        - $ref: '#/components/parameters/Currencies'
        - $ref: '#/components/parameters/Type'
        - name: round_step
          in: query
          required: false
          description: >-
            Adds `rounded`: every converted value rounded to a multiple of
            this step (greater than 0, at most 10^18), e.g. `0.05`, `1` or
            `10`. Not together with `price_ending`; not with `shape=compact`.
          schema:
            type: number
            exclusiveMinimum: 0
            maximum: 1000000000000000000
          example: 0.05
        - name: price_ending
          in: query
          required: false
          description: >-
            Adds `rounded`: every converted value rounded to a price with this
            ending (at least 0, below 1), e.g. `0.99` turns 10.97 into 10.99.
            Not together with `round_step`; not with `shape=compact`.
          schema:
            type: number
            minimum: 0
            exclusiveMaximum: 1
          example: 0.99
        - name: round_mode
          in: query
          required: false
          description: >-
            How `round_step` and `price_ending` round: to the `nearest`
            candidate (default), always `up` or always `down`.
          schema:
            type: string
            enum:
              - nearest
              - up
              - down
            default: nearest
        - name: locale
          in: query
          required: false
          description: >-
            Adds `formatted`: every converted value as text in this ICU locale
            (e.g. `de_AT`, `en-US`), with the currency's symbol and decimal
            places (at most 8; none with a whole-number `round_step`). With
            rounding, the rounded price is formatted. An unknown locale
            returns a `422`. Not with `shape=compact`.
          schema:
            type: string
            maxLength: 20
          example: de_AT
        - $ref: '#/components/parameters/Shape'
        - $ref: '#/components/parameters/Precision'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: >-
            Converted values keyed by currency code, or with `values` a list
            with one entry per value.
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="convert.xlsx"`.
              schema:
                type: string
              example: attachment; filename="convert.xlsx"
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ExchangeRatesResponse'
                  - $ref: '#/components/schemas/ConvertValuesResponse'
              examples:
                value:
                  summary: One value on a past date
                  value:
                    meta:
                      last_updated_at: "2022-01-01T23:59:59Z"
                      base_currency: USD
                      value: 12
                      date: "2022-01-01"
                    data:
                      AED:
                        code: AED
                        value: 44.07672
                      EUR:
                        code: EUR
                        value: 11.021472
                values:
                  summary: Several values (values=10,2.5, shape=compact)
                  value:
                    meta:
                      last_updated_at: "2026-09-29T23:59:59Z"
                      base_currency: USD
                      values:
                        - 10
                        - 2.5
                    data:
                      - value: 10
                        currencies:
                          EUR: 9
                      - value: 2.5
                        currencies:
                          EUR: 2.25
                shop_prices:
                  summary: A shop price (price_ending=0.99, locale=de_AT)
                  value:
                    meta:
                      last_updated_at: "2026-09-29T23:59:59Z"
                      base_currency: USD
                      value: 1371.11
                    data:
                      EUR:
                        code: EUR
                        value: 1233.999
                        rounded: 1233.99
                        formatted: "€ 1.233,99"
            text/csv:
              schema:
                type: string
              examples:
                value:
                  summary: One value
                  value: |
                    datetime,base_currency,currency,value
                    2022-01-01T23:59:59Z,USD,AED,44.07672
                    2022-01-01T23:59:59Z,USD,EUR,11.021472
                values:
                  summary: Several values (an amount column after base_currency)
                  value: |
                    datetime,base_currency,amount,currency,value
                    2026-09-29T23:59:59Z,USD,10,EUR,9
                    2026-09-29T23:59:59Z,USD,2.5,EUR,2.25
                shop_prices:
                  summary: With rounding and locale (rounded and formatted columns)
                  value: |
                    datetime,base_currency,currency,value,rounded,formatted
                    2026-09-29T23:59:59Z,USD,EUR,1233.999,1233.99,"€1,233.99"
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/rate:
    get:
      tags:
        - Rates
      summary: Exchange rate of one currency pair
      operationId: getRate
      description: >-
        Returns the rate of one pair as a single number: how many units of
        `to` one unit of `from` buys, and the inverse. Latest at your plan's
        update interval by default, the close of a past `date`, or the rate at
        a `datetime` within your plan's intraday history (the minute, quarter
        hour or hour it falls in, as `/v3/range` reports it: minutes for the
        last 7 days, hours for the last 3 months). `datetime` needs a plan
        with intraday updates.


        `format=text` answers with the bare number, so spreadsheets can read
        it directly, e.g. Google Sheets
        `=IMPORTDATA("https://api.currencyapi.com/v3/rate?from=EUR&to=USD&format=text&apikey=YOUR-API-KEY")`
        or Excel `=WEBSERVICE(...)`.
      parameters:
        - name: from
          in: query
          required: true
          description: The currency to convert from.
          schema:
            $ref: '#/components/schemas/CurrencyCode'
          example: EUR
        - name: to
          in: query
          required: true
          description: The currency to convert to.
          schema:
            $ref: '#/components/schemas/CurrencyCode'
          example: USD
        - name: date
          in: query
          required: false
          description: >-
            The close of this past day (format `YYYY-MM-DD`). Not together
            with `datetime`.
          schema:
            type: string
            format: date
          example: "2022-01-01"
        - name: datetime
          in: query
          required: false
          description: >-
            A moment within your plan's intraday history (ISO 8601). A moment
            not stored yet gets the newest rate.
          schema:
            type: string
            format: date-time
          example: "2026-09-30T10:07:30Z"
        - $ref: '#/components/parameters/Precision'
        - name: format
          in: query
          required: false
          description: >-
            `json` (default), `csv` (`from,to,rate,inverse,last_updated_at`),
            `xlsx` (the same table as an Excel workbook, `rate.xlsx`) or
            `text` (only the rate, as plain text without exponent notation).
          schema:
            type: string
            enum:
              - json
              - csv
              - text
              - xlsx
            default: json
      responses:
        '200':
          description: The rate of the pair.
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="rate.xlsx"`.
              schema:
                type: string
              example: attachment; filename="rate.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateResponse'
              example:
                meta:
                  last_updated_at: "2023-06-23T10:15:59Z"
                data:
                  from: EUR
                  to: USD
                  rate: 1.0887771
                  inverse: 0.918456
            text/plain:
              schema:
                type: string
              example: "1.0887771"
            text/csv:
              schema:
                type: string
              example: |
                from,to,rate,inverse,last_updated_at
                EUR,USD,1.0887771,0.918456,2023-06-23T10:15:59Z
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/matrix:
    get:
      tags:
        - Rates
      summary: Cross rates between several currencies
      operationId: getMatrix
      description: >-
        Returns every cross rate between 2 to 25 currencies in one request:
        `data.EUR.USD` is the price of 1 EUR in USD. Latest at your plan's
        update interval, or the close of a past `date`. `format=csv` gives the
        table with one row per base currency.
      parameters:
        - name: currencies
          in: query
          required: true
          description: >-
            2 to 25 currency codes, comma-separated (e.g. `USD,EUR,GBP`) or as
            `currencies[]=`. Rows and columns keep this order.
          style: form
          explode: false
          schema:
            type: array
            minItems: 2
            maxItems: 25
            items:
              $ref: '#/components/schemas/CurrencyCode'
          example:
            - USD
            - EUR
            - GBP
        - name: date
          in: query
          required: false
          description: The close of this past day (format `YYYY-MM-DD`).
          schema:
            type: string
            format: date
          example: "2022-01-01"
        - $ref: '#/components/parameters/Precision'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: The cross rates, one row per base currency.
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="matrix.xlsx"`.
              schema:
                type: string
              example: attachment; filename="matrix.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MatrixResponse'
              example:
                meta:
                  last_updated_at: "2023-06-23T10:15:59Z"
                  currencies:
                    - USD
                    - EUR
                    - GBP
                data:
                  USD:
                    USD: 1
                    EUR: 0.918456
                    GBP: 0.786123
                  EUR:
                    USD: 1.0887771
                    EUR: 1
                    GBP: 0.8559168
                  GBP:
                    USD: 1.2720671
                    EUR: 1.1683413
                    GBP: 1
            text/csv:
              schema:
                type: string
              example: |
                base_currency,USD,EUR,GBP
                USD,1,0.918456,0.786123
                EUR,1.0887771,1,0.8559168
                GBP,1.2720671,1.1683413,1
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/range:
    get:
      tags:
        - Rates
      summary: Historical exchange rates for a time range
      operationId: getRange
      description: >-
        Returns exchange rates for every interval between `datetime_start` and
        `datetime_end` at the requested accuracy. Requires a plan that includes
        the range endpoint (medium and up). The allowed span and look-back
        depend on the chosen accuracy:


        - `day`: not more than 366 days between start and end.

        - `hour`: not more than 7 days between start and end, and not more than 3
          months back.

        - `quarter_hour`: not more than 24 hours between start and end, and not
          more than 7 days back.

        - `minute`: not more than 6 hours between start and end, and not more
          than 7 days back.

        - `week`: the daily rate at the end of each week (Sunday), not more
          than 1830 days between start and end.

        - `month`: the daily rate at the end of each month, any span back to
          1999.


        For `week` and `month` the last point is `datetime_end` itself when it
        falls inside a period. Add `format=csv` for one row per point and
        currency: `datetime,base_currency,currency,value`.


        `orient=currency` returns one series per currency instead of one
        point per datetime (`data.EUR` is a list of `{datetime, value}`),
        `shape=compact` drops the code/value objects (with `orient=currency`
        each point is `[datetime, value]`), and `precision` rounds.
      parameters:
        - name: datetime_start
          in: query
          required: true
          description: >-
            Start of the range as an ISO 8601 datetime (e.g.
            `2021-11-30T23:59:59Z`). Must be before or equal to `datetime_end`.
          schema:
            type: string
            format: date-time
          example: "2021-11-30T23:59:59Z"
        - name: datetime_end
          in: query
          required: true
          description: >-
            End of the range as an ISO 8601 datetime (e.g.
            `2021-12-31T23:59:59Z`). Must be after or equal to `datetime_start`.
          schema:
            type: string
            format: date-time
          example: "2021-12-31T23:59:59Z"
        - name: accuracy
          in: query
          required: false
          description: The interval accuracy of the returned data.
          schema:
            type: string
            enum:
              - day
              - hour
              - quarter_hour
              - minute
              - week
              - month
            default: day
        - $ref: '#/components/parameters/BaseCurrency'
        - $ref: '#/components/parameters/Currencies'
        - $ref: '#/components/parameters/Type'
        - name: orient
          in: query
          required: false
          description: >-
            `datetime` (default): one point per datetime. `currency`: one
            series per currency, keyed by code.
          schema:
            type: string
            enum:
              - datetime
              - currency
            default: datetime
        - $ref: '#/components/parameters/Shape'
        - $ref: '#/components/parameters/Precision'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: Exchange rates per interval within the requested range.
          headers:
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="range.xlsx"`.
              schema:
                type: string
              example: attachment; filename="range.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RangeResponse'
              example:
                meta:
                  base_currency: USD
                  accuracy: day
                  datetime_start: "2022-01-01T00:00:00Z"
                  datetime_end: "2022-01-02T23:59:59Z"
                data:
                  - datetime: "2022-01-01T23:59:59Z"
                    currencies:
                      AED:
                        code: AED
                        value: 3.67306
                      EUR:
                        code: EUR
                        value: 0.918456
                  - datetime: "2022-01-02T23:59:59Z"
                    currencies:
                      AED:
                        code: AED
                        value: 3.67308
                      EUR:
                        code: EUR
                        value: 0.919012
            text/csv:
              schema:
                type: string
              example: |
                datetime,base_currency,currency,value
                2022-01-01T23:59:59Z,USD,AED,3.67306
                2022-01-01T23:59:59Z,USD,EUR,0.918456
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/ohlc:
    get:
      tags:
        - Rates
      summary: Hourly or daily OHLC candles
      operationId: getOhlc
      description: >-
        Returns open, high, low and close per hour or per day for 1 to 10
        currencies, built from the stored rates. Requires a plan that includes
        the range endpoint (medium and up).


        - `hour`: from the minute rates. `datetime_start` not more than 7 days
          back, not more than 7 days between start and end. Needs a plan with
          quarter-hourly updates or finer.

        - `day` (default): from the hourly rates. `datetime_start` not more
          than 3 months back, not more than 92 days between start and end.
          Needs a plan with hourly updates or finer.


        Each candle closes on the stored rate at the end of its hour or day and
        opens on the close of the candle before it (on its own close after a
        gap); `high` and `low` are the
        extremes of the finer rates in between and always include the
        open and the close. `datetime` is the start of the candle. Candles whose
        close is not stored yet (e.g. the hour or day still running) are left
        out. A request costs one request, however many currencies and candles
        it holds.


        `shape=compact` gives every candle as `[datetime, open, high, low,
        close]`, `precision` rounds, and `format=csv` gives one row per
        candle: `datetime,base_currency,currency,open,high,low,close`.
      parameters:
        - name: currencies
          in: query
          required: true
          description: >-
            1 to 10 currency codes, comma-separated (e.g. `EUR,GBP`) or as
            `currencies[]=`.
          style: form
          explode: false
          schema:
            type: array
            minItems: 1
            maxItems: 10
            items:
              $ref: '#/components/schemas/CurrencyCode'
          example:
            - EUR
            - GBP
        - $ref: '#/components/parameters/BaseCurrency'
        - name: interval
          in: query
          required: false
          description: The length of each candle.
          schema:
            type: string
            enum:
              - hour
              - day
            default: day
        - name: datetime_start
          in: query
          required: true
          description: >-
            Start of the range as an ISO 8601 datetime or date (e.g.
            `2026-09-29T00:00:00Z`). The first candle is the one this moment
            falls in.
          schema:
            type: string
            format: date-time
          example: "2026-09-29T00:00:00Z"
        - name: datetime_end
          in: query
          required: true
          description: >-
            End of the range as an ISO 8601 datetime or date, on or after
            `datetime_start`. The last candle is the one this moment falls in.
          schema:
            type: string
            format: date-time
          example: "2026-09-30T23:59:59Z"
        - $ref: '#/components/parameters/Shape'
        - $ref: '#/components/parameters/Precision'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: The candles of each currency, oldest first.
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="ohlc.xlsx"`.
              schema:
                type: string
              example: attachment; filename="ohlc.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OhlcResponse'
              example:
                meta:
                  base_currency: USD
                  interval: hour
                  datetime_start: "2026-09-30T10:00:00Z"
                  datetime_end: "2026-09-30T11:00:00Z"
                data:
                  EUR:
                    - datetime: "2026-09-30T10:00:00Z"
                      open: 0.91
                      high: 0.95
                      low: 0.9
                      close: 0.92
                    - datetime: "2026-09-30T11:00:00Z"
                      open: 0.92
                      high: 0.925
                      low: 0.9165
                      close: 0.9188
            text/csv:
              schema:
                type: string
              example: |
                datetime,base_currency,currency,open,high,low,close
                2026-09-30T10:00:00Z,USD,EUR,0.91,0.95,0.9,0.92
                2026-09-30T11:00:00Z,USD,EUR,0.92,0.925,0.9165,0.9188
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No rates are stored in the requested range.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/fluctuation:
    get:
      tags:
        - Rates
      summary: How rates changed between two dates
      operationId: getFluctuation
      description: >-
        Returns, for every requested currency, its rate at the end of
        `date_from` and of `date_to` and how much it changed in between, in
        absolute terms and in percent. Both days are UTC days back to
        1999-01-01; the newest allowed is yesterday.


        The JSON response also has the `high`, `low` and `average` of the
        daily closes from `date_from` to `date_to` (null when the two days are
        more than 1830 days apart or the span has no data). The CSV keeps its
        columns.
      parameters:
        - name: date_from
          in: query
          required: true
          description: First day (`YYYY-MM-DD`).
          schema:
            type: string
            format: date
          example: "2026-01-01"
        - name: date_to
          in: query
          required: true
          description: Last day (`YYYY-MM-DD`), on or after `date_from`.
          schema:
            type: string
            format: date
          example: "2026-06-30"
        - $ref: '#/components/parameters/BaseCurrency'
        - $ref: '#/components/parameters/Currencies'
        - $ref: '#/components/parameters/Type'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: >-
            Start rate, end rate, change, and high, low and average per
            currency.
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="fluctuation.xlsx"`.
              schema:
                type: string
              example: attachment; filename="fluctuation.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FluctuationResponse'
              example:
                meta:
                  base_currency: USD
                  date_from: "2026-01-01"
                  date_to: "2026-06-30"
                data:
                  EUR:
                    code: EUR
                    start_rate: 0.9654
                    end_rate: 0.8771
                    change: -0.0883
                    change_pct: -9.1465
                    high: 0.9712
                    low: 0.8695
                    average: 0.9183
            text/csv:
              schema:
                type: string
              example: |
                date_from,date_to,base_currency,currency,start_rate,end_rate,change,change_pct
                2026-01-01,2026-06-30,USD,EUR,0.9654,0.8771,-0.0883,-9.1465
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No rates are stored for one of the two days.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/average:
    get:
      tags:
        - Rates
      summary: Average, low and high rates per month, quarter or year
      operationId: getAverage
      description: >-
        Averages the daily rates per calendar `period` (`month`, `quarter`,
        `year`, or `total` for the whole span) and reports each period's low
        and high. Daily rates are first expressed against `base_currency` and
        then averaged, so the average EUR rate in GBP is the mean of the daily
        EUR/GBP rates. Average rates are what IFRS and US GAAP allow for
        translating income and expenses. With `source`, the
        same figures are computed from a central bank's official publications,
        e.g. the ECB's monthly average EUR/USD for your books.


        `date_from` and `date_to` may be at most 1830 days apart. The first
        and last period are cut to the requested span; `date_from`, `date_to`
        and `days` of each period tell exactly which days went into it.
      parameters:
        - name: date_from
          in: query
          required: true
          description: First day (`YYYY-MM-DD`), 1999-01-01 or later.
          schema:
            type: string
            format: date
          example: "2026-01-01"
        - name: date_to
          in: query
          required: true
          description: Last day (`YYYY-MM-DD`), yesterday at the latest.
          schema:
            type: string
            format: date
          example: "2026-06-30"
        - name: period
          in: query
          required: false
          description: How to group the days.
          schema:
            type: string
            enum:
              - month
              - quarter
              - year
              - total
            default: month
        - name: source
          in: query
          required: false
          description: >-
            Average a central bank's official publications instead of market
            rates (see `/v3/official/sources`). Rates are then against the
            bank's own currency unless `base_currency` is set, `date_from` and
            `date_to` may be at most 366 days apart, `days` counts
            publications and currencies are those the bank publishes. Cannot
            be combined with `type`.
          schema:
            type: string
          example: ecb
        - $ref: '#/components/parameters/BaseCurrency'
        - $ref: '#/components/parameters/Currencies'
        - $ref: '#/components/parameters/Type'
        - $ref: '#/components/parameters/Format'
      responses:
        '200':
          description: One entry per period with each currency's average, low and high.
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="average.xlsx"`.
              schema:
                type: string
              example: attachment; filename="average.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AverageResponse'
              example:
                meta:
                  source: market
                  base_currency: USD
                  period: month
                  date_from: "2026-01-01"
                  date_to: "2026-02-28"
                data:
                  - period: "2026-01"
                    date_from: "2026-01-01"
                    date_to: "2026-01-31"
                    days: 31
                    currencies:
                      EUR:
                        code: EUR
                        value: 0.9612
                        min: 0.9504
                        max: 0.9711
                  - period: "2026-02"
                    date_from: "2026-02-01"
                    date_to: "2026-02-28"
                    days: 28
                    currencies:
                      EUR:
                        code: EUR
                        value: 0.9558
                        min: 0.9461
                        max: 0.9640
            text/csv:
              schema:
                type: string
              example: |
                period,date_from,date_to,days,source,base_currency,currency,average,min,max
                2026-01,2026-01-01,2026-01-31,31,market,USD,EUR,0.9612,0.9504,0.9711
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No rates are stored in the requested span.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/official:
    get:
      tags:
        - Official rates
      summary: Official central bank exchange rates
      operationId: getOfficial
      description: >-
        Returns the official exchange rates a central bank published for a
        date, or its newest publication when `date` is omitted. Values are the
        bank's own figures, never blended with market data, and are normalised
        to "units of currency per 1 unit of `base_currency`".


        Central banks publish only on their business days. When nothing was
        published on the requested `date` (a weekend or holiday), the newest
        publication from up to 14 days before it is returned; `meta.date` is
        the date the returned rates are for and `meta.requested_date` the date
        you asked for.


        By default rates are against the bank's own currency (EUR for `ecb`,
        PLN for `nbp`, ...) and are official as-is. With any other
        `base_currency`, values are cross rates calculated from the official
        ones and `meta.cross_rates` is `true`.


        `compare=market` puts the market rate of the publication day next to
        each official rate: `market` (that day's close from
        `/v3/historical`; for a publication dated today, the latest market
        rate at your plan's update interval) and `difference_pct`, how far
        the official rate is from it in percent. `meta.market_last_updated_at`
        says when that market rate is from. The official values themselves
        are unchanged.

        Responses carry an `ETag` and `Cache-Control: private`. Send the
        ETag back in `If-None-Match` and an unchanged response is answered
        with `304 Not Modified` and no body (it counts as a request).
      parameters:
        - $ref: '#/components/parameters/OfficialSource'
        - name: date
          in: query
          required: false
          description: >-
            Date to get the official rates for (format `YYYY-MM-DD`). Omit for
            the newest publication. May be tomorrow, since some banks (e.g. the
            NBU) set their rate a day ahead.
          schema:
            type: string
            format: date
          example: "2026-09-28"
        - $ref: '#/components/parameters/OfficialBaseCurrency'
        - $ref: '#/components/parameters/OfficialCurrencies'
        - $ref: '#/components/parameters/OfficialCompare'
        - $ref: '#/components/parameters/OfficialFormat'
      responses:
        '200':
          description: The official rates of one publication.
          headers:
            X-RateLimit-Limit-Quota-Month:
              $ref: '#/components/headers/RateLimitLimitQuotaMonth'
            X-RateLimit-Remaining-Quota-Month:
              $ref: '#/components/headers/RateLimitRemainingQuotaMonth'
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="official.xlsx"`.
              schema:
                type: string
              example: attachment; filename="official.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialRatesResponse'
              examples:
                official:
                  summary: Official rates
                  value:
                    meta:
                      source: "nbp"
                      source_name: "National Bank of Poland"
                      date: "2026-09-28"
                      requested_date: "2026-09-28"
                      base_currency: "USD"
                      source_base_currency: "PLN"
                      cross_rates: true
                      reference: "188/A/NBP/2026"
                      last_updated_at: "2026-09-28T10:07:12Z"
                    data:
                      PLN:
                        code: PLN
                        value: 3.8478
                compare_market:
                  summary: compare=market
                  value:
                    meta:
                      source: "ecb"
                      source_name: "European Central Bank"
                      date: "2026-09-25"
                      requested_date: "2026-09-25"
                      base_currency: "EUR"
                      source_base_currency: "EUR"
                      cross_rates: false
                      reference: null
                      last_updated_at: "2026-09-25T14:16:03Z"
                      market_last_updated_at: "2026-09-25T23:59:59Z"
                    data:
                      USD:
                        code: USD
                        value: 1.1403
                        market: 1.1402508552
                        difference_pct: 0.0043
            text/csv:
              schema:
                type: string
              examples:
                csv:
                  summary: format=csv
                  value: "date,source,base_currency,currency,value,reference\n2026-09-28,nbp,USD,PLN,3.8478,\"188/A/NBP/2026\"\n"
                compare_market:
                  summary: format=csv&compare=market
                  value: "date,source,base_currency,currency,value,reference,market,difference_pct\n2026-09-25,ecb,EUR,USD,1.1403,,1.140250855,0.0043\n"
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '304':
          description: Not modified since the response with the ETag sent in `If-None-Match`.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NoOfficialRates'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/official/range:
    get:
      tags:
        - Official rates
      summary: Official central bank exchange rates for a date range
      operationId: getOfficialRange
      description: >-
        Returns every publication of a central bank between `date_from` and
        `date_to` (at most 366 days apart), oldest first. Only the bank's
        publication days are included; nothing is filled in for weekends or
        holidays. Requires a plan that includes the range endpoint (medium and
        up).

        Responses carry an `ETag` and `Cache-Control: private`. Send the
        ETag back in `If-None-Match` and an unchanged response is answered
        with `304 Not Modified` and no body (it counts as a request).


        `accuracy=week` or `accuracy=month` keeps only the last publication of
        each week (Monday to Sunday) or month, e.g. the month-end rates to
        revalue balances with. Works with every `format`.


        `compare=market` puts the market rate of each publication day next to
        each official rate (`market`, `difference_pct`) and adds
        `market_last_updated_at` to each entry, as on `/v3/official`. Not
        with `format=datev`, `erpnext` or `odoo` (`422`): the import files
        carry the official rates only.


        `format=datev`, `erpnext` or `odoo` returns a file to import as the
        rate table of that accounting software, as an attachment named
        `{source}-{format}-{date_from}-{date_to}.csv`:


        - `datev`: DATEV Kanzlei-Rechnungswesen / Rechnungswesen, Kurstabelle
          import (DATEV Dok.-Nr. 1015760). One line per currency and
          publication, `Währung 1;Währung 2;Datum von;Datum bis;Kurs;Notiz;Kurstyp`
          (e.g. `EUR;USD;25.09.2026;25.09.2026;1,140300;European Central Bank;5`):
          no header, CRLF line ends, windows-1252, 6 decimals with a decimal
          comma, Kurstyp 5 (Freier Kurs). Rates must be against EUR, so
          `base_currency` must be (or default to) `EUR`, else `422`.

        - `erpnext`: ERPNext Data Import into "Currency Exchange",
          `Date,From Currency,To Currency,Exchange Rate,For Buying,For Selling`.
          From is the foreign currency, To the base currency, and the rate the
          base currency units for 1 unit of the foreign currency (9 decimals).

        - `odoo`: Odoo, Import records on a currency's rates. Exactly one
          currency in `currencies` (else `422`); `name,company_rate`, newest
          first, `company_rate` being units of the currency per 1 unit of the
          base currency.
      parameters:
        - $ref: '#/components/parameters/OfficialSource'
        - name: date_from
          in: query
          required: true
          description: First date of the range (format `YYYY-MM-DD`).
          schema:
            type: string
            format: date
          example: "2026-09-01"
        - name: date_to
          in: query
          required: true
          description: >-
            Last date of the range (format `YYYY-MM-DD`), at most 366 days
            after `date_from`.
          schema:
            type: string
            format: date
          example: "2026-09-30"
        - $ref: '#/components/parameters/OfficialBaseCurrency'
        - $ref: '#/components/parameters/OfficialCurrencies'
        - $ref: '#/components/parameters/OfficialCompare'
        - name: accuracy
          in: query
          required: false
          description: >-
            `day` (default): every publication. `week`: only the last
            publication of each week (Monday to Sunday). `month`: only the last
            publication of each month (the month-end rates).
          schema:
            type: string
            enum:
              - day
              - week
              - month
            default: day
        - name: format
          in: query
          required: false
          description: >-
            `json` (default), `csv`
            (`date,source,base_currency,currency,value,reference`, plus
            `market,difference_pct` with `compare=market`), `xlsx` (the same
            table as an Excel workbook, `official-range.xlsx`), or a file
            to import into accounting software: `datev` (rates against EUR
            only), `erpnext` or `odoo` (exactly one currency).
          schema:
            type: string
            enum:
              - json
              - csv
              - xlsx
              - datev
              - erpnext
              - odoo
            default: json
      responses:
        '200':
          description: >-
            The official rates of every publication in the range (with
            `accuracy`, of the last one of each week or month).
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=datev`, `erpnext` or `odoo`: `attachment;
                filename="{source}-{format}-{date_from}-{date_to}.csv"`. With
                `format=xlsx`: `attachment; filename="official-range.xlsx"`.
              schema:
                type: string
              example: attachment; filename="ecb-datev-2026-09-25-2026-09-28.csv"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialRangeResponse'
              examples:
                official:
                  summary: Official rates
                  value:
                    meta:
                      source: "ecb"
                      source_name: "European Central Bank"
                      base_currency: "EUR"
                      source_base_currency: "EUR"
                      cross_rates: false
                    data:
                      - date: "2026-09-25"
                        reference: null
                        currencies:
                          USD:
                            code: USD
                            value: 1.1403
                      - date: "2026-09-28"
                        reference: null
                        currencies:
                          USD:
                            code: USD
                            value: 1.1378
                compare_market:
                  summary: compare=market
                  value:
                    meta:
                      source: "ecb"
                      source_name: "European Central Bank"
                      base_currency: "EUR"
                      source_base_currency: "EUR"
                      cross_rates: false
                    data:
                      - date: "2026-09-25"
                        reference: null
                        currencies:
                          USD:
                            code: USD
                            value: 1.1403
                            market: 1.1402508552
                            difference_pct: 0.0043
                        market_last_updated_at: "2026-09-25T23:59:59Z"
                      - date: "2026-09-28"
                        reference: null
                        currencies:
                          USD:
                            code: USD
                            value: 1.1378
                            market: 1.1376564278
                            difference_pct: 0.0126
                        market_last_updated_at: "2026-09-28T23:59:59Z"
            text/csv:
              schema:
                type: string
              examples:
                csv:
                  summary: format=csv
                  value: "date,source,base_currency,currency,value,reference\n2026-09-25,ecb,EUR,USD,1.1403,\n2026-09-28,ecb,EUR,USD,1.1378,\n"
                compare_market:
                  summary: format=csv&compare=market
                  value: "date,source,base_currency,currency,value,reference,market,difference_pct\n2026-09-25,ecb,EUR,USD,1.1403,,1.140250855,0.0043\n2026-09-28,ecb,EUR,USD,1.1378,,1.137656428,0.0126\n"
                erpnext:
                  summary: format=erpnext (Currency Exchange import)
                  value: "Date,From Currency,To Currency,Exchange Rate,For Buying,For Selling\n2026-09-25,USD,EUR,0.876962203,1,1\n2026-09-28,USD,EUR,0.878889084,1,1\n"
                odoo:
                  summary: format=odoo (one currency, newest first)
                  value: "name,company_rate\n2026-09-28,1.1378\n2026-09-25,1.1403\n"
            text/csv; charset=windows-1252:
              schema:
                type: string
              example: "EUR;GBP;25.09.2026;25.09.2026;0,860450;European Central Bank;5\r\nEUR;GBP;28.09.2026;28.09.2026;0,857850;European Central Bank;5\r\nEUR;USD;25.09.2026;25.09.2026;1,140300;European Central Bank;5\r\nEUR;USD;28.09.2026;28.09.2026;1,137800;European Central Bank;5\r\n"
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '304':
          description: Not modified since the response with the ETag sent in `If-None-Match`.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NoOfficialRates'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/official/compare:
    get:
      tags:
        - Official rates
      summary: Compare one currency pair across central banks
      operationId: getOfficialCompare
      description: >-
        Returns one currency pair as every central bank published it: how
        many `currency` one `base_currency` buys in each bank's newest
        publication on or before `date` (within the usual 14 days), or in its
        newest publication when `date` is omitted. Banks are listed in the
        order of `/v3/official/sources`.


        A bank that publishes against one of the two currencies gives the
        rate directly. A bank that publishes both against its own currency
        gives a cross rate computed from those two rates (`cross_rates` is
        `true`), e.g. the Bank of England for EUR to USD. Banks that do not
        publish both codes are left out; when none does, the answer is `404`
        (`no_rates_published`).


        `meta` gives the `high` and `low` value and `spread_pct`, how far the
        highest is above the lowest in percent.

        Responses carry an `ETag` and `Cache-Control: private`. Send the
        ETag back in `If-None-Match` and an unchanged response is answered
        with `304 Not Modified` and no body (it counts as a request).
      parameters:
        - name: base_currency
          in: query
          required: true
          description: The currency to convert from.
          schema:
            type: string
            pattern: '^[A-Za-z]{3}$'
          example: EUR
        - name: currency
          in: query
          required: true
          description: The currency to convert to. Must differ from `base_currency`.
          schema:
            type: string
            pattern: '^[A-Za-z]{3}$'
          example: USD
        - name: date
          in: query
          required: false
          description: >-
            Compare the publications for this date (format `YYYY-MM-DD`):
            each bank's newest publication on or before it, from up to 14
            days before. Omit for each bank's newest publication.
          schema:
            type: string
            format: date
          example: "2026-09-26"
        - name: sources
          in: query
          required: false
          description: >-
            Comma-separated list of the central banks to compare (codes of
            `/v3/official/sources`, e.g. `ecb,fed`). By default every bank.
          style: form
          explode: false
          schema:
            type: array
            items:
              type: string
          example:
            - ecb
            - fed
        - name: format
          in: query
          required: false
          description: >-
            `json` (default), `csv`
            (`source,source_name,country,date,base_currency,currency,value,cross_rates,reference`)
            or `xlsx` (the same table as an Excel workbook,
            `official-compare.xlsx`).
          schema:
            type: string
            enum:
              - json
              - csv
              - xlsx
            default: json
      responses:
        '200':
          description: The pair as each central bank published it.
          headers:
            X-Cost:
              $ref: '#/components/headers/Cost'
            Content-Disposition:
              description: >-
                With `format=xlsx`: `attachment; filename="official-compare.xlsx"`.
              schema:
                type: string
              example: attachment; filename="official-compare.xlsx"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialCompareResponse'
              example:
                meta:
                  base_currency: "EUR"
                  currency: "USD"
                  requested_date: "2026-09-26"
                  sources: 3
                  high: 1.140645161
                  low: 1.139999977
                  spread_pct: 0.0566
                data:
                  - source: "ecb"
                    source_name: "European Central Bank"
                    country: "EU"
                    date: "2026-09-25"
                    value: 1.1403
                    cross_rates: false
                    reference: null
                  - source: "boe"
                    source_name: "Bank of England"
                    country: "GB"
                    date: "2026-09-25"
                    value: 1.140645161
                    cross_rates: true
                    reference: null
                  - source: "fed"
                    source_name: "Federal Reserve"
                    country: "US"
                    date: "2026-09-25"
                    value: 1.139999977
                    cross_rates: false
                    reference: null
            text/csv:
              schema:
                type: string
              example: |
                source,source_name,country,date,base_currency,currency,value,cross_rates,reference
                ecb,European Central Bank,EU,2026-09-25,EUR,USD,1.1403,false,
                boe,Bank of England,GB,2026-09-25,EUR,USD,1.140645161,true,
                fed,Federal Reserve,US,2026-09-25,EUR,USD,1.139999977,false,
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: binary
                description: >-
                  With `format=xlsx`: the table of `format=csv` as an Excel
                  workbook (one sheet, frozen header row, numbers as numbers).
        '304':
          description: Not modified since the response with the ETag sent in `If-None-Match`.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: >-
            No central bank (of `sources`) published both currencies for the
            requested `date` (or in the 14 days before it). `error.code` is
            `no_rates_published`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialError'
              example:
                message: "No central bank published both EUR and XAU on or shortly before 2026-09-26."
                error:
                  code: no_rates_published
                  message: "No central bank published both EUR and XAU on or shortly before 2026-09-26."
                actions:
                  sources: "https://api.currencyapi.com/v3/official/sources"
                  sign_up: "https://app.currencyapi.com/register"
                  docs: "https://currencyapi.com/docs/openapi.yaml"
                info: "For more information, see documentation: https://currencyapi.com/docs/official"
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/official/sources:
    get:
      tags:
        - Official rates
      summary: List central bank sources
      operationId: getOfficialSources
      description: >-
        Returns every central bank available as a `source`, with its country
        and region, the currency it publishes against, the kind of rate, its
        publication schedule, the dates of the stored history and the
        currencies of its newest publication. Filter by `currency` to find
        every bank that publishes a rate for it. Free: requests to this
        endpoint do not count against your quota.
      parameters:
        - name: currency
          in: query
          required: false
          description: Only banks that publish a rate for this currency, or publish against it.
          schema:
            type: string
            pattern: '^[A-Za-z]{3}$'
          example: KZT
        - name: region
          in: query
          required: false
          description: Only banks in this region.
          schema:
            type: string
            enum:
              - europe
              - asia
              - africa
              - north-america
              - south-america
              - oceania
      responses:
        '200':
          description: The available central bank sources keyed by code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialSourcesResponse'
              example:
                data:
                  ecb:
                    code: "ecb"
                    name: "European Central Bank"
                    country: "EU"
                    region: "europe"
                    base_currency: "EUR"
                    rate_type: "Euro foreign exchange reference rates"
                    schedule: "Every TARGET2 business day at around 16:00 CET"
                    website: "https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html"
                    history:
                      from: "1999-01-04"
                      to: "2026-09-28"
                    currencies:
                      - AUD
                      - BRL
                      - CAD
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/currencies:
    get:
      tags:
        - Metadata
      summary: List supported currencies
      operationId: getCurrencies
      description: >-
        Returns metadata for all supported currencies, optionally filtered by
        code or type.
      parameters:
        - $ref: '#/components/parameters/Currencies'
        - $ref: '#/components/parameters/Type'
        - name: as_html
          in: query
          required: false
          description: >-
            When `true`, returns an HTML table of currency codes and names
            instead of a JSON payload.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: Supported currency metadata keyed by currency code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrenciesResponse'
              example:
                data:
                  AED:
                    symbol: "AED"
                    name: "UAE Dirham"
                    symbol_native: "د.إ"
                    decimal_digits: 2
                    rounding: 0
                    code: "AED"
                    name_plural: "UAE dirhams"
                    type: "fiat"
                    countries:
                      - "AE"
                  BTC:
                    symbol: "₿"
                    name: "Bitcoin"
                    symbol_native: "₿"
                    decimal_digits: 8
                    rounding: 0
                    code: "BTC"
                    name_plural: "Bitcoin"
                    type: "crypto"
                    countries: []
            text/html:
              schema:
                type: string
              example: "<table><tr><th>Code</th><th>Name</th></tr><tr><td>AED</td><td>UAE Dirham</td></tr></table>"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/countries:
    get:
      tags:
        - Metadata
      summary: List countries
      operationId: getCountries
      description: >-
        Returns the list of countries known to currencyapi, including their
        associated currency information.
      responses:
        '200':
          description: Country metadata.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CountriesResponse'
              example:
                data:
                  AE:
                    alpha2: "AE"
                    alpha3: "ARE"
                    calling_codes:
                      - "+971"
                    currencies:
                      - "AED"
                    emoji: "🇦🇪"
                    ioc: "UAE"
                    languages:
                      - name: "Arabic"
                        name_native: "العربية"
                    name: "United Arab Emirates"
                    name_translated: "United Arab Emirates"
                    timezones:
                      - "Asia/Dubai"
                    is_in_european_union: false
                    tld: ".ae"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v3/status:
    get:
      tags:
        - Metadata
      summary: Account quota status
      operationId: getStatus
      description: >-
        Returns your current monthly and grace quota usage and the plan of your
        API key's account. Requests to this endpoint do not count against your
        quota or rate limit.
      responses:
        '200':
          description: Current quota usage for the authenticated account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StatusResponse'
              example:
                account_id: 313373133731337
                account_id_str: "313373133731337"
                quotas:
                  month:
                    total: 300
                    used: 72
                    remaining: 228
                  grace:
                    total: 0
                    used: 0
                    remaining: 0
                plan:
                  name: "free"
                  interval: "month"
                  price_id: "price_1AbCdEfGhIjKlMnOpQrStUvW"
                  free: true
                  custom: false
                  status: "active"
                  renews_at: "2026-11-01T00:00:00+00:00"
                  scheduled: null
                  upgrade_url: "https://app.currencyapi.com/upgrade?utm_source=agent&utm_campaign=status&team=313373133731337"
                  plans_url: "https://api.currencyapi.com/v1/agent/plans"
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  securitySchemes:
    ApiKeyQuery:
      type: apiKey
      in: query
      name: apikey
      description: API key passed as the `apikey` query parameter.
    ApiKeyHeader:
      type: apiKey
      in: header
      name: apikey
      description: >-
        API key passed as the `apikey` request header. This is the recommended
        method as it keeps the key out of URLs and access logs.
  parameters:
    BaseCurrency:
      name: base_currency
      in: query
      required: false
      description: >-
        The base currency that all returned values are relative to. Defaults to
        `USD`.
      schema:
        $ref: '#/components/schemas/CurrencyCode'
    Currencies:
      name: currencies
      in: query
      required: false
      description: >-
        Comma-separated list of currency codes to include (e.g. `EUR,USD,CAD`).
        The array form `currencies[]=EUR&currencies[]=USD` is also accepted. By
        default all supported currencies are returned.
      style: form
      explode: false
      schema:
        type: array
        items:
          $ref: '#/components/schemas/CurrencyCode'
      example:
        - EUR
        - USD
        - CAD
    Format:
      name: format
      in: query
      required: false
      description: >-
        `json` (default), `csv` or `xlsx`. CSV has a header line and one row
        per currency (and point in time), values without exponent notation.
        `xlsx` is the same table as an Excel workbook (one sheet, bold frozen
        header row, numbers as numbers), sent as a download named after the
        endpoint, e.g. `latest.xlsx`.
      schema:
        type: string
        enum:
          - json
          - csv
          - xlsx
        default: json
    Shape:
      name: shape
      in: query
      required: false
      description: >-
        `default`: every rate as `{"code": "EUR", "value": 0.918456}`.
        `compact`: plain values, `"EUR": 0.918456`.
      schema:
        type: string
        enum:
          - default
          - compact
        default: default
    Inverse:
      name: inverse
      in: query
      required: false
      description: >-
        `true` adds `inverse` to every rate: the value of one unit of the
        currency in the base currency (1 / value). Not with `shape=compact`.
      schema:
        type: boolean
        default: false
    Precision:
      name: precision
      in: query
      required: false
      description: >-
        Round every value to this many decimals (0 to 10). By default values
        carry up to 10 decimals (10 significant digits below 0.1).
      schema:
        type: integer
        minimum: 0
        maximum: 10
      example: 4
    Type:
      name: type
      in: query
      required: false
      description: Filter the returned currencies by type.
      schema:
        type: string
        enum:
          - fiat
          - metal
          - crypto
    OfficialSource:
      name: source
      in: query
      required: true
      description: >-
        The central bank whose official rates to return. See
        `/v3/official/sources` for each bank's currencies and history.
      schema:
        type: string
        enum:
          - ecb
          - boe
          - cnb
          - nbp
          - norges
          - riksbank
          - nationalbanken
          - mnb
          - bnr
          - nbu
          - tcmb
          - nbm
          - nbrm
          - cbbh
          - cbr
          - nbg
          - cba
          - cbar
          - nbk
          - cbu
          - nbt
          - boi
          - pboc
          - bnm
          - bi
          - nrb
          - rba
          - fed
          - boc
          - bcb
          - bcra
          - bcrp
          - sfc
          - cbn
          - sarb
        x-enumDescriptions:
          ecb: European Central Bank (EUR)
          boe: Bank of England (GBP)
          cnb: Czech National Bank (CZK)
          nbp: National Bank of Poland (PLN)
          norges: Norges Bank (NOK)
          riksbank: Sveriges Riksbank (SEK)
          nationalbanken: Danmarks Nationalbank (DKK)
          mnb: Magyar Nemzeti Bank (HUF)
          bnr: National Bank of Romania (RON)
          nbu: National Bank of Ukraine (UAH)
          tcmb: Central Bank of the Republic of Türkiye (TRY)
          nbm: National Bank of Moldova (MDL)
          nbrm: National Bank of the Republic of North Macedonia (MKD)
          cbbh: Central Bank of Bosnia and Herzegovina (BAM)
          cbr: Bank of Russia (RUB)
          nbg: National Bank of Georgia (GEL)
          cba: Central Bank of Armenia (AMD)
          cbar: Central Bank of the Republic of Azerbaijan (AZN)
          nbk: National Bank of Kazakhstan (KZT)
          cbu: Central Bank of the Republic of Uzbekistan (UZS)
          nbt: National Bank of Tajikistan (TJS)
          boi: Bank of Israel (ILS)
          pboc: People's Bank of China (CNY)
          bnm: Bank Negara Malaysia (MYR)
          bi: Bank Indonesia (IDR)
          nrb: Nepal Rastra Bank (NPR)
          rba: Reserve Bank of Australia (AUD)
          fed: Federal Reserve (USD)
          boc: Bank of Canada (CAD)
          bcb: Banco Central do Brasil (BRL)
          bcra: Banco Central de la República Argentina (ARS)
          bcrp: Banco Central de Reserva del Perú (PEN)
          sfc: Superintendencia Financiera de Colombia (COP)
          cbn: Central Bank of Nigeria (NGN)
          sarb: South African Reserve Bank (ZAR)
      example: ecb
    OfficialBaseCurrency:
      name: base_currency
      in: query
      required: false
      description: >-
        The currency all values are relative to. Defaults to the bank's own
        currency, which gives the official values as published; any other
        currency the bank publishes gives cross rates calculated from them.
      schema:
        type: string
        pattern: '^[A-Za-z]{3}$'
      example: USD
    OfficialFormat:
      name: format
      in: query
      required: false
      description: >-
        `json` (default), `csv` or `xlsx`. CSV has one row per currency and
        publication: `date,source,base_currency,currency,value,reference`
        (plus `market,difference_pct` with `compare=market`), values without
        exponent notation, ready for spreadsheets. `xlsx` is the same table
        as an Excel workbook (one sheet, bold frozen header row, numbers as
        numbers), sent as the download `official.xlsx`.
      schema:
        type: string
        enum:
          - json
          - csv
          - xlsx
        default: json
    OfficialCompare:
      name: compare
      in: query
      required: false
      description: >-
        `market` adds the market rate of the publication day to each rate:
        `market`, that day's close from `/v3/historical` (for a publication
        dated today, the latest market rate at your plan's update interval),
        and `difference_pct`, (official / market − 1) × 100 with 4 decimals.
        Both are null where the market has no rate for the currency or the
        base currency. Adds `market_last_updated_at`, when that market rate
        is from.
      schema:
        type: string
        enum:
          - market
    OfficialCurrencies:
      name: currencies
      in: query
      required: false
      description: >-
        Comma-separated list of currency codes to include (e.g. `USD,GBP`).
        Codes the bank does not publish are left out. By default every
        currency of the publication is returned.
      style: form
      explode: false
      schema:
        type: array
        items:
          type: string
          pattern: '^[A-Za-z]{3}$'
      example:
        - USD
        - GBP
  headers:
    RateLimitLimitQuotaMonth:
      description: Your monthly request quota.
      schema:
        type: integer
      example: 300
    RateLimitRemainingQuotaMonth:
      description: Remaining requests in your monthly quota.
      schema:
        type: integer
      example: 228
    Cost:
      description: >-
        Number of requests this call counted against your quota (0 for sandbox
        keys). Only successful responses from the data endpoints carry this
        header.
      schema:
        type: integer
      example: 1
  responses:
    Unauthorized:
      description: >-
        The API key is missing or invalid: every request needs one, in the
        `apikey` header or query parameter. Without a key the message is "No
        API key found in request" (`error.code` `missing_api_key`), with an
        unknown key "Unauthorized" (`invalid_api_key`). `actions.sign_up`
        creates an account with a free API key. `actions` can also carry
        `agent_setup` (setup steps for AI coding agents), `pricing` (the plans
        as JSON) and `openapi`; `docs` then points to the docs' llms.txt
        (example `missing_api_key_agent_links`).
      headers:
        WWW-Authenticate:
          description: Always `Key`.
          schema: { type: string }
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
          examples:
            missing_api_key:
              summary: No API key sent
              value:
                message: "No API key found in request"
                error: { code: "missing_api_key", message: "No API key found in request" }
                actions:
                  sign_up: "https://app.currencyapi.com/register?utm_source=api_error&utm_campaign=missing_api_key"
                  docs: "https://currencyapi.com/docs/openapi.yaml"
            invalid_api_key:
              summary: Unknown API key
              value:
                message: "Unauthorized"
                error: { code: "invalid_api_key", message: "Unauthorized" }
                actions:
                  sign_up: "https://app.currencyapi.com/register?utm_source=api_error&utm_campaign=invalid_api_key"
                  docs: "https://currencyapi.com/docs/openapi.yaml"
            missing_api_key_agent_links:
              summary: No API key sent, with the links for AI coding agents
              value:
                message: "No API key found in request"
                error: { code: "missing_api_key", message: "No API key found in request" }
                actions:
                  agent_setup: "https://currencyapi.com/agents.md"
                  sign_up: "https://app.currencyapi.com/register?utm_source=api_error&utm_campaign=missing_api_key"
                  pricing: "https://api.currencyapi.com/v1/agent/plans"
                  docs: "https://currencyapi.com/docs/llms.txt"
                  openapi: "https://currencyapi.com/docs/openapi.yaml"
    Forbidden:
      description: >-
        Your plan does not permit this endpoint or parameter combination.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            message: "You are not allowed to use the convert endpoint, please upgrade your plan"
            info: "For more information, see documentation: https://currencyapi.com/docs/status-codes#_403"
    ValidationError:
      description: One or more request parameters failed validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationError'
          example:
            message: "Validation error"
            errors:
              base_currency:
                - "The selected base currency is invalid."
            info: "For more information, see documentation: https://currencyapi.com/docs/status-codes#_422"
    NoOfficialRates:
      description: >-
        The bank published no rates for the requested date (or in the 14 days
        before it) or range, e.g. because the date lies before its history
        starts. `error.code` is `no_rates_published`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OfficialError'
          example:
            message: "European Central Bank published no official rates on 1998-06-01 or in the 14 days before it."
            error:
              code: no_rates_published
              message: "European Central Bank published no official rates on 1998-06-01 or in the 14 days before it."
            actions:
              sign_up: "https://app.currencyapi.com/register"
              docs: "https://currencyapi.com/docs/openapi.yaml"
              sources: "https://api.currencyapi.com/v3/official/sources"
            info: "For more information, see documentation: https://currencyapi.com/docs/official"
    RateLimited:
      description: >-
        A limit is used up. `error.code` says which: `quota_exceeded` (the
        month's requests; `quota.resets_at` says when they come back),
        `grace_quota_exceeded` (the grace quota of an unpaid invoice:
        `actions.complete_payment` pays it), `overage_quota_exceeded` (the
        overage budget) or `rate_limit_exceeded` (the free plan's 10 requests
        a minute). Quota errors carry `quota`. Only successful requests count
        against your quota. `actions.upgrade` opens the plans of the API key's
        account. `actions` can also carry `pricing` (the plans as JSON) and
        `openapi`; `docs` then points to the docs' llms.txt (the examples
        ending in `_agent_links`).
      headers:
        Retry-After:
          description: >-
            Seconds until the next full minute, with the requests-per-minute
            `rate_limit_exceeded` of an API key. A used-up quota has none: it
            lasts until `quota.resets_at`.
          schema: { type: integer }
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
          examples:
            quota_exceeded:
              summary: The month's requests are used up
              value:
                message: "You used all your monthly requests. Please upgrade your plan at https://app.currencyapi.com/upgrade"
                error: { code: "quota_exceeded", message: "You used all your monthly requests. Please upgrade your plan at https://app.currencyapi.com/upgrade" }
                quota: { limit: 300, used: 300, remaining: 0, resets_at: "2026-11-01T00:00:00+00:00" }
                actions:
                  upgrade: "https://app.currencyapi.com/upgrade?utm_source=api_error&utm_campaign=quota_exceeded&team=7123456789012345678"
                  docs: "https://currencyapi.com/docs/openapi.yaml"
            rate_limit_exceeded:
              summary: The requests per minute are used up
              value:
                message: "API rate limit exceeded"
                error: { code: "rate_limit_exceeded", message: "API rate limit exceeded" }
                actions:
                  upgrade: "https://app.currencyapi.com/upgrade?utm_source=api_error&utm_campaign=rate_limit_exceeded&team=7123456789012345678"
                  docs: "https://currencyapi.com/docs/openapi.yaml"
            quota_exceeded_agent_links:
              summary: The month's requests are used up, with the links for AI coding agents
              value:
                message: "You used all your monthly requests. Please upgrade your plan at https://app.currencyapi.com/upgrade"
                error: { code: "quota_exceeded", message: "You used all your monthly requests. Please upgrade your plan at https://app.currencyapi.com/upgrade" }
                quota: { limit: 300, used: 300, remaining: 0, resets_at: "2026-11-01T00:00:00+00:00" }
                actions:
                  upgrade: "https://app.currencyapi.com/upgrade?utm_source=api_error&utm_campaign=quota_exceeded&team=7123456789012345678"
                  pricing: "https://api.currencyapi.com/v1/agent/plans"
                  docs: "https://currencyapi.com/docs/llms.txt"
                  openapi: "https://currencyapi.com/docs/openapi.yaml"
            rate_limit_exceeded_agent_links:
              summary: The requests per minute are used up, with the links for AI coding agents
              value:
                message: "API rate limit exceeded"
                error: { code: "rate_limit_exceeded", message: "API rate limit exceeded" }
                actions:
                  upgrade: "https://app.currencyapi.com/upgrade?utm_source=api_error&utm_campaign=rate_limit_exceeded&team=7123456789012345678"
                  pricing: "https://api.currencyapi.com/v1/agent/plans"
                  docs: "https://currencyapi.com/docs/llms.txt"
                  openapi: "https://currencyapi.com/docs/openapi.yaml"
  schemas:
    CurrencyCode:
      type: string
      description: >-
        A supported currency code (ISO 4217 for fiat and metals, common tickers
        for crypto).
      enum:
        - AED
        - AFN
        - ALL
        - AMD
        - ANG
        - AOA
        - ARS
        - AUD
        - AWG
        - AZN
        - BAM
        - BBD
        - BDT
        - BGN
        - BHD
        - BIF
        - BMD
        - BND
        - BOB
        - BRL
        - BSD
        - BTN
        - BWP
        - BYN
        - BYR
        - BZD
        - CAD
        - CDF
        - CHF
        - CLF
        - CLP
        - CNY
        - COP
        - CRC
        - CUC
        - CUP
        - CVE
        - CZK
        - DJF
        - DKK
        - DOP
        - DZD
        - EGP
        - ERN
        - ETB
        - EUR
        - FJD
        - FKP
        - GBP
        - GEL
        - GGP
        - GHS
        - GIP
        - GMD
        - GNF
        - GTQ
        - GYD
        - HKD
        - HNL
        - HRK
        - HTG
        - HUF
        - IDR
        - ILS
        - IMP
        - INR
        - IQD
        - IRR
        - ISK
        - JEP
        - JMD
        - JOD
        - JPY
        - KES
        - KGS
        - KHR
        - KMF
        - KPW
        - KRW
        - KWD
        - KYD
        - KZT
        - LAK
        - LBP
        - LKR
        - LRD
        - LSL
        - LTL
        - LVL
        - LYD
        - MAD
        - MDL
        - MGA
        - MKD
        - MMK
        - MNT
        - MOP
        - MRO
        - MUR
        - MVR
        - MWK
        - MXN
        - MYR
        - MZN
        - NAD
        - NGN
        - NIO
        - NOK
        - NPR
        - NZD
        - OMR
        - PAB
        - PEN
        - PGK
        - PHP
        - PKR
        - PLN
        - PYG
        - QAR
        - RON
        - RSD
        - RUB
        - RWF
        - SAR
        - SBD
        - SCR
        - SDG
        - SEK
        - SGD
        - SHP
        - SLL
        - SOS
        - SRD
        - STD
        - SVC
        - SYP
        - SZL
        - THB
        - TJS
        - TMT
        - TND
        - TOP
        - TRY
        - TTD
        - TWD
        - TZS
        - UAH
        - UGX
        - USD
        - UYU
        - UZS
        - VEF
        - VND
        - VUV
        - WST
        - XAF
        - XAG
        - XAU
        - XCD
        - XDR
        - XOF
        - XPF
        - YER
        - ZAR
        - ZMK
        - ZMW
        - ZWL
        - XPT
        - XPD
        - BTC
        - ETH
        - BNB
        - XRP
        - SOL
        - DOT
        - AVAX
        - MATIC
        - LTC
        - ADA
        - USDT
        - USDC
        - DAI
        - ARB
        - OP
        - TRX
        - VES
        - STN
        - MRU
        - ZWG
        - SLE
        - XCG
    CurrencyRate:
      type: object
      description: A single currency rate entry.
      properties:
        code:
          $ref: '#/components/schemas/CurrencyCode'
        value:
          type: number
          description: The conversion rate relative to the base currency.
          example: 3.67306
        inverse:
          type:
            - number
            - 'null'
          description: With `inverse=true`, the value of one unit of the currency in the base currency.
          example: 0.2722548
        change:
          type:
            - number
            - 'null'
          description: With `include=change`, the change since the previous day's close.
          example: 0.00012
        change_pct:
          type:
            - number
            - 'null'
          description: With `include=change`, that change in percent.
          example: 0.0033
        rounded:
          type: number
          description: >-
            Convert with `round_step` or `price_ending`: the converted value
            rounded as a shop price (`value` stays exact).
          example: 10.99
        formatted:
          type: string
          description: >-
            Convert with `locale`: the amount as text in that locale, with the
            currency's symbol and decimal places; the rounded price when
            rounding is on.
          example: "€\u00a01.233,99"
      required:
        - code
        - value
    RatesMap:
      type: object
      description: >-
        Map of currency code to its rate entry, or to the plain value with
        `shape=compact`.
      additionalProperties:
        oneOf:
          - $ref: '#/components/schemas/CurrencyRate'
          - type: number
    ExchangeRatesResponse:
      type: object
      description: Standard rates response used by latest, historical and convert.
      properties:
        meta:
          type: object
          properties:
            last_updated_at:
              type: string
              format: date-time
              description: When this dataset was last updated (ISO 8601, UTC).
              example: "2023-06-23T10:15:59Z"
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            date:
              type: string
              format: date
              description: The requested date (historical, and convert with `date`).
              example: "2022-01-01"
            value:
              type: number
              description: The converted value (convert with `value`).
              example: 12
            change_since:
              type: string
              format: date-time
              description: With `include=change`, the close the change is measured from.
              example: "2023-06-21T23:59:59Z"
          required:
            - last_updated_at
        data:
          $ref: '#/components/schemas/RatesMap'
      required:
        - meta
        - data
    ConvertValuesResponse:
      type: object
      description: '`/v3/convert` with `values`: one entry per value, in the order sent.'
      properties:
        meta:
          type: object
          properties:
            last_updated_at:
              type: string
              format: date-time
              description: When the rates used were last updated (ISO 8601, UTC).
              example: "2026-09-29T23:59:59Z"
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            values:
              type: array
              description: The values converted, in the order sent.
              items:
                type: number
            date:
              type: string
              format: date
              description: The requested date, when one was sent.
              example: "2022-01-01"
          required:
            - last_updated_at
            - base_currency
            - values
        data:
          type: array
          items:
            type: object
            properties:
              value:
                type: number
                description: The value converted.
                example: 10
              currencies:
                $ref: '#/components/schemas/RatesMap'
            required:
              - value
              - currencies
      required:
        - meta
        - data
    HistoricalDatesResponse:
      type: object
      description: '`/v3/historical` with `dates`: the rates keyed by date.'
      properties:
        meta:
          type: object
          properties:
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            dates:
              type: array
              description: The dates answered, each once, oldest first.
              items:
                type: string
                format: date
          required:
            - base_currency
            - dates
        data:
          type: object
          description: Map of date (`YYYY-MM-DD`) to the rates of that day's close.
          additionalProperties:
            $ref: '#/components/schemas/RatesMap'
      required:
        - meta
        - data
    RateResponse:
      type: object
      properties:
        meta:
          type: object
          properties:
            last_updated_at:
              type: string
              format: date-time
              description: The moment the rate applies to (ISO 8601, UTC).
              example: "2023-06-23T10:15:59Z"
          required:
            - last_updated_at
        data:
          type: object
          properties:
            from:
              $ref: '#/components/schemas/CurrencyCode'
            to:
              $ref: '#/components/schemas/CurrencyCode'
            rate:
              type: number
              description: Units of `to` for one unit of `from`.
              example: 1.0887771
            inverse:
              type:
                - number
                - 'null'
              description: Units of `from` for one unit of `to`.
              example: 0.918456
          required:
            - from
            - to
            - rate
            - inverse
      required:
        - meta
        - data
    MatrixResponse:
      type: object
      properties:
        meta:
          type: object
          properties:
            last_updated_at:
              type: string
              format: date-time
              example: "2023-06-23T10:15:59Z"
            currencies:
              type: array
              description: The currencies of the rows and columns, in order.
              items:
                $ref: '#/components/schemas/CurrencyCode'
          required:
            - last_updated_at
            - currencies
        data:
          type: object
          description: >-
            One row per base currency: `data.EUR.USD` is the price of 1 EUR in
            USD. Null where a currency has no rate.
          additionalProperties:
            type: object
            additionalProperties:
              type:
                - number
                - 'null'
      required:
        - meta
        - data
    RangeResponse:
      type: object
      description: >-
        One point per datetime, or with `orient=currency` one series per
        currency.
      properties:
        meta:
          type: object
          description: The range as requested. Not in CSV.
          properties:
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            accuracy:
              type: string
              example: day
            datetime_start:
              type: string
              format: date-time
              example: "2022-01-01T00:00:00Z"
            datetime_end:
              type: string
              format: date-time
              example: "2022-01-02T00:00:00Z"
        data:
          oneOf:
            - $ref: '#/components/schemas/RangePoints'
            - $ref: '#/components/schemas/RangeSeries'
      required:
        - data
    RangeSeries:
      type: object
      description: >-
        `orient=currency`: map of currency code to its points, oldest first;
        each point is `{datetime, value}`, or `[datetime, value]` with
        `shape=compact`.
      additionalProperties:
        type: array
        items:
          oneOf:
            - type: object
              properties:
                datetime:
                  type: string
                  format: date-time
                value:
                  type: number
              required:
                - datetime
                - value
            - type: array
              prefixItems:
                - type: string
                  format: date-time
                - type: number
              minItems: 2
              maxItems: 2
    RangePoints:
      type: array
      description: One point per datetime (the default).
      items:
        type: object
        properties:
          datetime:
            type: string
            format: date-time
            description: The datetime this interval's rates apply to.
            example: "2022-01-01T23:59:59Z"
          currencies:
            $ref: '#/components/schemas/RatesMap'
        required:
          - datetime
          - currencies
    OhlcResponse:
      type: object
      properties:
        meta:
          type: object
          description: The range as answered. Not in CSV.
          properties:
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            interval:
              type: string
              enum: [hour, day]
            datetime_start:
              type: string
              format: date-time
              description: Start of the first candle.
              example: "2026-09-30T10:00:00Z"
            datetime_end:
              type: string
              format: date-time
              description: Start of the last candle (the end, or now when the end is in the future).
              example: "2026-09-30T11:00:00Z"
          required: [base_currency, interval, datetime_start, datetime_end]
        data:
          type: object
          description: >-
            Map of currency code to its candles, oldest first; each candle is
            an object, or `[datetime, open, high, low, close]` with
            `shape=compact`.
          additionalProperties:
            type: array
            items:
              oneOf:
                - $ref: '#/components/schemas/Candle'
                - type: array
                  prefixItems:
                    - type: string
                      format: date-time
                    - type: number
                    - type: number
                    - type: number
                    - type: number
                  minItems: 5
                  maxItems: 5
      required: [meta, data]
    Candle:
      type: object
      properties:
        datetime:
          type: string
          format: date-time
          description: Start of the hour or day.
          example: "2026-09-30T10:00:00Z"
        open:
          type: number
          description: The close of the candle before.
          example: 0.91
        high:
          type: number
          description: The highest rate in the candle.
          example: 0.95
        low:
          type: number
          description: The lowest rate in the candle.
          example: 0.9
        close:
          type: number
          description: The stored rate at the end of the hour or day.
          example: 0.92
      required: [datetime, open, high, low, close]
    FluctuationResponse:
      type: object
      properties:
        meta:
          type: object
          properties:
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            date_from:
              type: string
              format: date
            date_to:
              type: string
              format: date
          required: [base_currency, date_from, date_to]
        data:
          type: object
          description: Map of currency code to its change.
          additionalProperties:
            type: object
            properties:
              code:
                $ref: '#/components/schemas/CurrencyCode'
              start_rate:
                type: number
                description: Rate at the end of `date_from`.
              end_rate:
                type: number
                description: Rate at the end of `date_to`.
              change:
                type: number
                description: '`end_rate - start_rate`.'
              change_pct:
                type: number
                description: Change in percent of `start_rate`, 4 decimals.
              high:
                type:
                  - number
                  - 'null'
                description: >-
                  Highest daily close from `date_from` to `date_to`. Null when
                  the span is longer than 1830 days or has no data. Not in CSV.
              low:
                type:
                  - number
                  - 'null'
                description: >-
                  Lowest daily close from `date_from` to `date_to`. Null like
                  `high`. Not in CSV.
              average:
                type:
                  - number
                  - 'null'
                description: >-
                  Average of the daily closes from `date_from` to `date_to`, as
                  `/v3/average` with `period=total` computes it. Null like
                  `high`. Not in CSV.
            required: [code, start_rate, end_rate, change, change_pct, high, low, average]
      required: [meta, data]
    AverageResponse:
      type: object
      properties:
        meta:
          type: object
          properties:
            source:
              type: string
              description: '`market`, or the central bank code given in `source`.'
            base_currency:
              $ref: '#/components/schemas/CurrencyCode'
            period:
              type: string
              enum: [month, quarter, year, total]
            date_from:
              type: string
              format: date
            date_to:
              type: string
              format: date
          required: [source, base_currency, period, date_from, date_to]
        data:
          type: array
          items:
            type: object
            properties:
              period:
                type: string
                description: '`2026-01`, `2026-Q1`, `2026`, or `date_from/date_to` for `total`.'
              date_from:
                type: string
                format: date
                description: First day with data in this period.
              date_to:
                type: string
                format: date
                description: Last day with data in this period.
              days:
                type: integer
                description: Number of days (or publications) averaged.
              currencies:
                type: object
                additionalProperties:
                  type: object
                  properties:
                    code:
                      $ref: '#/components/schemas/CurrencyCode'
                    value:
                      type: number
                      description: Average rate over the period.
                    min:
                      type: number
                      description: Lowest daily rate in the period.
                    max:
                      type: number
                      description: Highest daily rate in the period.
                  required: [code, value, min, max]
            required: [period, date_from, date_to, days, currencies]
      required: [meta, data]
    CurrencyInfo:
      type: object
      properties:
        symbol:
          type: string
          example: "AED"
        name:
          type: string
          example: "UAE Dirham"
        symbol_native:
          type: string
          example: "د.إ"
        decimal_digits:
          type: integer
          example: 2
        rounding:
          type: number
          example: 0
        code:
          $ref: '#/components/schemas/CurrencyCode'
        name_plural:
          type: string
          example: "UAE dirhams"
        type:
          type: string
          enum:
            - fiat
            - metal
            - crypto
        countries:
          type: array
          description: ISO 3166-1 alpha-2 country codes that use this currency.
          items:
            type: string
          example:
            - "AE"
    CurrenciesResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/CurrencyInfo'
      required:
        - data
    CountriesResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties:
            type: object
      required:
        - data
    StatusResponse:
      type: object
      properties:
        account_id:
          type: integer
          description: Your account (team) id.
          example: 313373133731337
        account_id_str:
          type: string
          description: >-
            The same id as `account_id`, as a string for JavaScript clients,
            whose numbers lose precision above 2^53.
          example: "313373133731337"
        quotas:
          type: object
          properties:
            month:
              $ref: '#/components/schemas/QuotaBucket'
            grace:
              $ref: '#/components/schemas/QuotaBucket'
          required:
            - month
        plan:
          type: object
          description: >-
            The plan of the API key's account, so you can check that an upgrade
            took effect.
          properties:
            name: { type: [string, "null"], example: "free" }
            interval: { type: [string, "null"], example: "month" }
            price_id: { type: [string, "null"] }
            free: { type: [boolean, "null"], example: true }
            custom:
              type: boolean
              description: A plan made for this account only; it has no `upgrade_url`.
              example: false
            status:
              type: [string, "null"]
              description: The status of the subscription, e.g. `active` or `past_due`.
              example: "active"
            renews_at: { type: [string, "null"], format: date-time, example: "2026-11-01T00:00:00+00:00" }
            scheduled:
              type: [object, "null"]
              description: A plan change that starts later, e.g. a downgrade at the end of the period.
              properties:
                name: { type: [string, "null"] }
                interval: { type: [string, "null"], example: "month" }
                starts_at: { type: string, format: date-time }
            upgrade_url:
              type: [string, "null"]
              format: uri
              description: Opens the plans of this account. `null` for a custom plan.
            plans_url:
              type: string
              format: uri
              description: Every plan as JSON.
              example: "https://api.currencyapi.com/v1/agent/plans"
      required:
        - quotas
    QuotaBucket:
      type: object
      properties:
        total:
          type: integer
          example: 300
        used:
          type: integer
          example: 72
        remaining:
          type: integer
          example: 228
    OfficialRatesMeta:
      type: object
      properties:
        source:
          type: string
          description: The central bank the rates come from.
          example: "nbp"
        source_name:
          type: string
          example: "National Bank of Poland"
        date:
          type: string
          format: date
          description: The date the bank published the returned rates for.
          example: "2026-09-28"
        requested_date:
          type:
            - string
            - "null"
          format: date
          description: The `date` you asked for, or null for the newest publication.
          example: "2026-09-28"
        base_currency:
          type: string
          description: The currency all values are relative to.
          example: "USD"
        source_base_currency:
          type: string
          description: The currency the bank publishes its rates against.
          example: "PLN"
        cross_rates:
          type: boolean
          description: >-
            True when `base_currency` differs from `source_base_currency`, i.e.
            the values are calculated from the official rates rather than
            published by the bank.
        reference:
          type:
            - string
            - "null"
          description: >-
            The bank's own identifier for the publication, e.g. the NBP table
            number or the TCMB bulletin number. Null for banks without one.
          example: "188/A/NBP/2026"
        last_updated_at:
          type: string
          format: date-time
          description: When currencyapi last imported or updated this publication (ISO 8601, UTC).
          example: "2026-09-28T10:07:12Z"
        market_last_updated_at:
          type:
            - string
            - "null"
          format: date-time
          description: >-
            Only with `compare=market`: when the market rates in `market` are
            from (the day's close, e.g. `2026-09-25T23:59:59Z`). Null when the
            market has no rates for the day.
          example: "2026-09-25T23:59:59Z"
      required:
        - source
        - source_name
        - date
        - requested_date
        - base_currency
        - source_base_currency
        - cross_rates
        - reference
        - last_updated_at
    OfficialRate:
      type: object
      properties:
        code:
          type: string
          description: ISO 4217 currency code.
          example: "PLN"
        value:
          type: number
          description: Units of this currency per 1 unit of `base_currency`.
          example: 3.8478
        market:
          type:
            - number
            - "null"
          description: >-
            Only with `compare=market`: the market rate for the publication
            day, in the same units as `value`. Null where the market has no
            rate for the currency or `base_currency`.
          example: 1.1402508552
        difference_pct:
          type:
            - number
            - "null"
          description: >-
            Only with `compare=market`: (value / market − 1) × 100, 4
            decimals. Positive when the official rate is above the market.
          example: 0.0043
      required:
        - code
        - value
    OfficialRatesMap:
      type: object
      description: Map of currency code to its official rate.
      additionalProperties:
        $ref: '#/components/schemas/OfficialRate'
    OfficialRatesResponse:
      type: object
      properties:
        meta:
          $ref: '#/components/schemas/OfficialRatesMeta'
        data:
          $ref: '#/components/schemas/OfficialRatesMap'
      required:
        - meta
        - data
    OfficialRangeResponse:
      type: object
      properties:
        meta:
          type: object
          properties:
            source:
              type: string
              example: "ecb"
            source_name:
              type: string
              example: "European Central Bank"
            base_currency:
              type: string
              example: "EUR"
            source_base_currency:
              type: string
              example: "EUR"
            cross_rates:
              type: boolean
          required:
            - source
            - source_name
            - base_currency
            - source_base_currency
            - cross_rates
        data:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
                example: "2026-09-25"
              reference:
                type:
                  - string
                  - "null"
                example: null
              currencies:
                $ref: '#/components/schemas/OfficialRatesMap'
              market_last_updated_at:
                type:
                  - string
                  - "null"
                format: date-time
                description: >-
                  Only with `compare=market`: when this entry's market rates
                  are from. Null when the market has no rates for the day.
                example: "2026-09-25T23:59:59Z"
            required:
              - date
              - reference
              - currencies
      required:
        - meta
        - data
    OfficialCompareResponse:
      type: object
      properties:
        meta:
          type: object
          properties:
            base_currency:
              type: string
              example: "EUR"
            currency:
              type: string
              example: "USD"
            requested_date:
              type:
                - string
                - "null"
              format: date
              description: The `date` you asked for, or null for the newest publications.
              example: "2026-09-26"
            sources:
              type: integer
              description: The number of central banks in `data`.
              example: 3
            high:
              type: number
              description: The highest `value` in `data`.
              example: 1.140645161
            low:
              type: number
              description: The lowest `value` in `data`.
              example: 1.139999977
            spread_pct:
              type:
                - number
                - "null"
              description: (high / low − 1) × 100, 4 decimals.
              example: 0.0566
          required:
            - base_currency
            - currency
            - requested_date
            - sources
            - high
            - low
            - spread_pct
        data:
          type: array
          description: One entry per central bank that published both currencies.
          items:
            type: object
            properties:
              source:
                type: string
                example: "ecb"
              source_name:
                type: string
                example: "European Central Bank"
              country:
                type: string
                description: ISO 3166-1 alpha-2 code of the bank's country (`EU` for the ECB).
                example: "EU"
              date:
                type: string
                format: date
                description: The date of the bank's publication the value comes from.
                example: "2026-09-25"
              value:
                type: number
                description: >-
                  Units of `currency` per 1 unit of `base_currency`, as the
                  bank published it.
                example: 1.1403
              cross_rates:
                type: boolean
                description: >-
                  True when neither currency is the bank's own, i.e. the value
                  is computed from two of its official rates.
              reference:
                type:
                  - string
                  - "null"
                description: The bank's own identifier for the publication, or null.
                example: null
            required:
              - source
              - source_name
              - country
              - date
              - value
              - cross_rates
              - reference
      required:
        - meta
        - data
    OfficialSourceInfo:
      type: object
      properties:
        code:
          type: string
          example: "ecb"
        name:
          type: string
          example: "European Central Bank"
        country:
          type: string
          description: ISO 3166-1 alpha-2 code of the bank's country (`EU` for the ECB).
          example: "EU"
        region:
          type: string
          enum:
            - europe
            - asia
            - africa
            - north-america
            - south-america
            - oceania
        base_currency:
          type: string
          description: The currency the bank publishes its rates against.
          example: "EUR"
        rate_type:
          type: string
          description: What kind of rate the bank publishes.
          example: "Euro foreign exchange reference rates"
        schedule:
          type: string
          description: When the bank publishes.
          example: "Every TARGET2 business day at around 16:00 CET"
        website:
          type: string
          format: uri
          description: The bank's own page for these rates.
        history:
          type:
            - object
            - "null"
          description: The first and last date of the stored history.
          properties:
            from:
              type: string
              format: date
              example: "1999-01-04"
            to:
              type: string
              format: date
              example: "2026-09-28"
        currencies:
          type: array
          description: The currencies of the bank's newest publication.
          items:
            type: string
          example:
            - USD
            - JPY
      required:
        - code
        - name
        - country
        - region
        - base_currency
        - rate_type
        - schedule
        - website
        - history
        - currencies
    OfficialSourcesResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/OfficialSourceInfo'
      required:
        - data
    OfficialError:
      type: object
      description: >-
        Errors of the official rates endpoints. `error.code` is stable and
        meant for programs: `invalid_parameters` (422), `currency_not_published`
        (422, the bank does not publish `base_currency` on that date),
        `no_rates_published` (404), `plan_upgrade_required` (403). `actions`
        holds links to the next step (documentation, source list, upgrade).
      properties:
        message:
          type: string
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - invalid_parameters
                - currency_not_published
                - no_rates_published
                - plan_upgrade_required
            message:
              type: string
          required:
            - code
            - message
        errors:
          type: object
          description: For `invalid_parameters`, the messages per parameter.
          additionalProperties:
            type: array
            items:
              type: string
        actions:
          type: object
          additionalProperties:
            type: string
            format: uri
        info:
          type: string
      required:
        - message
        - error
    Error:
      type: object
      properties:
        message:
          type: string
          description: Human-readable error message.
        info:
          type: string
          description: >-
            Link to the relevant documentation. Present on validation (422) and
            plan (403) errors.
        error:
          type: object
          description: >-
            Machine-readable error envelope, on 401, 403, 404 and 429
            responses (gateway errors included).
          properties:
            code:
              type: string
              description: >-
                Stable machine-readable error code, e.g. `missing_api_key`,
                `invalid_api_key`, `key_not_allowed_for_product`,
                `referrer_not_allowed`, `quota_exceeded`,
                `grace_quota_exceeded`, `overage_quota_exceeded`,
                `rate_limit_exceeded`, `not_found`, `forbidden`,
                `plan_upgrade_required` (a plan does not include the endpoint or
                parameter).
              example: quota_exceeded
            message:
              type: string
              description: The same text as the top-level `message`.
          required: [code, message]
        quota:
          type: object
          description: The quota of the API key's account. Present on quota errors only.
          properties:
            limit: { type: integer, example: 300 }
            used: { type: integer, example: 300 }
            remaining: { type: integer, example: 0 }
            resets_at:
              type: [string, 'null']
              format: date-time
              description: When the quota resets. Null when unknown.
        actions:
          type: object
          description: >-
            Next steps as absolute URLs, keyed by action. A key is only
            present when it applies to this error and is available for this
            product right now, so read the keys you know and ignore the
            others. `sign_up`: create an account with a free API key.
            `upgrade`: the plans of the API key's account (quota and plan
            errors). `complete_payment`: pay the open invoice (grace quota).
            `verify_email`: confirm the account's email address. `docs`: the
            documentation (always present). `openapi`: this specification.
            `pricing`: the plans as JSON. `agent_setup`: setup steps for AI
            coding agents. `get_free_api_key`, `get_trial_key`, `get_api_key`:
            endpoints that issue API keys to agents; `agent_setup` explains
            them.
            `enable_overage`: turn on overage for the account, so requests past
            the monthly quota are served and billed per request up to a budget
            (quota_exceeded of a paid plan that has overage, while it is off).
          additionalProperties: { type: string, format: uri }
      required:
        - message
    ValidationError:
      type: object
      properties:
        message:
          type: string
          example: "Validation error"
        errors:
          type: object
          description: Map of parameter name to an array of validation messages.
          additionalProperties:
            type: array
            items:
              type: string
        info:
          type: string
      required:
        - message
        - errors
