Frankfurter es una API gratuita de tipos de cambio para 223 divisas de 104 bancos centrales y fuentes oficiales. Los tipos se actualizan a diario y se remontan a 1948.

La API pública está en api.frankfurter.dev y no necesita clave API. El proyecto es de código abierto, así que también puedes alojarlo tú mismo para tener control total.

¿Trabajas con un agente de IA? Pásale el llms.txt o añade el servidor MCP.

Tipos de cambio

Obtén los últimos tipos de cambio.

curl https://api.frankfurter.dev/v2/rates

Cambia la divisa base con base.

curl https://api.frankfurter.dev/v2/rates?base=usd

Filtra las divisas de destino con quotes.

curl https://api.frankfurter.dev/v2/rates?quotes=usd,gbp

Tipos históricos

Consulta los tipos de una fecha concreta.

curl https://api.frankfurter.dev/v2/rates?date=1999-01-04

Series temporales

Obtén los tipos de un período con from y to.

curl https://api.frankfurter.dev/v2/rates?from=2026-01-01&quotes=usd

Consejo: Limitar las divisas mantiene las respuestas ligeras. Para rangos de fechas largos, pide NDJSON y recibe los resultados en streaming, línea a línea.

Agrupación

Reduce la resolución de una serie temporal con group. Admite week y month.

curl https://api.frankfurter.dev/v2/rates?from=2026-01-01&group=month

Filtrar por fuente

Limita la consulta a fuentes concretas con providers.

curl https://api.frankfurter.dev/v2/rates?providers=ecb

Por defecto, la API combina los tipos de todas las fuentes. Usa providers para obtener los tipos de una fuente concreta o consulta esa fuente directamente con sus propias rutas.

Atribución de fuentes

Añade expand=providers para ver qué fuentes intervienen en cada tipo combinado.

curl https://api.frankfurter.dev/v2/rates?expand=providers

Cada fila incluye un array providers con las claves de las fuentes que contribuyen. Las filas de divisas con paridad fija no llevan este campo: esos tipos salen de la paridad, no de los datos de las fuentes.

Salida CSV

Los tipos también están disponibles en CSV. Añade .csv a la ruta o envía la cabecera Accept con text/csv.

curl https://api.frankfurter.dev/v2/rates.csv

Salida NDJSON

Para respuestas grandes, pide NDJSON (JSON delimitado por saltos de línea) enviando la cabecera Accept con application/x-ndjson. Cada línea es un objeto JSON independiente, así que puedes procesar series temporales largas en streaming sin cargar toda la respuesta en memoria.

curl https://api.frankfurter.dev/v2/rates?from=2026-01-01

Tipo individual

Obtén el tipo de cambio de un solo par de divisas. Si quieres, añade date o providers.

curl https://api.frankfurter.dev/v2/rate/eur/usd

Divisas

Obtén las divisas disponibles y qué fuentes las cubren.

curl https://api.frankfurter.dev/v2/currencies

Incluye divisas retiradas con scope.

curl https://api.frankfurter.dev/v2/currencies?scope=all

Divisa individual

Obtén los detalles de una divisa y qué fuentes la cubren.

curl https://api.frankfurter.dev/v2/currency/eur

Fuentes

Lista las fuentes de datos que usa la API.

curl https://api.frankfurter.dev/v2/providers

Obtén los detalles de una fuente concreta.

curl https://api.frankfurter.dev/v2/providers/ecb

Tipos por fuente

Consulta los tipos de una fuente concreta directamente. Admite los mismos parámetros que /v2/rates y /v2/rate.

curl https://api.frankfurter.dev/v2/providers/ecb/rates

Obtén un solo par de divisas de esa fuente.

curl https://api.frankfurter.dev/v2/providers/ecb/rate/eur/usd

Combínalo con date, rangos de fechas (from y to) o agrupación. Los formatos como .csv y ndjson también funcionan aquí.

curl https://api.frankfurter.dev/v2/providers/ecb/rates?date=2024-05-15

Conversión

No hay endpoint de conversión. Obtén el tipo y convierte con unas pocas líneas de código.

