Python
Você não precisa de SDK. O Frankfurter é HTTPS puro e retorna JSON plano, então a biblioteca HTTP que você já usa resolve. Sem chave de API, sem cadastro.
Início rápido
Busque uma cotação e converta:
import requests
res = requests.get("https://api.frankfurter.dev/v2/rate/usd/eur")
data = res.json()
total = 100 * data["rate"] A resposta é um objeto plano: {"date": "2026-07-17", "base": "USD", "quote": "EUR", "rate": 0.8739}. Um código de moeda inválido retorna 422 com uma mensagem em JSON.
Cálculos monetários precisos
Floats servem para exibir valores, não para contabilidade. Faça o parse das cotações como Decimal passando parse_float para o 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"]Várias cotações de uma vez
/v2/rates retorna um array plano, com uma linha por cotação. Transforme-o num dicionário com uma dict comprehension. Omita quotes para receber todas as moedas.
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()}Faça cache do que não muda
As cotações históricas de um provedor fixado não mudam, então podem ficar em cache para sempre. As cotações combinadas podem mudar quando chegam dados novos, e as mais recentes mudam quando os provedores publicam, no máximo algumas vezes por dia útil. Para essas, um TTL curto basta. Com requests-cache, o cache fica em uma linha:
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
Numa aplicação web assíncrona, use 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"]Fixar uma fonte oficial
Por padrão, você recebe a combinação de todas as fontes. Adicione providers para fixar uma única autoridade, o que importa quando uma jurisdição exige a taxa publicada pelo próprio banco central, como a taxa de referência do BCE para o IVA da UE.
res = requests.get(
"https://api.frankfurter.dev/v2/rate/usd/eur",
params={"providers": "ecb"},
)
data = res.json()Veja todas as fontes. Uma fonte fixada segue o próprio calendário de publicação, então a cotação mais recente dela pode ficar um dia atrás da cotação combinada mais recente.
Analisando uma série?
Para intervalos de datas, agrupamento mensal e gráficos, o endpoint CSV carrega direto num DataFrame. Veja pandas.