API de tipos de cambio por WebSocket

Suscríbete a pares compatibles y recibe actualizaciones en una conexión persistente. Guarda tu clave API en el servidor.

Crear una clave gratuitaLeer la referencia API

Inicia una conexión

Conéctate a wss://api.exchangerate.dev/v1/stream, envía auth en 10 segundos y suscríbete después de authenticated.

Ejemplo de conexión

Esta secuencia del servidor autentica una clave y se suscribe a USD/EUR y USD/JPY.

Node.js 22+ · cliente WebSocket del servidor
// Node.js 22+ · run on your server · set EXCHANGERATE_API_KEY in the environment
const key = process.env.EXCHANGERATE_API_KEY;
if (!key) throw new Error("EXCHANGERATE_API_KEY is required");

let retries = 0;
let stopped = false;
function connect() {
  const ws = new WebSocket("wss://api.exchangerate.dev/v1/stream");
  ws.addEventListener("open", () => {
    ws.send(JSON.stringify({ action: "auth", api_key: key }));
  });
  ws.addEventListener("message", ({ data }) => {
    const frame = JSON.parse(String(data));
    if (frame.type === "authenticated") {
      retries = 0;
      ws.send(JSON.stringify({ action: "subscribe", base: "USD", symbols: ["EUR", "JPY"] }));
    } else if (frame.type === "snapshot" || frame.type === "update") {
      if (frame.stale) return; // Keep the observation time; don't treat it as a fresh tick.
      console.log(frame.base, frame.symbol, frame.rate, frame.effective_at);
    } else if (frame.type === "state") {
      console.log(frame.base, frame.symbol, frame.state); // stale or unavailable
    } else if (frame.type === "error") {
      console.error(frame.code, frame.message);
      if (["invalid_api_key", "quota_exceeded", "connection_limit_exceeded", "subscription_limit_exceeded"].includes(frame.code)) {
        stopped = true;
        ws.close();
      }
    }
  });
  ws.addEventListener("close", () => {
    if (stopped) return;
    const delay = Math.min(30_000, 1_000 * 2 ** Math.min(retries++, 5));
    setTimeout(connect, delay + Math.random() * 250);
  });
}
connect();

Las conexiones WebSocket requieren autenticación.

Lee cada mensaje

Cada mensaje incluye el par, el tipo, la hora de observación y el estado de frescura. Trata unavailable y stale como estados explícitos.

JSON · mensaje de ejemplo; los valores y la hora son ilustrativos
{
  "type": "update",
  "base": "USD",
  "symbol": "JPY",
  "rate": "154.792",
  "effective_at": "2026-09-15T02:59:44Z",
  "source": "live",
  "source_type": "market",
  "market_session": "open",
  "derived": false,
  "stale": false
}

Cobertura

Solo puedes suscribirte a los pares de la tabla de cobertura actual. Los cruces requieren observaciones recientes de ambas patas.

AUD, CAD, CHF, EUR, GBP, JPY, MXN, NOK, NZD, PLN, SEK, SGD, USD, ZAR · 182 Pares compatibles

Las actualizaciones son observaciones indicativas. Comprueba el estado y la hora de observación.

Ver la cobertura actual

Límites del plan

El número de conexiones y de pares por conexión depende del plan. Cada conexión aceptada consume una unidad de cuota mensual.

PlanConexionesPares por conexiónUso comercial
Free15No
Basic325
Pro10100

Cada conexión aceptada consume una unidad de cuota mensual.

Ver precios

Uso comercial

Consulta el plan y las condiciones de uso comercial actuales antes de distribuir un producto que dependa del flujo.

Reconecta de forma segura

Tras una desconexión, espera antes de reconectar, autentica de nuevo, espera authenticated y vuelve a suscribirte. Nunca pongas la clave en una URL ni en JavaScript público.

Las actualizaciones que faltan siguen faltando; el flujo no inventa valores.

¿Puedo conectarme sin autenticación?

No. Las conexiones WebSocket requieren una clave API. La evaluación anónima está disponible mediante los endpoints REST compatibles.

¿Se transmite cada par de divisas?

No. La cobertura de WebSocket depende del par. Consulta la tabla y gestiona explícitamente las suscripciones no compatibles.