Fragen oder Probleme? Melde dich in den GitHub Discussions.

Du brauchst kein SDK. Frankfurter verwendet reines HTTPS und liefert flaches JSON. Die HTTP-Bibliothek, die du ohnehin nutzt, reicht völlig aus. Kein API-Schlüssel, kein Benutzerkonto.

Schnellstart

Kurs abrufen und umrechnen:

import requests

res = requests.get("https://api.frankfurter.dev/v2/rate/usd/eur")
data = res.json()
total = 100 * data["rate"]

Die Antwort ist ein flaches Objekt: {"date": "2026-07-17", "base": "USD", "quote": "EUR", "rate": 0.8739}. Ein ungültiger Währungscode liefert den HTTP-Status 422 mit einer JSON-Meldung.

Finanzmathematik ohne Rundungsfehler

Gleitkommazahlen (Floats) genügen zur reinen Anzeige, sind für die Buchhaltung jedoch ungeeignet. Parse Kurse als Decimal, indem du parse_float an json.loads durchreichst:

from decimal import Decimal

import requests

res = requests.get("https://api.frankfurter.dev/v2/rate/usd/eur")
data = res.json(parse_float=Decimal)
total = Decimal("100") * data["rate"]

Mehrere Kurse auf einmal

/v2/rates liefert ein flaches Array mit einer Zeile pro Zielwährung. Wandle es per Dictionary Comprehension in ein Lookup um. Wenn du quotes weglässt, erhältst du alle Währungen.

res = requests.get(
    "https://api.frankfurter.dev/v2/rates",
    params={"base": "usd", "quotes": "eur,gbp,jpy"},
)
rates = {row["quote"]: row["rate"] for row in res.json()}

Cachen, was sich nicht ändert

Historische Kurse sind unveränderlich, du kannst sie dauerhaft im Cache halten. Aktuelle Kurse ändern sich nur, wenn Quellen veröffentlichen, meist wenige Male am Werktag; ein kurzes TTL reicht völlig. Mit requests-cache genügt dafür eine einzige Zeile:

import requests_cache

session = requests_cache.CachedSession("frankfurter", expire_after=3600)
res = session.get("https://api.frankfurter.dev/v2/rate/usd/eur")
data = res.json()

Async

In einer asynchronen Webanwendung empfiehlt sich httpx:

import httpx

API = "https://api.frankfurter.dev"


async def rate(base, quote):
    async with httpx.AsyncClient(base_url=API) as client:
        res = await client.get(f"/v2/rate/{base}/{quote}")
        res.raise_for_status()
        return res.json()["rate"]

Offizielle Quelle festlegen

Standardmäßig erhältst du den Mischkurs aller Quellen. Ergänze providers, um eine bestimmte Institution festzulegen. Das ist wichtig, wenn eine Rechtsordnung den veröffentlichten Kurs ihrer Zentralbank verlangt, wie den EZB-Referenzkurs für die EU-Umsatzsteuer.

res = requests.get(
    "https://api.frankfurter.dev/v2/rate/usd/eur",
    params={"providers": "ecb"},
)
data = res.json()

Alle Quellen ansehen. Eine festgelegte Quelle folgt ihrem eigenen Veröffentlichungsrhythmus, sodass ihr neuester Kurs dem kombinierten Kurs um einen Tag hinterherhinken kann.

Zeitreihen analysieren?

Für Zeiträume, monatliche Gruppierungen und Diagramme lädt der CSV-Endpoint direkt in ein DataFrame. Siehe pandas.