API kursów walut przez WebSocket

Subskrybuj obsługiwane pary i odbieraj aktualizacje przez stałe połączenie. Klucz API przechowuj na serwerze.

Utwórz darmowy kluczPrzeczytaj referencję API

Rozpocznij połączenie

Połącz się z wss://api.exchangerate.dev/v1/stream, wyślij auth w ciągu 10 sekund, a po authenticated wyślij subscribe.

Przykład połączenia

Ta sekwencja po stronie serwera uwierzytelnia klucz i subskrybuje USD/EUR oraz USD/JPY.

Node.js 22+ · klient WebSocket po stronie serwera
// 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();

Połączenia WebSocket wymagają uwierzytelnienia.

Odczytuj każdą wiadomość

Wiadomość zawiera parę, kurs, czas obserwacji i stan świeżości. unavailable i stale traktuj jako jawne stany.

JSON · przykładowa wiadomość; wartości i czas służą tylko jako przykład
{
  "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
}

Zakres

Możesz subskrybować tylko pary z aktualnej tabeli zakresu. Pary krzyżowe wymagają świeżych obserwacji obu nóg.

AUD, CAD, CHF, EUR, GBP, JPY, MXN, NOK, NZD, PLN, SEK, SGD, USD, ZAR · 182 Obsługiwane pary

Aktualizacje to obserwacje orientacyjne. Sprawdzaj stan i czas obserwacji w każdej wiadomości.

Sprawdź aktualny zakres

Limity planu

Liczba połączeń i par na połączenie zależy od planu. Każde zaakceptowane połączenie zużywa jedną jednostkę miesięcznego limitu.

PlanPołączeniaPary na połączenieUżycie komercyjne
Free15Nie
Basic325Tak
Pro10100Tak

Każde zaakceptowane połączenie zużywa jedną jednostkę miesięcznego limitu.

Zobacz ceny

Użycie komercyjne

Przed dystrybucją produktu zależnego od strumienia sprawdź aktualny plan i warunki użycia komercyjnego.

Bezpieczne ponowne połączenie

Po rozłączeniu odczekaj przed ponownym połączeniem, uwierzytelnij się, poczekaj na authenticated i ponownie zasubskrybuj. Nie umieszczaj klucza w URL ani publicznym JavaScript.

Brakujące aktualizacje pozostają brakujące; strumień nie tworzy wartości.

Czy mogę połączyć się anonimowo?

Nie. Połączenia WebSocket wymagają klucza API. Anonimowe testy są dostępne przez obsługiwane endpointy REST.

Czy każda para walut jest przesyłana?

Nie. Zakres WebSocket zależy od pary. Sprawdź tabelę i jawnie obsłuż nieobsługiwane subskrypcje.