StabisoDocs

Reference data API

FX

ECB reference rates, conversion with EUR triangulation, official VAT exchange rates and IAS 21 period rates.

Operation Summary
GET /v1/fx/convert Convert an amount at the ECB reference rate
GET /v1/fx/history List the daily ECB cross rates of a currency pair
GET /v1/fx/period-rates Get the IAS 21 average or closing rate of a period
GET /v1/fx/rates List ECB reference rates
GET /v1/fx/tax-rates Get the official VAT exchange rate
GET /v1/fx/tax-rates/convert Convert an amount at the official VAT exchange rate

GET /v1/fx/convert

Convert an amount at the ECB reference rate

Convert an amount between two currencies at the ECB euro reference rate.

Currencies other than EUR are triangulated through EUR (data.path shows the route). rate is the cross rate rounded to 10 decimals and converted the amount rounded half-even to the minor unit of the target currency. fixing_date is the ECB day used. For VAT or IAS 21 purposes use /tax-rates or /period-rates instead. 404 if there is no fixing within 7 days before the date or a currency is not published by the ECB.

Authentication an API key, where the server requires one
Operation id convert_v1_fx_convert_get

Parameters

In Name Type Required Description
query from string yes ISO 4217 code of the currency to convert from, case-insensitive. (min length 3; max length 3)
query to string yes ISO 4217 code of the currency to convert to, case-insensitive. (min length 3; max length 3)
query amount decimal string Amount in the from currency, as a decimal number. Default 1. (default "1")
query date string (date) or null Rate date (ISO 8601, e.g. 2026-09-25). The latest ECB fixing on or before it (up to 7 days back) is used. Defaults to today.
query dataset_version string or null Pin the response to an archived dataset version (git SHA). Defaults to the current version. Also accepted as the X-Dataset-Version header. The version that answered is in meta.dataset_version; an archived version that does not exist gives 404.

Example request

curl "$DATAVNEXT_URL/v1/fx/convert?from=USD&to=SEK" \
  -H "X-API-Key: $DATAVNEXT_KEY"

Responses

Status Meaning Body
200 OK Envelope_Conversion_
401 Missing or invalid API key. Error
404 Nothing found for the identifier, or the pinned dataset_version is not archived. Error
422 The request is invalid: {"detail": "…"} for a rule the service checks, or FastAPI's {"detail": [{"loc", "msg", "type"}]} for a malformed parameter or body. HTTPValidationError

Example response (shape)

{
  "data": {
    "source": "ecb",
    "requested_date": "2026-09-25",
    "fixing_date": "2026-09-25",
    "from_currency": "USD",
    "to_currency": "SEK",
    "amount": "1000",
    "rate": "9.9009032711",
    "converted": "9900.90",
    "path": [
      "USD",
      "EUR",
      "SEK"
    ]
  },
  "meta": {
    "dataset_version": "3f2a9c1b7d4e",
    "as_of": "2026-09-25",
    "sources": [
      {
        "authority": "European Central Bank",
        "url": "https://data.ecb.europa.eu/data/datasets/EXR",
        "reference": "Euro reference rates",
        "verified_at": "2026-10-01",
        "kind": "official"
      }
    ],
    "notes": [
      "ECB euro reference rates are for information purposes; the most recent fixing on or before the requested date is used."
    ]
  }
}

GET /v1/fx/history

List the daily ECB cross rates of a currency pair

The ECB cross rate of a pair on every fixing day of a range, oldest first.

Each point in data.points is the rate of one ECB fixing day, triangulated through EUR and rounded to 10 decimals half-even, so it equals the rate of /convert for that day. Weekends and holidays have no point (the ECB publishes none); a day on which the ECB did not publish both currencies is left out too. The mean of the points is the IAS 21 average that /period-rates returns for a calendar period. 422 if base and quote are equal, the range is reversed or longer than the limit; 404 if the range holds no fixing of both currencies.

Authentication an API key, where the server requires one
Operation id history_v1_fx_history_get

Parameters