function convert(base, quote, amount) {
  const api = "https://api.frankfurter.dev";
  return fetch(`${api}/v2/rate/${base}/${quote}`)
    .then((r) => r.json())
    .then((d) => (amount * d.rate).toFixed(2));
}

convert("eur", "usd", 10).then((result) =>
  alert(`10 EUR = ${result} USD`)
);

Errores

La API responde con códigos de estado HTTP estándar y un cuerpo JSON.

{
  "status": 422,
  "message": "invalid currency: ABC"
}
400
Parámetro no válido o petición mal formada.
404
Divisa, tipo de cambio o recurso no encontrado.
422
Petición entendida, pero no se puede procesar.

Self-hosting

Puedes alojar Frankfurter tú mismo con Docker. La guía de despliegue explica la configuración para producción y las claves API.

FAQ

¿Para quién es Frankfurter (y para quién no)?
Funciona bien para facturación SaaS, e-commerce, informes fiscales, sistemas ERP y de contabilidad, e investigación académica con series históricas desde 1948. No está pensado para trading en tiempo real ni para negocios con divisas exóticas sujetas a fuertes oscilaciones intradía.
¿La API es gratis para uso comercial?
Sí. Los tipos en sí se rigen por las condiciones de cada proveedor.
¿Tiene la API límites de llamadas?
No hay cuotas. Las peticiones tienen un rate limit para evitar abusos, pero sin topes diarios ni mensuales. Para volúmenes altos, cachea las respuestas, aloja tu propia instancia o consulta los datasets directamente.
¿La API admite GraphQL?
No. La API REST es tan simple que GraphQL solo añadiría complejidad sin mucho beneficio. Además, rompería la caché en el edge, que es lo que la hace rápida. Usa parámetros de consulta como base, quotes y from/to para obtener exactamente los datos que necesitas.
¿Se va a retirar la API v1?
No. La API v1 está obsoleta en favor de v2, pero seguirá disponible indefinidamente. Consulta la documentación de v1. Para datos del Banco Central Europeo, usa /v2/providers/ecb/rates.
¿Cuál es la política de privacidad de la API?
La API no recopila ni registra datos personales, direcciones IP ni URLs de las peticiones. La instancia pública funciona detrás de Cloudflare, que aporta caché y protección DDoS y solo ofrece estadísticas de tráfico agregadas.
¿Tengo que declarar la API en las etiquetas de privacidad de la App Store o Google Play?
No. Como las consultas son anónimas y no se guardan registros de las peticiones, cuentan como datos no recopilados según las directrices de Apple y Google Play.
¿Dónde puedo reportar un error o hacer una pregunta?
Abre una issue para reportar un error, pedir una funcionalidad o sugerir una nueva fuente de datos. Usa Discussions para hacer preguntas o compartir una librería o herramienta que hayas creado con Frankfurter.
¿Qué precisión tienen los tipos?
Para cumplimiento normativo, filtra por una fuente concreta y obtendrás sus tipos de referencia oficiales. Para uso general, los tipos combinados por defecto funcionan bien, aunque los últimos decimales pueden variar a medida que llegan datos nuevos.
¿Los tipos son medios, de compra o de venta?
La API devuelve tipos medios de mercado (mid-market). Si una fuente publica tipos de compra y venta en lugar de un tipo de referencia, Frankfurter guarda ambos y calcula el punto medio.
¿Todos los tipos son diarios?
Casi todos. Algunas fuentes ofrecen observaciones semanales, mensuales o trimestrales. Estas fuentes no entran en el feed combinado. Consúltalas directamente con el filtro providers.
¿Por qué se solapan las fechas de algunas divisas antiguas y nuevas?
Algunas fuentes retrotraen la divisa nueva al período de la antigua (por ejemplo, TRL termina en 2010 y TRY empieza en 1996). Guardamos los datos de las fuentes tal cual y solo filtramos los solapamientos al combinarlos.
¿Por qué Frankfurter?
Porque el Banco Central Europeo, nuestra fuente de datos original, está en Fráncfort.
European Central Bank and Main riverfront, Frankfurt