API kursów walut przez WebSocket
Subskrybuj obsługiwane pary i odbieraj aktualizacje przez stałe połączenie. Klucz API przechowuj na serwerze.
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+ · 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.
{
"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 zakresLimity 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.
| Plan | Połączenia | Pary na połączenie | Użycie komercyjne |
|---|---|---|---|
| Free | 1 | 5 | Nie |
| Basic | 3 | 25 | Tak |
| Pro | 10 | 100 | Tak |
Każde zaakceptowane połączenie zużywa jedną jednostkę miesięcznego limitu.
Zobacz cenyUż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.