In Name Type Required Description
query base string yes ISO 4217 code of the base currency (the unit being priced), case-insensitive. (min length 3; max length 3)
query quote string yes ISO 4217 code of the quote currency, case-insensitive; each rate is units of quote per one unit of base. Must differ from base. (min length 3; max length 3)
query start string (date) yes First day of the range (ISO 8601, e.g. 2026-08-01).
query end string (date) yes Last day of the range (ISO 8601), on or after start; the range covers at most 1830 days.
query dataset_version string or null Pin the response to an archived dataset version (git SHA). Defaults to the current version. Also accepted as the X-Dataset-Version header. The version that answered is in meta.dataset_version; an archived version that does not exist gives 404.

Example request

curl "$DATAVNEXT_URL/v1/fx/history?base=USD&quote=CHF&start=2026-08-01&end=2026-08-31" \
  -H "X-API-Key: $DATAVNEXT_KEY"

Responses

Status Meaning Body
200 OK Envelope_FxHistory_
401 Missing or invalid API key. Error
404 Nothing found for the identifier, or the pinned dataset_version is not archived. Error
422 The request is invalid: {"detail": "…"} for a rule the service checks, or FastAPI's {"detail": [{"loc", "msg", "type"}]} for a malformed parameter or body. HTTPValidationError

Example response (shape)

{
  "data": {
    "source": "ecb",
    "base": "USD",
    "quote": "CHF",
    "start": "2026-09-21",
    "end": "2026-09-25",
    "points": [
      {
        "date": "2026-09-24",
        "rate": "0.8231234567"
      },
      {
        "date": "2026-09-25",
        "rate": "0.8282908356"
      }
    ]
  },
  "meta": {
    "dataset_version": "3f2a9c1b7d4e",
    "as_of": "2026-09-25",
    "sources": [
      {
        "authority": "European Central Bank",
        "url": "https://data.ecb.europa.eu/data/datasets/EXR",
        "reference": "Euro reference rates",
        "verified_at": "2026-10-01",
        "kind": "official"
      }
    ],
    "notes": [
      "ECB euro reference rates are for information purposes; the most recent fixing on or before the requested date is used."
    ]
  }
}

GET /v1/fx/period-rates

Get the IAS 21 average or closing rate of a period

IAS 21 average or closing rate for a calendar period, derived from ECB fixings.

data.rate is units of quote per one unit of base, rounded to 10 decimals; fixings is the number of daily ECB fixings used, from first_fixing to last_fixing. meta.notes explains the method. 422 if the period is malformed or has not ended, or base and quote are equal; 404 if the stored ECB fixings for the period are incomplete or a currency is not published.

Authentication an API key, where the server requires one
Operation id period_rates_v1_fx_period_rates_get

Parameters

In Name Type Required Description
query base string yes ISO 4217 code of the base currency (the unit being priced). (min length 3; max length 3)
query quote string yes ISO 4217 code of the quote currency; rate is units of quote per one unit of base. Must differ from base. (min length 3; max length 3)
query period string yes Calendar period: YYYY-MM (month), YYYY-Qn (quarter) or YYYY (year). It must have ended before today.
query kind "average" | "closing" 'average': mean of the daily cross rates over the period (income and expenses, IAS 21.40); 'closing': the last fixing on or before the period end (monetary items, IAS 21.23). Default 'average'. (default "average")
query dataset_version string or null Pin the response to an archived dataset version (git SHA). Defaults to the current version. Also accepted as the X-Dataset-Version header. The version that answered is in meta.dataset_version; an archived version that does not exist gives 404.

Example request

curl "$DATAVNEXT_URL/v1/fx/period-rates?base=CHF&quote=EUR&period=2026-08" \
  -H "X-API-Key: $DATAVNEXT_KEY"

Responses

Status Meaning Body
200 OK Envelope_PeriodRate_
401 Missing or invalid API key. Error
404 Nothing found for the identifier, or the pinned dataset_version is not archived. Error
422 The request is invalid: {"detail": "…"} for a rule the service checks, or FastAPI's {"detail": [{"loc", "msg", "type"}]} for a malformed parameter or body. HTTPValidationError

Example response (shape)

