Metadata-Version: 2.4
Name: ecb-exchange-rate
Version: 1.0.2
Summary: Official European Central Bank exchange rates - ~41 currencies vs EUR, history since 1999. Keyless, zero-dependency Python client.
Author-email: AllRatesToday <info@allratestoday.com>
License-Expression: MIT
Project-URL: Homepage, https://allratestoday.com/central-bank-rates-api/ecb/
Project-URL: Documentation, https://allratestoday.com/docs
Project-URL: Repository, https://github.com/AllRates-Today/exchange-rates-api
Project-URL: Issues, https://github.com/AllRates-Today/exchange-rates-api/issues
Keywords: allratestoday,bank,central,central-bank,currency,ecb,eur,european,exchange-rate,exchange-rates,forex,fx,official-rates
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Office/Business :: Financial :: Accounting
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# European Central Bank Exchange Rates for Python — ecb-exchange-rate

[![PyPI version](https://img.shields.io/pypi/v/ecb-exchange-rate.svg)](https://pypi.org/project/ecb-exchange-rate/)
[![Python versions](https://img.shields.io/pypi/pyversions/ecb-exchange-rate.svg)](https://pypi.org/project/ecb-exchange-rate/)
[![license](https://img.shields.io/pypi/l/ecb-exchange-rate.svg)](https://github.com/AllRates-Today/ecb-exchange-rate/blob/main/LICENSE)
[![zero dependencies](https://img.shields.io/badge/dependencies-0-brightgreen.svg)](https://pypi.org/project/ecb-exchange-rate/)
[![EUR/USD today](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fallratestoday.com%2Fapi%2Fopen%2Fcentral-bank%2Fecb%3Fsource%3DEUR%26target%3DUSD&query=%24.rate&label=EUR%2FUSD%20published%20by%20European%20Central%20Bank&color=0A7E8C&cacheSeconds=3600)](https://allratestoday.com/central-bank-rates-api/ecb/)
[![rate date](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fallratestoday.com%2Fapi%2Fopen%2Fcentral-bank%2Fecb%3Fsource%3DEUR%26target%3DUSD&query=%24.rate_date&label=rate%20date&color=555&cacheSeconds=3600)](https://allratestoday.com/central-bank-rates-api/ecb/)

**Official European Central Bank exchange rates for Python. The published central bank rates behind tax filings, customs valuations, audits and compliant invoicing — not market estimates, but the numbers European Central Bank itself prints, with its own `rate_date` on every response. The latest table needs no API key.**

## 🚀 Why this package?

- 🏛️ **Official published rates** — European Central Bank's own table, with the publisher's own `rate_date` on every response
- 🔓 **No key for the latest table** — `get_latest_rates()` and `get_rate()` work the moment the package is installed
- 📅 **History back to 1999** — point-in-time tables and daily series on a [paid plan](https://allratestoday.com/pricing/)
- 🔀 **Published vs derived, always flagged** — computed inverse/cross pairs carry `derived: True`, never mixed with official prints
- ⚡ **Zero dependencies** — standard library only (`urllib`), Python 3.9+
- 🔷 **Typed** — ships `py.typed` for mypy and pyright

> **Official rate, not mid-market:** every value here is a number European Central Bank itself published, fixed once printed — what filings and audits require. Need the live mid-market rate for pricing or display instead? Use [`allratestoday`](https://pypi.org/project/allratestoday/). The two can diverge by several percent. For all 120+ central banks and tax authorities in one package, use [`allratestoday-central-bank`](https://pypi.org/project/allratestoday-central-bank/).

## 📦 Installation

```bash
pip install ecb-exchange-rate
```

Requires Python 3.9+. No dependencies. The import name is `ecb_exchange_rate`.

## 🏁 Quick start

```python
from ecb_exchange_rate import get_rate

pair = get_rate("USD", "EUR")
print(pair["rate"], "published", pair["rate_date"])  # no API key needed
```

## 📈 Latest published table

[![Latest European Central Bank table](https://allratestoday.com/api/open/central-bank/ecb/table.svg)](https://allratestoday.com/central-bank-rates-api/ecb/)

The image is rendered live from the keyless endpoint, so it stays current on PyPI without a new release.

Source: [Official rates published by European Central Bank, served by AllRatesToday](https://allratestoday.com/central-bank-rates-api/ecb/). Rates are as printed by the central bank; AllRatesToday is not affiliated with it.

## 📚 API reference

### Latest published table — no key

```python
from ecb_exchange_rate import get_latest_rates

table = get_latest_rates()
print(table["rate_date"], len(table["rates"]))
for row in table["rates"][:3]:
    print(row["base"], row["quote"], row["type"], row["value"])
```

Returns `{"bank", "rate_date", "age_days", "stale", "cadence", "rates": [{"base", "quote", "type", "value"}], "attribution"}`.

### One pair — no key

```python
from ecb_exchange_rate import get_rate

pair = get_rate("USD", "EUR")
pair["rate"], pair["rate_date"], pair["derived"], pair["method"]
```

`method` is `published`, `inverse` or `cross`; anything but `published` comes with `derived: True`.

### Table for a date — paid plan

```python
from ecb_exchange_rate import get_rates_for_date

table = get_rates_for_date("2026-01-15", api_key="art_live_...")
pair = get_rates_for_date("2026-01-15", source="USD", target="EUR", api_key="art_live_...")
```

Weekends and holidays roll back to the last date European Central Bank actually published; the returned `rate_date` says which.

### Daily series — paid plan

```python
from ecb_exchange_rate import get_history

series = get_history(source="USD", target="EUR",
                     from_date="2026-01-01", to_date="2026-03-31",
                     api_key="art_live_...")
```

Billed by volume: one call per currency per month of data returned.

## 📖 Methods reference

| Function | Key | Returns |
|---|---|---|
| `get_latest_rates()` | none | Newest published table |
| `get_rate(source, target)` | none | One pair from it, `derived` flagged |
| `get_rates_for_date(date, source=None, target=None, api_key=None)` | paid plan | The table (or one pair) in force on a date |
| `get_history(symbol=None, source=None, target=None, from_date=None, to_date=None, api_key=None)` | paid plan | Date-by-date official series |

Dates accept `"YYYY-MM-DD"`, `date` or `datetime`. Keyed calls read `api_key=` or the `ALLRATES_API_KEY` environment variable. Module constants: `BANK_CODE` (`"ecb"`), `BANK_NAME`, `HOME_CURRENCY` (`"EUR"`).

## 🔑 API key

The latest table is keyless. Dated tables and history need a key on a [paid plan](https://allratestoday.com/pricing/) — [register](https://allratestoday.com/register) (free, no card), then upgrade from the [dashboard](https://allratestoday.com/profile).

```bash
export ALLRATES_API_KEY=art_live_...
```

## 🛡️ Error handling

Every failure raises `ExchangeRateError`, with the HTTP status on `.status` when the server answered:

```python
from ecb_exchange_rate import get_rate, ExchangeRateError

try:
    get_rate("USD", "XXX")
except ExchangeRateError as err:
    print(err, err.status)  # human-readable reason, e.g. 404
```

| Status | Meaning |
|---|---|
| `None` | Network error or timeout (10 s) |
| `401` | Missing or invalid API key |
| `403` | Your plan does not include this endpoint (dated tables and history are paid) |
| `404` | No published rate for that pair or date |
| `429` | Quota or rate limit reached |

## 🗺️ Currencies covered

European Central Bank currently publishes rates covering **29 currencies** against the EUR (as of the latest table):

🇦🇺 `AUD` · 🇧🇷 `BRL` · 🇨🇦 `CAD` · 🇨🇭 `CHF` · 🇨🇳 `CNY` · 🇨🇿 `CZK` · 🇩🇰 `DKK` · 🇬🇧 `GBP` · 🇭🇰 `HKD` · 🇭🇺 `HUF` · 🇮🇩 `IDR` · 🇮🇱 `ILS` · 🇮🇳 `INR` · 🇮🇸 `ISK` · 🇯🇵 `JPY` · 🇰🇷 `KRW` · 🇲🇽 `MXN` · 🇲🇾 `MYR` · 🇳🇴 `NOK` · 🇳🇿 `NZD` · 🇵🇭 `PHP` · 🇵🇱 `PLN` · 🇷🇴 `RON` · 🇸🇪 `SEK` · 🇸🇬 `SGD` · 🇹🇭 `THB` · 🇹🇷 `TRY` · 🇺🇸 `USD` · 🇿🇦 `ZAR`

## 🏛️ Source

The European Central Bank is the central bank of the 20 euro-area countries. Its euro foreign exchange reference rates — around 30 currencies against the euro — are published every business day at about 16:00 CET and serve as the standard conversion reference across the EU.

- Publisher's own page: [Euro foreign exchange reference rates](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html) · [www.ecb.europa.eu](https://www.ecb.europa.eu)
- Publication: every business day; the exact schedule, freshness status and any current delay are on the [European Central Bank rates page](https://allratestoday.com/central-bank-rates-api/ecb/)
- Values are stored unmodified, with the publisher's own `rate_date` on every row — see the [methodology](https://allratestoday.com/official-rates-methodology/)

## 🧭 Reading the numbers

- `value` is always **quote currency per 1 unit of base currency** (`base: "EUR", quote: "USD", value: 1.15` means 1 EUR = 1.15 USD).
- European Central Bank quotes **foreign currency per 1 EUR** (e.g. `base: "EUR", quote: "USD"` means USD per one EUR).
- Need the other way round? Ask `get_rate(target, source)` and the API inverts or crosses for you, flagged `derived: true` — never divide a published rate yourself in a compliance workflow.
- `rate_type` tells you which of the central bank's series a row belongs to (`reference` here); some publishers print buy/sell or several fixings for the same pair.

## ⚖️ Published vs derived rates

If European Central Bank does not print a pair directly, the API resolves it from the central bank's own table and says so — official and computed values are never confused:

| `method` | `derived` | Meaning |
| --- | --- | --- |
| `published` | `false` | The central bank printed this pair directly |
| `inverse` | `true` | Computed as 1 ÷ the published opposite direction |
| `cross` | `true` | Computed via EUR from two published rates |

## 🧩 ERP & accounting systems

Loading the official European Central Bank rate into an accounting system is a supported workflow, not a hack. Step-by-step guides with the direction each system expects:

- [Dynamics 365 Business Central](https://allratestoday.com/docs/integrations/business-central/) — built-in Currency Exchange Rate Service, no code
- [Xero](https://allratestoday.com/docs/integrations/xero/) · [QuickBooks Online](https://allratestoday.com/docs/integrations/quickbooks/) · [SAP S/4HANA and ECC](https://allratestoday.com/docs/integrations/sap/) · [Odoo](https://allratestoday.com/docs/integrations/odoo/)

The same keyed endpoints return `?format=csv`, `?format=xml` and `?format=xlsx`, and accept the key as `?api_key=` on the URL for importers that cannot send headers:

```bash
curl "https://allratestoday.com/api/v1/central-bank/ecb/latest?format=xml&api_key=art_live_..."
```

## 🤖 AI agents

- MCP server: `npx -y @allratestoday/central-bank-mcp` (stdio) or the hosted endpoint `https://allratestoday.com/api/mcp` — tools for official rates, history, cross-bank comparison and publication calendars
- Already using the general SDK or MCP server? Since 2026-10-01 [`@allratestoday/sdk`](https://www.npmjs.com/package/@allratestoday/sdk) 1.4+ has `officialRates('ecb')` and [`@allratestoday/mcp-server`](https://www.npmjs.com/package/@allratestoday/mcp-server) 0.6+ has a `get_official_rates` tool — both return this source's latest table with no key, so you can add it without a second dependency
- Claude Code plugin (no key): `/plugin marketplace add AllRates-Today/claude-code-plugin` then `/plugin install allratestoday@allratestoday` — bundles both MCP servers plus an `/official-rate ecb ...` command
- Evaluating? Agents can self-issue a trial key with no signup: `POST https://allratestoday.com/api/agent/keys` (send `Content-Type: application/json`) returns a 100-call key valid 7 days that covers the free-plan methods (latest table, pairs); dated tables and history need a [paid plan](https://allratestoday.com/pricing/). The MCP servers expose it as `request_trial_key`
- Machine-readable site guide: [llms.txt](https://allratestoday.com/llms.txt) · [for-ai-agents](https://allratestoday.com/for-ai-agents/)

## 💡 Caching tip

European Central Bank publishes at most once per business day — cache `get_latest_rates()` for a few hours and you will rarely hit the network.

## 📥 Bulk data (no key)

Need the whole archive rather than an API call? The same published tables are mirrored daily as open data:

- Hugging Face: [AllRatesToday/central-bank-exchange-rates](https://huggingface.co/datasets/AllRatesToday/central-bank-exchange-rates) — one CSV per institution (`rates/ecb.csv`)
- Kaggle: [allratestoday/central-bank-exchange-rates](https://www.kaggle.com/datasets/allratestoday/central-bank-exchange-rates)
- Raw JSON on GitHub: `https://raw.githubusercontent.com/AllRates-Today/central-bank-exchange-rates/main/data/ecb/latest.json`

## 🔗 Links

- [European Central Bank rates page](https://allratestoday.com/central-bank-rates-api/ecb/) — live table, publication cadence, FAQ
- [All central bank sources](https://allratestoday.com/central-bank-rates-api/)
- [Package docs on the site](https://allratestoday.com/docs/sdk/ecb-exchange-rate/) · [ERP integration guides](https://allratestoday.com/docs/integrations/)
- [API documentation](https://allratestoday.com/docs/#central-bank) · [Interactive reference](https://allratestoday.com/api-reference/) · [Methodology](https://allratestoday.com/official-rates-methodology/)
- [Register (Free)](https://allratestoday.com/register) · [Dashboard](https://allratestoday.com/profile) · [Pricing](https://allratestoday.com/pricing/)
- [Status](https://allratestoday.com/status)
- [GitHub](https://github.com/AllRates-Today/ecb-exchange-rate)
- Node.js equivalent: [`ecb-exchange-rate`](https://www.npmjs.com/package/ecb-exchange-rate) on npm

## 📜 License

MIT. Rates are served as published by European Central Bank; AllRatesToday is not affiliated with it.
