Des questions ou un problème ? Écris dans les GitHub Discussions.

Pas besoin de SDK. Frankfurter, c'est du HTTPS simple qui renvoie du JSON plat : la bibliothèque HTTP que tu utilises déjà suffit. Pas de clé API, pas de compte.

Démarrage rapide

Récupère un taux et convertis :

import requests

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

La réponse est un objet plat : {"date": "2026-07-17", "base": "USD", "quote": "EUR", "rate": 0.8739}. Un code de devise invalide renvoie une erreur 422 avec un message JSON.

Calculs monétaires exacts

Les floats conviennent pour l'affichage, pas pour la comptabilité. Parse les taux en Decimal en passant parse_float à json.loads :

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"]

Plusieurs devises à la fois

/v2/rates renvoie un tableau plat, avec une ligne par devise cible. Transforme-le en dictionnaire avec une compréhension. Omets quotes pour obtenir toutes les devises.

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()}

Mettre en cache ce qui ne change pas

Les taux historiques d'un fournisseur choisi ne changent pas : mets-les en cache pour de bon. Les taux combinés peuvent bouger quand de nouvelles données arrivent, et les derniers taux changent au fil des publications, au plus quelques fois par jour ouvré. Pour ceux-là, un TTL court suffit. Avec requests-cache, le cache tient en une ligne :

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()

Asynchrone

Dans une application web asynchrone, utilise 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"]

Choisir une source officielle

Par défaut, tu obtiens le taux combiné de toutes les sources. Ajoute providers pour t'en tenir à une autorité précise, ce qui compte quand une juridiction impose le taux publié par sa banque centrale, comme le taux de référence de la BCE pour la TVA européenne.

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

Consulte toutes les sources. Une source choisie suit son propre calendrier de publication : son dernier taux peut donc avoir un jour de retard sur le dernier taux combiné.

Analyser une série ?

Pour les plages de dates, les regroupements mensuels et les graphiques, l'endpoint CSV se charge directement dans un DataFrame. Voir pandas.