{
  "data": {
    "source": "ecb",
    "base": "CHF",
    "quote": "EUR",
    "period": "2026-08",
    "period_start": "2026-08-01",
    "period_end": "2026-08-31",
    "kind": "average",
    "rate": "1.0681709886",
    "fixings": 21,
    "first_fixing": "2026-08-03",
    "last_fixing": "2026-08-31"
  },
  "meta": {
    "dataset_version": "3f2a9c1b7d4e",
    "sources": [
      {
        "authority": "European Central Bank",
        "url": "https://data.ecb.europa.eu/data/datasets/EXR",
        "reference": "Euro reference rates",
        "verified_at": "2026-10-01",
        "kind": "official"
      },
      {
        "authority": "IFRS Foundation",
        "url": "https://www.ifrs.org/issued-standards/list-of-standards/ias-21-the-effects-of-changes-in-foreign-exchange-rates/",
        "reference": "IAS 21.9, 21.21, 21.23, 21.39",
        "verified_at": "2026-09-29",
        "kind": "official"
      }
    ],
    "notes": [
      "Average: the arithmetic mean of the daily cross rates on every ECB fixing day in the period (each day triangulated through EUR, then averaged), rounded to 10 decimals."
    ]
  }
}

GET /v1/fx/rates

List ECB reference rates

ECB euro reference rates, rebased to any published currency.

data.rates maps each currency to the units of that currency per one unit of base, as decimal strings with 10 decimals. fixing_date is the ECB publication day actually used (weekends and holidays fall back to the previous fixing); requested_date is what you asked for and meta.as_of repeats it. 404 if there is no fixing within 7 days before the date or the base currency is not published by the ECB.

Authentication an API key, where the server requires one
Operation id rates_v1_fx_rates_get

Parameters

In Name Type Required Description
query base string ISO 4217 code of the base currency, case-insensitive. The ECB publishes its rates against EUR; any other base is derived from them. Default EUR. (default "EUR")
query date string (date) or null Rate date (ISO 8601, e.g. 2026-09-25). The latest ECB fixing on or before it (up to 7 days back) is used. Defaults to today.
query dataset_version string or null Pin the response to an archived dataset version (git SHA). Defaults to the current version. Also accepted as the X-Dataset-Version header. The version that answered is in meta.dataset_version; an archived version that does not exist gives 404.

Example request

curl "$DATAVNEXT_URL/v1/fx/rates" \
  -H "X-API-Key: $DATAVNEXT_KEY"

Responses

Status Meaning Body
200 OK Envelope_FxRates_
401 Missing or invalid API key. Error
404 Nothing found for the identifier, or the pinned dataset_version is not archived. Error
422 The request is invalid: {"detail": "…"} for a rule the service checks, or FastAPI's {"detail": [{"loc", "msg", "type"}]} for a malformed parameter or body. HTTPValidationError

Example response (shape)

{
  "data": {
    "source": "ecb",
    "base": "EUR",
    "requested_date": "2026-09-25",
    "fixing_date": "2026-09-25",
    "rates": {
      "CHF": "0.9445000000",
      "GBP": "0.8604500000",
      "SEK": "11.2900000000"
    }
  },
  "meta": {
    "dataset_version": "3f2a9c1b7d4e",
    "as_of": "2026-09-25",
    "sources": [
      {
        "authority": "European Central Bank",
        "url": "https://data.ecb.europa.eu/data/datasets/EXR",
        "reference": "Euro reference rates",
        "verified_at": "2026-10-01",
        "kind": "official"
      }
    ],
    "notes": [
      "ECB euro reference rates are for information purposes; the most recent fixing on or before the requested date is used."
    ]
  }
}

GET /v1/fx/tax-rates

Get the official VAT exchange rate

The official VAT exchange rate for a foreign currency on a date.

data.rate is the published rate and quoted_as says how it is quoted (CHF per 1 USD for Switzerland, USD per 1 EUR for Germany); tax_currency_per_unit is always the tax currency per one unit of foreign currency. fixing_date is the publication date used and period the month it covers. meta.notes states which rate applies and when it is published. 422 for a jurisdiction or kind with no series, or for the tax currency itself; 404 when the rate is not published yet or does not list the currency.

