GuíasTutoriales

Conversión de divisas en JavaScript y Node.js

Obtén un tipo con fetch, conviértelo con una respuesta JSON y usa currency.js para las operaciones y el formato de importes.

1 oct 2026 · 6 min de lectura

En el navegador puedes empezar con una llamada anónima. En Node.js o en el servidor, guarda la clave en una variable de entorno y conserva la información de frescura que acompaña al tipo.

  • fetch funciona en Node 18+, Deno, Bun y navegadores modernos.
  • No pongas una clave de cuenta en JavaScript que se envía al navegador.
  • Usa currency.js para aritmética y formato, no para obtener la cotización.
  • Comprueba la respuesta HTTP y respeta Retry-After cuando recibas 429.
  • Muestra source y effective_at cuando el usuario necesite saber la antigüedad.

Tu primera llamada, sin clave

En Node 18 o en cualquier navegador moderno ya tienes fetch. Un solo await basta para leer el tipo del EUR:

Las llamadas anónimas tienen tope por dirección IP, así que pásate a una clave gratuita en cuanto dejes atrás la prueba rápida.

Añade una clave y manejo de errores

Pasa la clave como token bearer en la cabecera Authorization. Comprueba res.ok y lanza en un estado malo para que los errores salgan a la superficie pronto:

La cabecera X-API-Key: exr_live_... también se acepta, para plataformas que no pueden fijar una cabecera Authorization (algunos entornos serverless, Zapier y herramientas no-code parecidas).

Convierte un importe

Para una conversión directa llama a /v1/convert/{from}/{to}/{amount}. La respuesta te da el tipo y el importe convertido en un solo viaje:

El endpoint de conversión devuelve los mismos campos source y market_session que el endpoint latest, así que puedes mostrar a los usuarios la clase de tipo y si la semana interbancaria está abierta.

Entiende source y market_session

Para la moneda que muestras, consulta sources[currency] y effective_at[currency]: indican el tipo de fuente y la hora de observación. source resume los datos menos recientes de toda la respuesta. market_session describe la sesión de mercado; timestamp es la hora de generación de la respuesta, no la hora de observación.

Valor del campoQué significaCuándo se mueve
source: liveTipo spot indicativoIntradía (~60 s), semana de negociación
source: ecb_dailyFix de referencia del Banco Central EuropeoUna vez por día hábil (~16:00 CET)
source: market_dailyCierre guardado sin BCEFeed diario
market_session: weekendSábado o domingo (interbancario cerrado)Los fixes de referencia arrastran el valor del viernes; el feed en vivo no se actualiza

El campo data_updated_at te dice cuándo se escribió por última vez el tipo subyacente. timestamp registra cuándo se construyó la respuesta. Juntos te permiten decidir cómo cachear y mostrar el valor.

Solo tipos indicativos

Estos tipos se publican para referencia, análisis y visualización. No son una cotización en firme y no deben usarse para liquidar una operación ni una transferencia. Cada respuesta lo declara en su campo notice.

Límites del plan gratuito

La cuota mensual se reinicia el día 1 de cada mes a las 00:00 UTC. Ante un 429, respeta Retry-After antes de reintentar.

  • 5,000 llamadas al mes
  • 10 peticiones por minuto
  • Sin tarjeta de crédito
  • Cubre /v1/latest, /v1/convert, /v1/range y /v1/{date}/{base}

Calcula y formatea el importe

currency.js ayuda con el importe, los decimales y el formato. No sustituye a una API de FX: primero obtén el tipo y después multiplica el importe.

javascript · no key
const response = await fetch("https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP", {  signal: AbortSignal.timeout(10_000),});if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);const data = await response.json();console.log(data.rates.EUR);console.log(data.sources.EUR, data.effective_at.EUR);console.log(data.market_session);
javascript · authenticated call with error handling
// Node.js server only. Never put an account key in browser code.const KEY = process.env.EXCHANGERATE_API_KEY;if (!KEY) throw new Error("Set EXCHANGERATE_API_KEY on your server");async function getLatest(base = "USD") {  const response = await fetch(`https://api.exchangerate.dev/v1/latest/${encodeURIComponent(base)}`, {    headers: { Authorization: `Bearer ${KEY}` },    redirect: "error",    signal: AbortSignal.timeout(10_000),  });  if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);  return response.json();}const data = await getLatest("USD");console.log(data.rates.GBP, data.effective_at.GBP);
javascript · convert 100 USD to EUR
// Node.js server only.const KEY = process.env.EXCHANGERATE_API_KEY;if (!KEY) throw new Error("Set EXCHANGERATE_API_KEY on your server");const response = await fetch("https://api.exchangerate.dev/v1/convert/USD/EUR/100", {  headers: { Authorization: `Bearer ${KEY}` },  redirect: "error",  signal: AbortSignal.timeout(10_000),});if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);const data = await response.json();console.log(data.rate, data.converted);
JavaScript · currency.js
import currency from "currency.js";const response = await fetch("https://api.exchangerate.dev/v1/latest/USD?symbols=EUR", {  signal: AbortSignal.timeout(10_000),});if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();const rate = data.rates.EUR;if (!Number.isFinite(rate) || rate <= 0) throw new Error("Invalid rate");const euros = currency("100.00", { precision: 2, symbol: "€" }).multiply(rate);console.log(euros.format());

Preguntas

¿Necesito un bundler o paquetes extra para usar esta API en JavaScript?

No. La función global fetch viene incluida en Node 18+, Deno, Bun y todos los navegadores modernos. Puedes hacer tu primera llamada con un solo await fetch(...) y res.json(). No hace falta ninguna librería HTTP de terceros.

¿Cómo paso mi clave de API en una petición fetch?

Envíala en la cabecera Authorization como token bearer: { "Authorization": "Bearer exr_live_..." }. La cabecera X-API-Key también se acepta como alias, útil en plataformas que no pueden fijar una cabecera Authorization personalizada.

¿Cuál es la diferencia entre /v1/latest y /v1/convert?

El endpoint latest devuelve tipos para las 144 monedas soportadas contra la base que elijas. El endpoint convert recibe una moneda de origen, una de destino y un importe opcional, y devuelve el tipo más el valor convertido en una llamada. Usa convert cuando solo necesitas un par y quieres el resultado ya calculado.

¿Puedo usar estos tipos para procesar un pago o liquidar una transacción?

No. Los tipos son indicativos, publicados solo para referencia, visualización y análisis. No son cotizaciones en firme. Cada respuesta incluye un campo notice que lo declara. Para liquidaciones financieras, consulta a tu proveedor de pagos el tipo que aplica.

Sigue leyendo

Empieza con una clave API gratuita

5.000 solicitudes al mes con el plan gratuito. Sin tarjeta de crédito.

Obtén una clave gratuita