ECB Exchange Rates API: Daily, Historical, Conversion
Pricing
from $0.43 / 1,000 exchange rate rows
ECB Exchange Rates API: Daily, Historical, Conversion
Official ECB euro reference exchange rates for ~30 currencies: latest, history since 1999, cross rates and conversion of dated invoice amounts (rate, inverse, change %, converted amount). No API key, no login. MCP-ready for AI agents. Pay per result, errors are free. $0.50 per 1,000 rows.
Pricing
from $0.43 / 1,000 exchange rate rows
Rating
0.0
(0)
Developer
ABM
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
ECB Exchange Rates API: daily, historical euro FX rates and conversion
Get the official European Central Bank (ECB) euro foreign exchange reference rates as clean JSON or CSV: today's rates, the full history since 1999-01-04 for about 30 currencies, cross rates against any base (USD, GBP, CHF...), and bulk conversion of your own dated amounts (invoices, expenses, transactions) at the ECB rate of their date.
Price: $0.50 per 1,000 rows ($0.0005 per exchange rate or converted amount). No API key, no login, no monthly rental. Errors, unknown currencies and duplicates are free.
What does it do?
- Latest: the last rates published by the ECB (around 16:00 CET on TARGET business days).
- History: every business day between two dates, with the day-over-day change in %.
- Convert: send a list of
{amount, from, to, date}items and get the converted amount, the rate and the ECB date used. On weekends and holidays it uses the last rate published before that date (isFallbackDate: true), which is the usual accounting practice. - Cross rates: set
baseCurrencytoUSD(or any ECB currency) to get USD/GBP, USD/JPY... computed from the ECB euro rates. - Only new rates: with
onlyNew: true, a scheduled run delivers only the rates published since the previous run, so you pay only for new rows. - Outputs: dataset (JSON, CSV, Excel, XML via the API) plus a
rates.csvfile in the key-value store. Every row also has a plain-Englishtextfield that LLMs and RAG pipelines can use directly.
Data comes straight from the ECB's public eurofxref files (daily XML, 90-day XML, full-history CSV), with the ECB Data Portal API as a fallback. Nothing is scraped from HTML.
How much does it cost?
You pay $0.0005 per delivered row. Platform usage is included.
| Request | Rows | Price |
|---|---|---|
| Today's rates, all ~30 currencies | 30 | $0.015 |
| USD, GBP, CHF, JPY for all of 2024 | ~1,024 | ~$0.51 |
| 1,000 invoices converted | 1,000 | $0.50 |
Daily onlyNew schedule, 5 currencies, for a month | ~110 | ~$0.055 |
Invalid items, unknown currencies, duplicates and empty periods are not charged. Use Maximum rows or the run's maximum cost to cap spending: the actor stops cleanly once your limit is reached.
Input
| Field | Type | Description |
|---|---|---|
mode | latest / history / convert | What to return (default latest) |
currencies | array | ISO codes; empty = all ECB currencies (latest and history modes) |
baseCurrency | string | EUR (official ECB figures) or any ECB currency for cross rates; default target in convert mode |
startDate, endDate | YYYY-MM-DD | Period for history (default: the last 30 days) |
amounts | array | Items for convert: {"id", "amount", "from", "to", "date"} |
onlyNew | boolean | Deliver only rates newer than the previous run |
maxRows | integer | Stop after N rows (0 = no limit) |
saveCsv | boolean | Also save rates.csv (default true) |
Historical rates example:
{"mode": "history","currencies": ["USD", "GBP", "CHF", "JPY"],"baseCurrency": "EUR","startDate": "2024-01-01","endDate": "2024-12-31"}
Conversion example:
{"mode": "convert","baseCurrency": "EUR","amounts": [{ "id": "INV-001", "amount": 1250.5, "from": "USD", "to": "EUR", "date": "2024-03-15" },{ "id": "INV-002", "amount": "1 234,56", "from": "GBP", "date": "2024-12-25" }]}
Amounts can be numbers or strings in European or US format ("1 234,56", "1,234.56"). Dates also accept DD/MM/YYYY.
Output
Rate row (history or latest):
{"type": "rate","date": "2024-12-31","baseCurrency": "EUR","currency": "USD","rate": 1.0389,"inverseRate": 0.96255655,"changePct": -0.2591,"isCrossRate": false,"text": "On 2024-12-31, 1 EUR = 1.0389 USD (ECB euro reference rate).","source": "ECB euro foreign exchange reference rates","sourceUrl": "https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html"}
Conversion row:
{"type": "conversion","id": "INV-002","itemIndex": 1,"requestedDate": "2024-12-25","date": "2024-12-24","amount": 1234.56,"fromCurrency": "GBP","toCurrency": "EUR","baseCurrency": "GBP","currency": "EUR","rate": 1.2058,"inverseRate": 0.8293,"isCrossRate": false,"convertedAmount": 1488.6,"isFallbackDate": true,"error": null,"text": "1234.56 GBP = 1488.6 EUR at the ECB reference rate of 2024-12-24 (1 GBP = 1.2058 EUR)."}
(Figures above are illustrative.) An invalid item comes back with only its input fields and an error message, for example "currency \"XYZ\" is not published by the ECB", and it is not charged.
Use cases
1. Month-end revaluation for an accountant
A chartered accountant converts every foreign-currency supplier invoice of the month into EUR at the ECB rate of the invoice date, as many EU tax rules allow.
Input: {"mode": "convert", "baseCurrency": "EUR", "amounts": [{"id": "FA-2024-0312", "amount": 4820, "from": "USD", "date": "2024-03-12"}, {"id": "FA-2024-0316", "amount": 1500, "from": "CHF", "date": "2024-03-16"}]}
Output: [{"id": "FA-2024-0312", "rate": 0.9147..., "convertedAmount": 4409.0..., "date": "2024-03-12"}, {"id": "FA-2024-0316", "date": "2024-03-15", "isFallbackDate": true, ...}]
Next step: 300 invoices cost $0.15. The CSV is imported into the accounting software, and isFallbackDate documents the weekend rule for the auditor.
2. Daily rates in Google Sheets for a finance team
A treasury analyst wants the new ECB rates every morning in a shared sheet used by pricing and billing.
Input (scheduled every weekday at 17:00 CET): {"mode": "latest", "currencies": ["USD", "GBP", "CHF", "SEK", "PLN"], "onlyNew": true}
Output: [{"date": "2026-10-16", "currency": "USD", "rate": 1.1253, "changePct": 0.12}, ...]
Next step: Apify's Google Sheets integration appends the 5 rows. That is about 110 rows a month, roughly $0.06 a month, and nothing is charged on ECB holidays.
3. Historical FX for a BI dashboard or a pricing model
A data analyst at an e-commerce company backfills USD, GBP and JPY against EUR since 2015 to restate revenue in a constant currency.
Input: {"mode": "history", "currencies": ["USD", "GBP", "JPY"], "startDate": "2015-01-01", "endDate": "2025-12-31"}
Output: ~8,500 rows like {"date": "2015-01-02", "currency": "USD", "rate": 1.2043}
Next step: about $4.25, loaded into BigQuery or Snowflake through the dataset CSV export, then joined on date + currency.
4. USD-based cross rates for a US subsidiary
A controller reporting in USD sets baseCurrency to USD: {"mode": "history", "baseCurrency": "USD", "currencies": ["EUR", "GBP", "CAD"], "startDate": "2024-01-01", "endDate": "2024-03-31"} returns rows like {"baseCurrency": "USD", "currency": "EUR", "rate": 0.91, "isCrossRate": true}.
API usage
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<username>/ecb-exchange-rates").call(run_input={"mode": "history","currencies": ["USD", "GBP"],"startDate": "2024-01-01","endDate": "2024-12-31",})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["date"], row["currency"], row["rate"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('<username>/ecb-exchange-rates').call({mode: 'convert',amounts: [{ id: 'INV-001', amount: 1250.5, from: 'USD', to: 'EUR', date: '2024-03-15' }],});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items[0].convertedAmount);
Single HTTP call (returns the rows directly):
POST https://api.apify.com/v2/acts/<username>~ecb-exchange-rates/run-sync-get-dataset-items?token=<TOKEN>&format=csv{"mode": "latest"}
Integrations (Make, n8n, Zapier, Google Sheets)
- n8n: a Schedule Trigger node (weekdays at 17:00) feeds an Apify node with "Run actor and get dataset" and input
{"mode": "latest", "onlyNew": true}, then a Google Sheets → Append row node. Your sheet gets only new rates, every day. - Make: Apify → Run an Actor (synchronous), then Apify → Get Dataset Items, then Iterator and Google Sheets / Airtable / Xero.
- Zapier: trigger "New invoice in QuickBooks", then Apify → Run Actor in
convertmode with the invoice amount, currency and date, then writeconvertedAmountback. - Google Sheets: use Apify's built-in Google Sheets export or
=IMPORTDATA()on the dataset CSV URL.
Use with AI agents (MCP)
This actor works with the Apify MCP server (https://mcp.apify.com) from Claude, Cursor, ChatGPT and other MCP clients. An agent can call it with {"mode": "convert", "amounts": [...]} to answer "how much was this USD invoice worth in EUR on 15 March 2024?" using an official source. The text field gives a ready-to-quote sentence, and sourceUrl gives the citation.
FAQ
Is this the official ECB data? Yes. The rates are the euro foreign exchange reference rates published by the European Central Bank, read from its public files. They are not modified, except that cross rates (base other than EUR) are computed from them.
Why are there no rates on some days? The ECB publishes only on TARGET business days, so there are no rates on weekends, 1 January, Good Friday, Easter Monday, 1 May, 25 and 26 December. In convert mode the previous business day is used.
Which currencies are available? About 30: USD, JPY, BGN, CZK, DKK, GBP, HUF, PLN, RON, SEK, CHF, ISK, NOK, TRY, AUD, BRL, CAD, CNY, HKD, IDR, ILS, INR, KRW, MXN, MYR, NZD, PHP, SGD, THB, ZAR, plus discontinued ones for the years they were published (e.g. RUB until March 2022, HRK until 2022).
What time are new rates available? Around 16:00 CET. Schedule onlyNew runs after 16:30 CET.
How does onlyNew work? The last delivered date per currency and base currency is stored in your named key-value store ecb-exchange-rates-state. Delete that record to start over.
Do I need an API key or proxy? No. The ECB data is public, and the actor downloads it directly.
Limits
- ECB reference rates are for information. They are fixed once a day and are not live market or trading rates.
- No intraday rates, no rates before 1999-01-04, and no currencies outside the ECB list (for example, no crypto and no AED).
- Cross rates are derived from two euro rates and are rounded to 8 significant digits, so they can differ slightly from another provider's direct quotes.
- Rates are fixed after publication but are not available for the current day before about 16:00 CET; the convert mode then uses the previous business day.