Category guide

AvailableView as Markdown

Foreign Exchange

Daily ECB euro reference rates and EUR-triangulated conversions.

Where the data comes from

Every value this category returns is attributable to one of these publishers, and every payload carries the source tag with it.

SourcePublisherWhat we holdLicence
ecbEuropean Central BankTen curated ECB key-interest-rate, €STR, and euro-area AAA central-government yield-curve spot-rate seriesECB information reuse terms (ecb-reuse)

Required notices

  • Reproduced ECB information must appear accurately and cite the ECB as source.
  • Where ECB information is incorporated in documents that are sold, buyers must be informed that the information is available free of charge from the ECB website.
  • The ECB does not charge for the €STR or license its use.

Full licence text, attribution strings, and every source on the surface are in Attribution.

How the rates work

The euro is always the pivot. A pair with EUR on one side is served from the published fixing directly, or as its inverse; any other pair is triangulated through the euro, flagged derived: true, and names the arithmetic it used in meta.derived_method. That flag is the whole story an agent needs about how much processing sits between the publisher and the number — check it before you quote a rate as published.

Dates resolve rather than fail. Ask for a weekend or a holiday and you get the newest prior fixing, with requested_date and rate_date both echoed in the payload so the substitution is visible instead of silent. Values are exact decimal strings, never floats.

Worked workflows

Convert one amount on one date

The single-answer path. Give it an amount, two currencies, and optionally a date:

[ PYTHON ]
fx_convert(amount="1000", from_currency="USD", to_currency="EUR", date="2026-08-07")

The payload is scalar — one object, no list, and pagination is null:

[ JSON ]
{
  "data": {
    "amount": "1000",
    "from_currency": "USD",
    "to_currency": "EUR",
    "requested_date": "2026-08-07",
    "rate_date": "2026-08-07",
    "rate": "0.914500",
    "converted": "914.500000",
    "derived": false,
    "unit": "EUR per USD",
    "currency": "EUR",
    "as_of": "2026-08-07T16:00:00Z"
  },
  "meta": {
    "source": "ecb",
    "as_of": "2026-08-07T16:00:00Z",
    "attribution": "...",
    "derived_method": "conversion from ECB reference rate"
  },
  "pagination": null
}

Values above are illustrative; the field names are the real ones. Omit date for the latest available fixing.

Read a fixing series

For history — a chart, a volatility calculation, a period average — ask for the series rather than looping conversions:

[ PYTHON ]
fx_get_rates(base="EUR", quote="USD", start="2026-08-01", end="2026-08-07", limit=100)
[ JSON ]
{
  "data": {
    "base": "EUR",
    "quote": "USD",
    "unit": "USD per EUR",
    "currency": "USD",
    "rates": [
      { "date": "2026-08-07", "value": "1.093400", "as_of": "2026-08-07T16:00:00Z", "derived": false }
    ]
  },
  "meta": { "source": "ecb", "as_of": "2026-08-07T16:00:00Z", "attribution": "...", "derived_method": null },
  "pagination": { "limit": 100, "has_more": true, "next_cursor": "eyJ2IjoxLCJrIjpbLi4uXX0" }
}

Rates come back newest-first. When has_more is true, continue with the cursor and every other argument unchanged:

[ PYTHON ]
fx_get_rates(base="EUR", quote="USD", start="2026-08-01", end="2026-08-07", limit=100, cursor="eyJ2IjoxLCJrIjpbLi4uXX0")

Cross two non-euro currencies

Nothing special is required — ask for the pair and read the flag:

[ PYTHON ]
fx_get_rates(base="GBP", quote="JPY", limit=30)

Every rate in that response carries derived: true, and meta.derived_method states the triangulation. Treat a derived cross as what it is: two reference fixings divided, not a quoted market cross.

Coverage and caveats

  • These are reference rates, not prices. The ECB publishes them for information purposes only and strongly discourages using them for transaction purposes. They are not transaction or execution prices, and no tool here will turn them into one.
  • Coverage is the euro reference set. A currency the ECB does not publish against the euro is a bad_parameter, not an empty result. A date outside the published history comes back as out_of_coverage from fx_convert.
  • A reversed date window or an unparseable cursor is bad_parameter too — the surface refuses ambiguous input rather than guessing at it.
  • Check freshness before you trust recency. platform_get_freshness(limit=50) reports the last successful refresh and the freshest value timestamp for the FX dataset, so an agent can tell "the market did not move" from "our connector has not run".

Tools and endpoints

Each tool's full input schema, provenance, and bounds are on its own page; the REST endpoints mirror them one for one.

ToolWhat it doesPage size
fx_convertConvert one amount with ECB reference rates and explicit date resolution.scalar result
fx_get_ratesGet daily ECB euro reference rates or EUR-triangulated cross-rates.default 100 · min 1 · max 500

Over HTTP: Foreign Exchange REST endpoints.