Frankfurter registra tipos de cambio diarios de 98 bancos centrales y fuentes oficiales para 206 divisas. Los datos se remontan a 1948.

La API pública está disponible en api.frankfurter.dev y no requiere clave API. El proyecto es de código abierto. Para un control total también puedes autohospedarlo.

¿Trabajas con un agente de IA? Proporciónale llms.txt o conecta el servidor MCP.

Tipos de cambio

Obtén los tipos de cambio más recientes.

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 tipos para una fecha concreta.

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

Series temporales

Obtén tipos de cambio a lo largo de un período con from y to.

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

Consejo: Consulta solo las divisas que necesitas para mantener las respuestas reducidas. En rangos de fechas extensos, solicita NDJSON para recibir los resultados en streaming línea a línea.

Agrupación

Reduce la resolución de una serie temporal con group. Valores admitidos: week y month.

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

Filtrar por fuente

Consulta únicamente fuentes específicas con providers.

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

Por defecto, la API combina los tipos de cambio de todas las fuentes. Para obtener los tipos de una sola fuente, utiliza providers o consulta directamente sus rutas específicas.

Atribución de fuentes

expand=providers muestra qué fuentes han contribuido a cada tipo combinado.

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

Cada registro incluye un array providers con las claves de las fuentes participantes. En las divisas con tipo de cambio fijo este campo se omite, ya que proceden de la paridad y no de datos de fuentes.

Salida CSV

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

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

Salida NDJSON

Para respuestas extensas, solicita NDJSON (JSON delimitado por saltos de línea) definiendo la cabecera Accept como application/x-ndjson. Cada línea es un objeto JSON independiente, lo que permite recibir series temporales largas en streaming sin almacenar en búfer toda la respuesta.

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

Tipo individual

Obtén el tipo de cambio para un único par de divisas.

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

Divisas

Obtén las divisas disponibles y sus fuentes de datos.

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

Incluye divisas históricas con scope.

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

Divisa individual

Obtén detalles y fuentes de una divisa concreta.

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

Fuentes

Lista las fuentes de datos de la API.

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

Obtén detalles sobre una fuente concreta.

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

Tipos por fuente

Consulta tipos directamente de una fuente determinada. Se admiten los mismos parámetros que en /v2/rates y /v2/rate.

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

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

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

Obtén tipos de un par de divisas para un período. Se puede combinar 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 existe un endpoint de conversión específico. Obtén el tipo de cambio 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.

{
  "message": "Could not find currency ABC"
}
400
Parámetro no válido o solicitud incorrecta.
404
Divisa, tipo de cambio o recurso no encontrado.
422
Solicitud comprendida, pero no puede ser procesada.

Self-Hosting

Puedes autohospedar Frankfurter con Docker. La guía de deploy explica la puesta en producción y la configuración de claves API.

FAQ

¿Para quién está pensado Frankfurter (y para quién no)?
Es ideal para facturación SaaS, comercio electrónico, informes fiscales, sistemas ERP y contables, e investigación académica con series históricas desde 1948. No está pensado para trading en tiempo real ni para operaciones con divisas exóticas con fuertes variaciones intradía.
¿Puedo usar Frankfurter con fines comerciales?
Sí, por supuesto. Para los datos subyacentes rigen las condiciones de cada fuente.
¿Hay cuotas de uso o límites de llamadas?
No hay cuotas. Se aplica un límite de frecuencia para evitar abusos, pero no existen topes diarios ni mensuales. Para volúmenes altos conviene almacenar respuestas en caché, autohospedar el servicio o consultar los conjuntos de datos directamente.
¿Admite la API GraphQL?
No. La API REST es tan sencilla que GraphQL solo añadiría complejidad sin aportar grandes ventajas. Además, deshabilitaría la caché en el edge que la hace rápida. Con parámetros de consulta como base, quotes y from/to obtienes exactamente lo que necesitas.
¿Se va a retirar la API v1?
No. La API v1 está marcada como deprecated en favor de v2, pero seguirá disponible de forma indefinida. Más detalles en la documentación de v1. Para datos del BCE, consulta /v2/providers/ecb/rates.
¿Cómo gestiona la API la privacidad?
Frankfurter no almacena datos personales, direcciones IP ni URLs consultadas. Solo registramos métricas anónimas agregadas de uso (a través de una instancia autohospedada de Plausible Analytics).
¿Debo incluir la API en las declaraciones de privacidad de la App Store o Google Play?
No. Las consultas son anónimas y no se registran. Según las directrices de Apple y Google Play, se consideran datos no recopilados.
¿Dónde puedo reportar errores o hacer preguntas?
Abre una issue para informar de errores, proponer funcionalidades o sugerir nuevas fuentes. Las dudas y las librerías o herramientas desarrolladas con Frankfurter se comparten en Discussions.
¿Qué precisión tienen los tipos de cambio?
Para cumplimiento normativo, filtra por una fuente concreta para obtener sus tipos de referencia oficiales. Para cualquier otro uso, los tipos combinados por defecto son adecuados, aunque los últimos decimales pueden ajustarse con nuevos datos.
¿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 uno de referencia, Frankfurter guarda ambos y calcula el promedio.
¿Se publican todos los tipos a diario?
Casi todos. Solo 2 fuentes publican con menor frecuencia: la autoridad fiscal británica HMRC (mensual) y el Tesoro de EE. UU. UST (trimestral). Sus tipos rigen durante semanas o meses, por lo que no se incluyen en el feed combinado. Solo los obtienes consultando esas fuentes directamente.
¿Por qué coinciden los períodos de algunas divisas antiguas y nuevas?
Algunas fuentes aplican retroactivamente las divisas sucesoras al período de la divisa sustituida (por ejemplo, TRL finaliza en 2010 mientras que TRY comienza en 1996). Mantenemos los datos de origen intactos y filtramos los solapamientos al combinar.
¿Por qué Frankfurter?
Porque el Banco Central Europeo, nuestra fuente de datos original, tiene su sede en Fráncfort.
European Central Bank and Main riverfront, Frankfurt