Uwierzytelnianie i limity
Endpointy danych można testować anonimowo: 10 żądań na minutę i 100 na godzinę dla jednego IP. Klucz uruchamia miesięczny limit konta. Ceny Free są opóźnione o 15 minut (nagłówek X-Price-Delay-Seconds: 900).
Authorization: Bearer YOUR_KEYX-RateLimit-Remaining: 9999X-RateLimit-Reset: 1788220800Pola opisujące świeżość
source określa klasę źródła, market_session stan rynku, a data_updated_at czas najstarszej obserwacji uwzględnionej w odpowiedzi. Zachowaj wszystkie trzy.
Endpointy
| GET /v1/latest[/{BASE}] | Bieżące kursy, wszystkie lub filtrowane przez symbols. |
| GET /v1/{YYYY-MM-DD}[/{BASE}] | Migawka historyczna dla daty i waluty bazowej. |
| GET /v1/convert/{FROM}/{TO}[/{AMOUNT}] · POST /v1/convert | Przeliczenie kwoty; pojedynczy GET lub grupowy POST. |
| GET /v1/rate/{slug} | Płaska odpowiedź dla pary podanej jako slug. |
| GET /v1/range | Seria dzienna z paginacją i pobieraniem plików. |
| GET /v1/currencies | Lista obsługiwanych walut, bez parametrów. |
| GET /v1/account | Konto, plan, aktywny klucz i użycie w miesiącu. |
| GET /v1/indices/{index_slug} · GET /v1/indices/{index_slug}/timeseries | Najnowsze wartości indeksów USD i ich szeregi historyczne. |
Serie intraday i zakres
/v1/timeseries obsługuje 1m, 5m, 15m, 1h, 4h oraz dzienne dane referencyjne 1d. Nie ma interwału 2h. Krzyżowe pary SGD bez USD nie obsługują 4h; USD/SGD i odwrotny kierunek są dostępne. Zbieranie danych rynkowych rozpoczęło się 2026-09-14. Dane 1m są przechowywane przez 30 dni, a większe interwały nie mają zaplanowanego terminu usunięcia. Retencja nie oznacza już zgromadzonej długości historii. Intraday od 1m do 1h obejmuje 221 unikalnych par: 143 pary z USD i 78 par krzyżowych.
Historyczne pary krzyżowe wymagają rzeczywistych obserwacji zamknięcia w tym samym przedziale UTC, oddalonych o najwyżej 5 sekund. effective_at wskazuje starszą obserwację. Luki nie są wypełniane; otwarty przedział może się zmieniać. 1d korzysta z dziennych danych referencyjnych całego katalogu. Tabela liczy unikalne pary; oba kierunki są obsługiwane.
| interval | Unikalne pary |
|---|---|
1m | 221 |
5m | 221 |
15m | 221 |
1h | 221 |
4h | 209 |
1d | 10296 |
curl "https://api.exchangerate.dev/v1/timeseries?base=EUR&symbols=JPY&interval=15m&from=2026-09-14T12:00:00Z&to=2026-09-14T13:00:00Z" \ -H "Authorization: Bearer YOUR_API_KEY"Obsługiwane okno bez obserwacji zwraca HTTP 200 z data: [], has_more: false i next_cursor: null. Nieznany interwał zwraca unsupported_interval; para poza zakresem zwraca unsupported_pair_interval i rejected_pairs (HTTP 400). Żądania mieszane są odrzucane w całości.
WebSocket na żywo
Połącz się z wss://api.exchangerate.dev/v1/stream i wyślij auth w ciągu 10 sekund. Przechowuj klucz na serwerze, nigdy w URL ani publicznym JavaScript. Połączenia anonimowe nie są obsługiwane. Po authenticated wyślij subscribe. Obsługiwane waluty podano poniżej; pary krzyżowe wymagają dwóch świeżych obserwacji oddalonych o najwyżej 5 sekund. Możliwe stany to unavailable i stale. Każde przyjęte połączenie zużywa jedną jednostkę miesięcznego limitu.
Tabela: limity nowych kont. Obecne konta zachowują starsze plany Basic 3 × 25 lub Pro 10 × 100 (połączenia × pary na połączenie). Komunikat authenticated podaje obowiązujące limity konta.
AUD, CAD, CHF, EUR, GBP, JPY, MXN, NOK, NZD, PLN, SEK, SGD, USD, ZAR
| Plan | Jednoczesne połączenia | Pary na połączenie |
|---|---|---|
| Free | 0 | 0 |
| Basic | 0 | 0 |
| Plus | 1 | 10 |
| Pro | 3 | 100 |
{"action":"auth","api_key":"YOUR_KEY"}{"action":"subscribe","base":"EUR","symbols":["USD","JPY"]}Błędy
REST: Każdy błąd ma postać { result: "error", code, message }. Odpowiedź 429 zawiera Retry-After; awaria źródła nigdy nie uruchamia danych testowych. HTTP 403 plan_gated zawiera tier, interval; przekroczenie okna historii dodaje history_days, earliest_allowed. Jeśli zmiana planu pozwala wykonać żądanie, odpowiedź zawiera upgrade_plans, upgrade_offers (plan, loses) وupgrade_url.
{ "result": "error", "code": "missing_parameter", "message": "required parameter missing: symbols"}{ "result": "error", "code": "plan_gated", "message": "The 15m interval is not included in your plan.", "tier": "plus_2026", "interval": "15m", "upgrade_plans": ["pro_2026"], "upgrade_offers": [{ "plan": "pro_2026", "loses": [] }], "upgrade_url": "https://exchangerate.dev/pricing?plan=pro_2026&source=api&reason=plan_gated"}curl -fsS --max-time 10 "https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP"from urllib.request import Request, urlopenimport json# Identify your application explicitly when calling the API.request = Request("https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP", headers={"User-Agent": "exchangerate-docs/1.0"})with urlopen(request, timeout=10) as response: data = json.load(response)print(data["rates"]["EUR"])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}`);const data = await response.json();console.log(data.rates.EUR);Przewodniki integracji: Python · JavaScript / Node.js · Google Sheets · Excel · Go · Swift · Zapier