---
name: frankfurter-ingestion
description: "How to get Frankfurter data into a pandas DataFrame and Parquet: access, the request, the format, limits, quirks and terms."
---

# Load Frankfurter exchange rates into pandas and Parquet

Source entry: https://signal-lab-jet.vercel.app/datasets/frankfurter
Provider: https://frankfurter.dev
Checked against the provider's documentation: 2026-10-29

## Access
- No API key or account.

## Request
```bash
curl 'https://api.frankfurter.dev/v2/providers/ecb/rates?from=2026-10-20&quotes=usd,gbp'
```

## Format
JSON array of rows {date, base, quote, rate}, one row per date and currency (rate is a number). CSV with a .csv suffix and NDJSON with Accept: application/x-ndjson are also offered.

## Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
```python
"""Frankfurter (ECB reference rates via the ECB provider route) -> pandas -> Parquet. No key."""
import requests
import pandas as pd

r = requests.get("https://api.frankfurter.dev/v2/providers/ecb/rates",
                 params={"from": "2020-01-01", "quotes": "usd,gbp,jpy"}, timeout=60)
r.raise_for_status()
rows = r.json()                      # [{"date": "2026-10-20", "base": "EUR", "quote": "USD", "rate": 1.1215}, ...]
df = pd.DataFrame(rows)
df["date"] = pd.to_datetime(df["date"])
wide = df.pivot(index="date", columns="quote", values="rate").reset_index()   # one column per currency
wide.to_parquet("frankfurter_ecb_eur.parquet", index=False)
print(len(df), "rows", len(wide), "dates", wide["date"].min().date(), "to", wide["date"].max().date())
```
Run by us on 2026-10-29 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 5,253 rows (1,751 dates for USD, GBP and JPY against EUR), 2019-12-31 to 2026-10-29.

## Limits
- No daily or monthly caps; requests are rate-limited to prevent abuse (no number published).
- For large date ranges, narrow the currencies with quotes, or request NDJSON to stream.

## Quirks
- /v2/rates blends rates across providers by default; the snippet uses /v2/providers/ecb/rates for the ECB reference rates only.
- Observed 2026-10-29: the ECB route has business days only, while the blended /v2/rates answered for a Sunday (2026-10-25).
- Observed 2026-10-29: from=2020-01-01 started at 2019-12-31, the last ECB rate on or before that date.
- v1 is deprecated in favor of v2 but stays available.

## Terms and attribution
- Frankfurter says the API is free for commercial use and that storing daily rates locally is encouraged.
- Frankfurter does not own the rates: direct provider routes (such as /v2/providers/ecb) stay subject to that provider's terms.
- Rates come as is, with no warranty, and can be late, missing or revised.
- Terms page: https://frankfurter.dev/license/

## Sources
- https://frankfurter.dev/: "You don't need an API key."
- https://frankfurter.dev/: "There are no quotas. Requests are rate-limited to prevent abuse, but there are no monthly or daily caps."
- https://frankfurter.dev/: "Direct queries to individual provider endpoints remain subject to each provider's terms"
- https://frankfurter.dev/: "Storing daily observations locally for caching or historical analytics is encouraged to keep API traffic light."
- https://frankfurter.dev/: "By default, rates are blended across all providers."
- https://frankfurter.dev/license/: "Frankfurter doesn't own the rates, so it can't give you rights the provider doesn't."
- https://frankfurter.dev/license/: "Rates can be late, missing, or revised."

Information for educational purposes only. Free tiers, limits and licenses belong to the providers and may change; check the provider's own terms before using the data.
