ECB Exchange Rates History
Pricing
$50.00 / 1,000 rate blocks
ECB Exchange Rates History
ECB exchange rate history scraper for dated currency-pair tables. Export daily reference observations and derived same-day cross rates as JSON with calculation inputs and source series.
ECB exchange rates scraper returns published daily reference rates and derived same-day cross rates. ECB exchange rates API rows include observation dates, currency pairs, calculation inputs, and source series.
The actor uses the official ECB Data Portal SDMX API. It returns one flat row per published date and requested currency pair. A rate means quote-currency units per one base-currency unit. For example, a EUR/USD rate of 1.0956 means one euro corresponds to 1.0956 US dollars in that reference observation.
For a non-EUR base, the actor computes quote/EUR ÷ base/EUR from observations on the same date. It does not substitute previous-day rates, interpolate weekends or manufacture missing observations. Same-currency pairs return 1 on observed publication days; EUR/EUR uses USD's ECB series solely as a publication-day anchor.
What it returns
| Field | Type | Example value |
|---|---|---|
date | string | "2024-01-02" |
baseCurrency | string | "EUR" |
quoteCurrency | string | "USD" |
rate | number | 1.0956 |
kind | string | "reference" |
status | string | "ok" |
source | string | "ECB" |
baseEurRate | integer | 1 |
quoteEurRate | number | 1.0956 |
sourceSeries | array | ["EXR.D.USD.EUR.SP00.A"] |
sourceUrls | nullable / see code | null |
observationStatus | nullable / see code | null |
fetchedAt | nullable / see code | null |
startDate | nullable / see code | null |
endDate | nullable / see code | null |
errors | array | [] |
The default dataset has a Daily rates view and a source-provenance view. A SUMMARY key-value record reports output counts, diagnostics, duration and whether an output/budget limit stopped the run.
Input example
{"startDate": "2024-01-02","endDate": "2024-01-02","baseCurrency": "EUR","currencies": ["USD"]}
Use the input schema for the remaining filters and defaults.
Source example
The saved tests/fixtures/ecb_daily.csv, retrieved with the URL in tests/fixtures/SOURCE.json, includes:
KEY,TIME_PERIOD,OBS_VALUEEXR.D.USD.EUR.SP00.A,2024-01-02,1.0956EXR.D.GBP.EUR.SP00.A,2024-01-02,0.86645EXR.D.JPY.EUR.SP00.A,2024-01-02,155.68
These are selected columns from the actual source response. For USD/GBP, the resulting calculation is 0.86645 / 1.0956, or approximately 0.7908451989777292. The complete actor JSON sample is generated by tools/acceptance.py only after an actual local actor run. Its generation is currently blocked by this build session's process-launch failure; no actor output has been fabricated.
Output contract example for that observed EUR/USD value (selected fields, not a captured actor run):
{"date": "2024-01-02","baseCurrency": "EUR","quoteCurrency": "USD","rate": 1.0956,"kind": "reference","status": "ok","source": "ECB","baseEurRate": 1,"quoteEurRate": 1.0956,"sourceSeries": ["EXR.D.USD.EUR.SP00.A"],"errors": []}
Pricing
Proposed event rate: $0.05 per block of up to 100 successful rows. The final partial block rounds up to one event; 1–100 successful rows cost $0.05, and 1,000 cost $0.50. Diagnostics add no rate events. Prices are proposals awaiting owner publication and configuration; see PRICING.md for the live Store comparison and rounding caveat.
Limits and source behavior
- These are reference observations, not executable trading quotes. ECB discourages their use for transaction purposes.
- Only currencies and dates covered by ECB are available. Coverage changes over time; historical discontinued currencies can have shorter ranges.
- Weekends, holidays, missing base/quote observations and delayed current-day publication cannot produce a successful pair rate.
- Dates are requested in 90-day windows. Rows are ordered by window, observation date and target input order; range-level errors follow dated rows in that window.
- The cap includes diagnostic rows. A small cap can leave later currencies/dates unreturned.
- Requests use bounded concurrency and three attempts with backoff for throttling, server errors, transport failures or invalid source bodies. An exhausted source failure becomes a diagnostic for affected pairs.
- Each run is independent; restarting a run does not promise cross-run deduplication or billing recovery.
FAQ
What limits the output? The maxItems input caps output rows; its schema maximum is 100,000. Source availability and errors may yield fewer rows.
Does it need a proxy, login, or API key? The actor calls public ECB endpoints without an API key, login, or proxy input.
How is it priced? PRICING.md proposes $0.05 per block of up to 100 successful rate rows, including a final partial block. This is not an applied Store price.
What happens on rate limits? The ECB client retries throttling and server failures with backoff and Retry-After. Missing observations are not filled from another date.
How fresh is the data? The date is the ECB observation date; fetchedAt is retrieval time. Missing dates are not interpolated.
Are cross rates carried forward? No. A cross rate uses observations published for the same date.
Use with AI agents / MCP
An AI agent can call a published actor through the Apify MCP server or Apify API, pass the JSON input, then read the run’s default dataset. Check the actor’s published identifier and permissions in your Apify account.
Expose this actor through Apify's MCP server after the owner publishes it. An agent can pass an explicit historical date range, base code and quote codes, then read the default dataset. Ask the agent to retain date, sourceUrls, status and errors when explaining results; fetchedAt is retrieval time, not the date of the rate. This package does not claim a tested hosted MCP integration.
Local development and verification
The supplied input file lives at storage/key_value_stores/default/INPUT.json. On this Windows workspace, run from the actor directory:
$env:APIFY_LOCAL_STORAGE_DIR = "$PWD/storage"& C:/GritWork/earn/.venv/Scripts/python.exe -m src& C:/GritWork/earn/.venv/Scripts/python.exe -m pytest -q -m "not live"& C:/GritWork/earn/.venv/Scripts/python.exe -m pytest -q -m liveapify validate-schema
For the complete acceptance pass, use & C:/GritWork/earn/.venv/Scripts/python.exe tools/acceptance.py. It runs tests, validates schemas, executes real local actor probes and writes an actual <=20-row sample_output.json with evidence. It does not publish or install packages. For development elsewhere, create a separate environment from requirements.txt and use Python 3.12; pytest is a development-only prerequisite.
Current verification status: source fixture and Store research fetched successfully; Python tests, actor runs, CLI schema validation and independent review are blocked by process-launch access denial in this session. See REPORT.md.