Authentication an API key, where the server requires one
Operation id tax_rates_v1_fx_tax_rates_get

Parameters

In Name Type Required Description
query jurisdiction string yes Country whose VAT exchange rate applies: 'CH' (ESTV, published by BAZG) or 'DE' (BMF, UStG §16 Abs. 6). Case-insensitive.
query currency string yes ISO 4217 code of the foreign currency, case-insensitive. It must differ from the jurisdiction's tax currency (CHF or EUR). (min length 3; max length 3)
query date string (date) or null Tax point: the date of the supply or invoice (ISO 8601). It selects the month (monthly) or the latest published day (daily). Defaults to today.
query kind "daily" | "monthly" 'monthly': the monthly average rate; 'daily': the daily rate (published for Switzerland). Default 'monthly'. (default "monthly")
query dataset_version string or null Pin the response to an archived dataset version (git SHA). Defaults to the current version. Also accepted as the X-Dataset-Version header. The version that answered is in meta.dataset_version; an archived version that does not exist gives 404.

Example request

curl "$DATAVNEXT_URL/v1/fx/tax-rates?jurisdiction=CH&currency=USD" \
  -H "X-API-Key: $DATAVNEXT_KEY"

Responses

Status Meaning Body
200 OK Envelope_TaxFxRate_
401 Missing or invalid API key. Error
404 Nothing found for the identifier, or the pinned dataset_version is not archived. Error
422 The request is invalid: {"detail": "…"} for a rule the service checks, or FastAPI's {"detail": [{"loc", "msg", "type"}]} for a malformed parameter or body. HTTPValidationError

Example response (shape)

{
  "data": {
    "series": "ch-vat-monthly",
    "jurisdiction": "CH",
    "kind": "monthly",
    "requested_date": "2026-10-15",
    "fixing_date": "2026-10-01",
    "period": "2026-10",
    "currency": "USD",
    "tax_currency": "CHF",
    "rate": "0.8218",
    "quotation": "direct",
    "quoted_as": "CHF per 1 USD",
    "tax_currency_per_unit": "0.8218"
  },
  "meta": {
    "dataset_version": "3f2a9c1b7d4e",
    "as_of": "2026-10-15",
    "sources": [
      {
        "authority": "Eidgenössische Steuerverwaltung (ESTV)",
        "url": "https://www.estv.admin.ch/de/mwst-fremdwaehrungskurse",
        "reference": "Fremdwährungskurse MWST",
        "verified_at": "2026-10-01",
        "kind": "official"
      }
    ],
    "notes": [
      "Published by BAZG on the 25th of the previous month (or the next working day)."
    ]
  }
}

GET /v1/fx/tax-rates/convert

Convert an amount at the official VAT exchange rate

Convert a foreign-currency amount into the tax currency at the official VAT rate, rounded half up to the tax currency's minor unit.

The response has the rate fields of /tax-rates plus amount and converted (decimal strings, converted in the tax currency). Errors as for /tax-rates: 422 for a jurisdiction or kind without a series or for the tax currency itself, 404 when the rate is not published yet or does not list the currency.

Authentication an API key, where the server requires one
Operation id tax_convert_v1_fx_tax_rates_convert_get

Parameters

In Name Type Required Description
query jurisdiction string yes Country whose VAT exchange rate applies: 'CH' (ESTV, published by BAZG) or 'DE' (BMF, UStG §16 Abs. 6). Case-insensitive.
query currency string yes ISO 4217 code of the foreign currency, case-insensitive. It must differ from the jurisdiction's tax currency (CHF or EUR). (min length 3; max length 3)
query amount decimal string Amount in the foreign currency, as a decimal number. Default 1. (default "1")
query date string (date) or null Tax point: the date of the supply or invoice (ISO 8601). It selects the month (monthly) or the latest published day (daily). Defaults to today.
query kind "daily" | "monthly" 'monthly': the monthly average rate; 'daily': the daily rate (published for Switzerland). Default 'monthly'. (default "monthly")
query dataset_version string or null Pin the response to an archived dataset version (git SHA). Defaults to the current version. Also accepted as the X-Dataset-Version header. The version that answered is in meta.dataset_version; an archived version that does not exist gives 404.

