Exchange Rates Scraper: ECB Daily FX & History
Pricing
Pay per event
Exchange Rates Scraper: ECB Daily FX & History
Scrape official ECB exchange rates: latest daily reference rates and daily history back to 1999 for 30+ currencies, from any base, with inverse rates on every row. Multi-base batches and a currency directory. Export CSV, Excel, JSON, XML. No login or API key. 29 currencies per USD-base request.
Pricing
Pay per event
Rating
0.0
(0)
Developer
RecordsData
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
💱 Exchange Rates Scraper: 165 Currencies, History, OHLC
Exchange Rates Scraper exports exchange rates for 165 currencies, blended from 104 central banks, as clean rows: latest rates, daily history back to 1999 (older for some pairs), weekly to yearly open-high-low-close, amount conversion, change versus the previous fixing, and a monitor mode that skips unchanged rates for free. No login, no API key. Export CSV, Excel, JSON or XML.
Exchange Rates Scraper turns the open Frankfurter v2 service into one row per base currency, target currency and date, with a source field saying which central bank feed produced it. Besides the 165 current currencies it covers 58 retired ones (DEM, FRF, ATS, GRD, CYP...) for history. Built for finance teams, BI engineers and researchers who need an auditable FX table.
💱 What does Exchange Rates Scraper do?
- Latest rates for 165 currencies, with the change against the previous fixing.
- ECB only, on request: set
providersto["ECB"]for the 45 ECB currencies on business days. Keys such as BOE, BOJ, BANXICO or BCB work the same way. - History since 1999: daily rates for any range, earlier for some pairs (USD/JPY from 1969).
historyFromaccepts30d,12w,6m,5y,ytd. - OHLC intervals:
daily,weekly,monthly,quarterlyoryearlyrows with open, high, low, close, average and range percent. - Amount conversion: set
amountand every rate row getsconverted. - Monitor mode:
onlyChangedreturns only new or changed rates; unchanged rates are not charged. - Directories of currencies and sources, and multi-base batches.
📊 What data can you extract from the exchange rates?
| Field | Description |
|---|---|
recordType | rate, currency or provider |
rateType | latest or historical (rate rows) |
interval | daily, weekly, monthly, quarterly, yearly (history rows) |
changeType | new or changed (monitor mode) |
date | Fixing date, YYYY-MM-DD (last fixing of the period on aggregated rows) |
period, periodStart, periodEnd | Aggregated rows: 2025-W03, 2025-01, 2025-Q1 or 2025, and bounds |
base, baseName | Base currency code and full name |
currency, currencyName, pair | Target currency code, full name and pair |
rate | Units of target per 1 unit of base (closing rate on aggregated rows) |
inverseRate | 1 / rate, 10 significant digits |
amount, converted | Only when the amount input is set |
previousRate, previousDate, change, changePct | Versus the previous fixing, or previous period close |
open, high, low, average, rangePct, days | Aggregated rows: period statistics and days with a rate |
source | blended, or the source keys you chose (for example ECB) |
providerCount, providerRates | Latest rows with includeProviderRates: each source's rate and date |
name, isoNumeric, symbol, isActive, firstDate, lastDate | Currency directory rows |
provider, country, rateKind, frequency, publishCadence, currencyCount, currencies, dataUrl | Source directory rows |
scrapedAt | ISO timestamp of the run |
error | Only on a failed lookup row (never billed) |
Fields that do not apply to a row are omitted.
📄 Exchange rates sample output
A latest-rate row from a cloud run (2026-10-04):
{"recordType": "rate","rateType": "latest","date": "2026-10-02","base": "USD","currency": "BRL","rate": 5.2214,"inverseRate": 0.19151952,"scrapedAt": "2026-10-04T04:19:31.176Z"}
💰 How much does it cost to get exchange rates?
Pay per event: you pay only for rows saved.
| Event | Price (Free plan) | Lower on paid Apify plans |
|---|---|---|
Rate row (rate-record) | $0.012 per row ($12 per 1,000) | down to $0.010 per row |
Currency or source directory row (currency-record) | $0.010 per row | $0.010 per row |
An aggregated row (weekly, monthly, quarterly, yearly) costs the same as a daily row, so aggregating makes a series much cheaper. Worked examples on the Free plan:
- USD latest rates for 10 currencies: 10 x $0.012 = $0.12.
- One pair, one year of daily rows from the blended feed (365 days): about $4.38. The same year as weekly rows (52): about $0.62.
- USD latest for all currencies plus both directories with retired currencies: 164 rates and 327 directory rows, about $5.24 (cloud run: 164
rate-record, 327currency-record).
On the top paid tier the rate row is $0.010, so the year of daily rows is $3.65 and the weekly one $0.52. Error rows are free, and a run that delivers no rates fails with a clear message and charges nothing. Your maxTotalChargeUsd limit is respected.
🚀 How to scrape exchange rates in 3 steps
- Open the actor on Apify and click Try for free.
- Enter your base currencies (for example
USD), optionally target currencies, anamount, and a history range with an interval. - Click Start, then download the dataset as CSV, Excel, JSON or XML.
⚙️ Exchange Rates Scraper input
| Field | Default | What it does |
|---|---|---|
baseCurrencies | ["USD"] | Bases to quote from (3-letter ISO codes, retired ones work for history) |
symbols | [] | Keep only these target currencies; empty means all |
providers | [] | Source keys instead of the blend, for example ["ECB"]; empty means blended |
includeLatest | true | Add the latest rates |
amount | empty | Adds amount and converted to rate rows |
includeChange | true | Adds previous rate, change and change percent |
includeProviderRates | false | Adds each source's rate to latest rows |
historyFrom | empty | Start: YYYY-MM-DD or 30d, 12w, 6m, 5y, last 5 years, ytd |
historyTo | empty | End: YYYY-MM-DD, yesterday or today; empty means today |
interval | daily | daily, weekly, monthly, quarterly or yearly |
includeCurrencyList | false | Add one row per currency |
includeRetiredCurrencies | false | Also list retired currencies in the directory |
includeProviderList | false | Add one row per rate source |
onlyChanged | false | Return only new or changed rates |
stateKey | empty | Name of the monitor memory; empty derives it from your inputs |
resetSeen | false | Forget previous results before the run |
maxItems | 100 | Maximum rows returned (free users: 10) |
Example input:
{"baseCurrencies": ["USD", "EUR"],"symbols": ["MXN", "JPY", "GBP"],"amount": 100,"historyFrom": "5y","interval": "monthly","maxItems": 5000}
📦 Output behavior
A wrong source key or currency code fails the run before any request, with the list of valid values, and nothing is charged. A genuinely empty result finishes as SUCCEEDED with no charge.
⚖️ Exchange rates API alternatives compared
Competitor Store pages read on 2026-10-09. A feature marked "not stated" is not shown in that listing.
| RecordsData | chorelet/currency-rates-scraper | parseforge/ecb-fx-rates-scraper | |
|---|---|---|---|
| Price per row | $0.012 Free, $0.010 top tier | $0.0002 | $0.0075 |
| Currencies | 165 blended, 45 ECB | 165 global (today only), 29 ECB | ECB; count not stated |
| History | 1999, older for some, all 165 | ECB since 1999 | Since 1999 |
| Weekly to yearly OHLC | Yes, plus quarterly | Weekly, monthly, yearly | Not stated in their listing |
| Amount and change % | Yes, both | Yes, both | Not stated in their listing |
| Only-changed monitor, free skips | Yes | Not stated in their listing | Not stated in their listing |
| Retired currencies | 58, any range, in directory | Some, within their lifetime | Not stated in their listing |
| Source directory, per-source rates | Yes | Not stated in their listing | Not stated in their listing |
We cost 50 to 60 times more per row than chorelet, and chrisp1211/currency-exchange-scraper-max ($0.0004, daily rows only) and benthepythondev/ecb-exchange-rates-scraper ($0.0015, ECB only) are cheaper too. If you only need rates and weekly or monthly OHLC, a cheaper listing may be enough. Pick this one for 165-currency history, monitoring, source transparency and retired currencies. Rates are daily fixings: no intraday or bid/ask, and no sourceUpdatedAt field.
🧰 Exchange rates use cases
Month-end close, FX dimension tables in a warehouse, price localization with alerts, economic research panels including pre-euro currencies, and treasury comparison of central bank rates.
🔌 Exchange Rates Scraper API, schedules and integrations
Run it from the API with the Apify client (client.actor('RecordsData/exchange-rates-scraper').call({ baseCurrencies: ['USD'], historyFrom: '12w', interval: 'weekly' })). Schedule it daily with onlyChanged on, or connect it to Zapier, Make, n8n or Airbyte.
⚖️ Is it legal to scrape exchange rates?
Central bank reference rates are public data, and Frankfurter is an open service that republishes them without a key. The actor collects no personal data. For compliance or audit use, cite the central bank in the source field and read the publisher's own terms on reuse.
🤖 Exchange Rates Scraper MCP server for AI agents
AI agents can call this Actor through the Apify MCP server at https://mcp.apify.com?tools=RecordsData/exchange-rates-scraper. The URL loads only this Actor as a tool.
Add this to your MCP client configuration (Claude Desktop, Cursor, VS Code):
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=RecordsData/exchange-rates-scraper"}}}
Example agent prompt:
Use the Exchange Rates Scraper to get weekly USD to MXN, JPY and GBP rates for the last 12 months, with high and low per week, convert 1,000 USD at each closing rate, and tell me the week with the biggest range.
An agent should choose this tool when it needs official, auditable exchange rates (latest or history since 1999) with conversion, change or monitoring, rather than a live market quote.
❓ Frequently asked questions
Where do the Exchange Rates Scraper rates come from?
The Exchange Rates Scraper reads the open Frankfurter v2 service. By default it returns a blend of rates published by 104 central banks and institutions, and every row says source: blended. With providers set to ["ECB"] you get European Central Bank reference rates only. These are official fixings published once per business day, not live market quotes.
Which currencies does the exchange rates scraper cover?
It covers 165 current currencies in the blended feed, including USD, EUR, GBP, JPY, MXN, BRL and CNY, and 45 with the ECB alone. It also covers 58 retired currencies such as DEM, FRF and GRD for history. Turn on includeCurrencyList for one row per currency with name, ISO number and symbol, and includeRetiredCurrencies to list the retired ones.
How far back does the exchange rate history go?
The Exchange Rates Scraper returns daily history back to 1999 for most pairs, and earlier for some, for example USD/JPY from 1969. Set historyFrom and historyTo to choose the range. With the ECB source, weekends and holidays have no fixing, so only business days come back.
Why did the Exchange Rates Scraper return 0 results?
Usually the date range holds no fixing, or onlyChanged is on and nothing moved since the last run, which finishes as SUCCEEDED and charges nothing. A wrong currency code, source key or date format makes the run fail before any request, with a message that lists the valid values, and nothing is charged.
Does the Exchange Rates Scraper work with a base other than the euro?
Yes. Any of the 165 currencies can be the base, for example USD, GBP or MXN, and so can retired currencies for history. You can list several base currencies in baseCurrencies and get all of them in a single run, with inverseRate computed on every row, so no extra runs are needed.
Why is the Exchange Rates Scraper free plan limited to 10 rows?
Free Apify users get a 10-row preview so they can check the output before paying. Paid Apify plans run up to 1,000,000 rows per run, and you can still cap spending with maxTotalChargeUsd and the maxItems row limit, which defaults to 100, so tests stay cheap.
Am I charged for errors when I scrape exchange rates?
No. Error rows and failed runs are not billed, and a run that delivers no rates fails with a clear message and charges nothing. You pay only for rows saved to the dataset, and maxTotalChargeUsd stops the run cleanly at your limit.
Are these exchange rates live market rates?
No. The scraper returns official daily fixings published by central banks, one per day. They suit accounting, reporting, invoicing and analysis, but they are not live market quotes, there is no bid/ask or intraday data, and they are not intended for trading. Each row shows the fixing date and the source.
How do weekly, monthly and yearly OHLC rows work?
Set interval to weekly, monthly, quarterly or yearly together with a history range. You get one row per pair and period with open, high, low, rate (the close), average, rangePct, days and the change against the previous close. An aggregated row costs the same as a daily row.
Can I use relative date ranges like the last 30 days?
Yes. historyFrom accepts 30d, 12w, 6m, 5y, last 30 days, last 5 years or ytd, and historyTo accepts yesterday or today. A scheduled run with 30d always covers the latest 30 days, and the monitor memory uses the text you typed, so it stays stable from day to day.
How does monitor mode work?
Turn on onlyChanged and schedule the Exchange Rates Scraper. A latest rate is new the first time and changed when its date or value moves; history rows are tracked by pair, date and interval. Unchanged rows are skipped before the row cap and before charging, so a quiet day costs nothing. Use stateKey to keep separate monitors and resetSeen to start over.
How do I convert an amount with the Exchange Rates Scraper?
Set the amount input, for example 100 with base USD. Every rate row then carries amount and converted (amount x rate), so you get the value of 100 USD in each currency or on each historical date.
What are the rate limits for old history?
The data service allows 10 requests per minute for ranges starting before 2021. The scraper spaces those requests about 6.5 seconds apart and honours the wait the service asks for, so fifteen years of all currencies finished in about 150 seconds in our tests. You are billed per row only, not for waiting time.
🛟 Support
Found a bug or missing field? Open the Issues tab on this actor's page or write to contact.punkrecordsdata@gmail.com. Custom solutions are available on request.
Last updated: 2026-10-11