Aprender/Inicio rápido con JavaScript

Conversión de divisas en JavaScript y Node.js

Obtén tipos de cambio en vivo y convierte importes en JavaScript con la API global fetch. Funciona en Node 18+, Deno, Bun y navegadores modernos. Sin clave para empezar, 10,000 llamadas al mes en el plan gratuito.

ERexchangerate.dev·Jun 19, 2026·5 min de lectura

El camino más rápido a los tipos de cambio en JavaScript es un GET a /v1/latest/USD con fetch. La respuesta es JSON plano con tipos para 31 monedas y dos campos de frescura, source y market_session. Tu primera llamada no necesita clave de API.

Puntos clave
El fetch global funciona de serie en Node 18+, Deno, Bun y navegadores, sin dependencias extra.
Un GET a /v1/latest/{base} devuelve tipos para 31 monedas, más source y market_session.
Pasa la clave como Authorization: Bearer exr_live_..., o usa X-API-Key si tu plataforma no puede fijar Authorization.
El plan gratuito son 10,000 llamadas al mes a 12 peticiones por minuto, sin tarjeta.
Los tipos son indicativos, solo para referencia y análisis, no una cotización en firme.

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:

javascript · no keycopy
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);

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:

javascript · authenticated call with error handlingcopy
// 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);

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:

javascript · convert 100 USD to EURcopy
// 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);

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: liveConsenso spot agregadoIntradí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: fred_dailySerie diaria de la Reserva FederalUna vez por día hábil
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.

  • 10,000 llamadas al mes
  • 12 peticiones por minuto
  • Sin tarjeta de crédito
  • Cubre /v1/latest, /v1/convert, /v1/range y /v1/{date}/{base}
ER
exchangerate.dev
Guías de integración para desarrolladores.

Sigue leyendo

TutorialCómo obtener tipos de cambio en PythonLeer
Más ComparacionesFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.dev
AprenderCómo obtener tipos de cambio en PythonTipos de cambio en Next.js y TypeScriptCrear una alerta de tipo de cambio en Python con USD/IDR
Tasas en VivoEUR/USDGBP/USDUSD/JPY