Example request

curl "$DATAVNEXT_URL/v1/fx/tax-rates/convert?jurisdiction=CH&currency=USD" \
  -H "X-API-Key: $DATAVNEXT_KEY"

Responses

Status Meaning Body
200 OK Envelope_TaxFxConversion_
401 Missing or invalid API key. Error
404 Nothing found for the identifier, or the pinned dataset_version is not archived. Error
422 The request is invalid: {"detail": "…"} for a rule the service checks, or FastAPI's {"detail": [{"loc", "msg", "type"}]} for a malformed parameter or body. HTTPValidationError

Example response (shape)

{
  "data": {
    "series": "de-vat-monthly",
    "jurisdiction": "DE",
    "kind": "monthly",
    "requested_date": "2026-08-20",
    "fixing_date": "2026-08-01",
    "period": "2026-08",
    "currency": "USD",
    "tax_currency": "EUR",
    "rate": "1.1593",
    "quotation": "indirect",
    "quoted_as": "USD per 1 EUR",
    "tax_currency_per_unit": "0.8625894937",
    "amount": "1000",
    "converted": "862.59"
  },
  "meta": {
    "dataset_version": "3f2a9c1b7d4e",
    "as_of": "2026-08-20",
    "sources": [
      {
        "authority": "Bundesamt für Justiz (gesetze-im-internet.de)",
        "url": "https://www.gesetze-im-internet.de/ustg_1980/__16.html",
        "reference": "UStG §16 Abs. 6",
        "verified_at": "2026-10-01",
        "kind": "official"
      }
    ],
    "notes": [
      "The average for the month in which the supply is made (or a prepayment is received; under cash accounting, the month the consideration is received). Rates are units of foreign currency per 1 EUR."
    ]
  }
}

Schemas

Conversion

Field Type Required Description
source string yes
requested_date string (date) yes
fixing_date string (date) yes
from_currency string yes
to_currency string yes
amount string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
rate string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
converted string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
path array of string yes

Envelope_Conversion_

Field Type Required Description
data Conversion yes
meta Meta yes

Envelope_FxHistory_

Field Type Required Description
data FxHistory yes
meta Meta yes

Envelope_FxRates_

Field Type Required Description
data FxRates yes
meta Meta yes

Envelope_PeriodRate_

Field Type Required Description
data PeriodRate yes
meta Meta yes

Envelope_TaxFxConversion_

Field Type Required Description
data TaxFxConversion yes
meta Meta yes

Envelope_TaxFxRate_

Field Type Required Description
data TaxFxRate yes
meta Meta yes

FxHistory

Field Type Required Description
source string yes
base string yes
quote string yes
start string (date) yes
end string (date) yes
points array of FxPoint yes

FxPoint

Field Type Required Description
date string (date) yes
rate string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)

FxRates

Field Type Required Description
source string yes
base string yes
requested_date string (date) yes
fixing_date string (date) yes
rates map of string yes

PeriodRate

Field Type Required Description
source string yes
base string yes
quote string yes
period string yes
period_start string (date) yes
period_end string (date) yes
kind "average" | "closing" yes
rate string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
fixings integer yes
first_fixing string (date) yes
last_fixing string (date) yes

TaxFxConversion

Field Type Required Description
series string yes
jurisdiction string yes
kind "daily" | "monthly" yes
requested_date string (date) yes
fixing_date string (date) yes
period string or null
currency string yes
tax_currency string yes
rate string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
quotation "direct" | "indirect" yes
quoted_as string yes
tax_currency_per_unit string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
amount string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
converted string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)

TaxFxRate

Field Type Required Description
series string yes
jurisdiction string yes
kind "daily" | "monthly" yes
requested_date string (date) yes
fixing_date string (date) yes
period string or null
currency string yes
tax_currency string yes
rate string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
quotation "direct" | "indirect" yes
quoted_as string yes
tax_currency_per_unit string yes (pattern ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$)
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 20b7dd5b0c4d