Tutorial/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.

Key points
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 GuideTipos históricos y series temporales en una llamadaLeer ReferenceCómo leer source y market_sessionLeer
Más ComparacionesFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.dev
AprenderReading source and market_session in your pipelineIndicative vs executable FX rates: what a rates API actually gives youECB reference rates, explained
Tasas en VivoEUR/USDGBP/USDUSD/JPY