GET /changes
GET /changes # ostatnie zmiany we wszystkich krajachGET /changes/YYYY-MM-DD # wszystkie zmiany wykryte w dniu danego snapshotu/changes to log diff-ów stojący za endpointem /rates.
Codzienny cron TEDB porównuje każdy nowy snapshot z poprzednim i
zapisuje jeden wiersz na każde numeryczne pole, które się zmieniło.
Użyj tego zamiast pollować /rates i samodzielnie liczyć diff JSON-a
— jest tańszy, posortowany i już ograniczony do faktycznych ruchów.
Kiedy używać
Dział zatytułowany „Kiedy używać”- Widok „ostatnie zmiany” w dashboardzie — wyrenderuj ostatnie N zmian stawek we wszystkich krajach.
- Alerty — reaguj na ruch stawki standardowej w danym kraju.
- Audyt — odpytaj „co się zmieniło w maju 2026?” jednym GET-em z dolną granicą daty ISO.
Jeśli potrzebujesz strumienia zamiast pollingu, podepnij webhook na
zdarzenie rates.changed — strzela raz na cykl crona,
gdy diff jest niepusty, z tą samą tablicą changes w payloadzie
zdarzenia.
Odpowiedź
Dział zatytułowany „Odpowiedź”{ "changes": [ { "id": "rc_a1b2c3d4e5f6", "snapshotDate": "2026-05-30", "country": "HU", "field": "standard", "old": 27, "new": 25, "detectedAt": "2026-05-30T07:00:23.000Z" } ], "count": 1, "limit": 50}Znaczenie pól
Dział zatytułowany „Znaczenie pól”id— stabilny identyfikator wiersza zmiany. Ten sam id przy ponownych dostarczeniach webhooka; bezpieczny do deduplikacji po stronie odbiorcy.snapshotDate— ISO data snapshotu TEDB, w którym wykryto zmianę. Dla potrzeb Stawki to praktycznie „kiedy ruch wszedł w życie”.country— ISO 3166-1 alpha-2.field— która stawka się zmieniła. Jedna z:standardsuper_reducedparkingreduced[N]dla N-tego slotu tablicy stawek obniżonych (indeksowane od 0).
old— poprzednia wartość liczbowa lubnull, jeśli stawka wcześniej nie istniała.nulloznacza „wczoraj nie było takiej stawki” (np. kraj zaczął publikować stawkę super-obniżoną).new— bieżąca wartość liczbowa lubnull, jeśli stawka została usunięta.detectedAt— znacznik czasu ISO 8601, kiedy cron zapisał wiersz. Różny odsnapshotDate: data snapshotu to to, co zadeklarował TEDB;detectedAtto kiedy my to zauważyliśmy.
Wszystkie wartości liczbowe to punkty procentowe — nigdy punkty
bazowe, nigdy ułamki. 25 oznacza 25%.
Parametry zapytania (tylko /changes)
Dział zatytułowany „Parametry zapytania (tylko /changes)”| Param | Typ | Domyślnie | Uwagi |
|---|---|---|---|
since | YYYY-MM-DD | brak | Dolna granica daty snapshotu. Zwracane są tylko zmiany z snapshotDate >= since. |
country | ISO 2-literowe | brak | Wielkość liter nieistotna na wejściu. Filtruje do jednego kraju. |
limit | int 1–200 | 50 | Ogranicza liczbę wierszy. Wartości powyżej 200 są po cichu klampowane; wartości ≤ 0 lub nienumeryczne zwracają 400. |
Nieznane parametry zapytania są ignorowane — przydatne do cache-bustingu w testach, nieszkodliwe na produkcji.
Sortowanie
Dział zatytułowany „Sortowanie”/changeszwraca wiersze od najnowszych:detected_at DESC, potemcountry ASC, field ASCjako tiebreaker, gdy wiele zmian wpada w ten sam cykl crona./changes/YYYY-MM-DDzwraca wiersze posortowane wgcountry, field— czas wykrycia jest taki sam dla każdego wiersza w danym dniu snapshotu, więc kolejność alfabetyczna jest praktyczniejsza.
Zachowanie cache’u
Dział zatytułowany „Zachowanie cache’u”/changes—Cache-Control: public, max-age=300, stale-while-revalidate=86400. Codzienny cron to jedyny pisarz; 300s na brzegu w zupełności wystarczy widokowi dashboardu./changes/YYYY-MM-DD—Cache-Control: public, max-age=31536000, immutable. Diff per snapshot jest stały po uruchomieniu crona; cache’uj go na zawsze.
| Status | Body | Przyczyna |
|---|---|---|
| 200 | {"changes": [], "count": 0, ...} | To nie błąd. Dzień bez ruchów stawek — stan ustalony. Nie traktuj jako 404. |
| 400 | {"error": "invalid 'since' — expected YYYY-MM-DD"} | Zły format parametru since. |
| 400 | {"error": "invalid 'country' — expected 2-letter ISO code"} | country nie ma dokładnie dwóch liter. |
| 400 | {"error": "invalid 'limit' — expected positive integer"} | limit nie jest dodatnią liczbą całkowitą. |
| 401 | {"error": "INVALID_KEY"} | Brakujący lub nieprawidłowy token bearer. |
| 429 | {"error": "RATE_LIMITED"} lub {"error": "QUOTA_EXCEEDED"} | Zobacz limity i kwoty. |
Przepisy
Dział zatytułowany „Przepisy”„Co się zmieniło w tym miesiącu?”
Dział zatytułowany „„Co się zmieniło w tym miesiącu?””GET /changes?since=2026-05-01&limit=200Cap 200 wierszy to twardy maksimum. Stawki VAT w UE zmieniają się na tyle rzadko, że miesięczny zbiór zmian praktycznie nigdy go nie przekracza.
„Kiedy Węgry ostatnio zmieniły standardowy VAT?”
Dział zatytułowany „„Kiedy Węgry ostatnio zmieniły standardowy VAT?””GET /changes?country=HU&limit=10Zwraca ostatnie węgierskie ruchy stawek; snapshotDate pierwszego
wiersza to odpowiedź.
„Wszystkie zmiany w konkretnym dniu”
Dział zatytułowany „„Wszystkie zmiany w konkretnym dniu””GET /changes/2026-05-30Zwraca każde pole, które się ruszyło tego dnia, posortowane po kraju. Przydatne do changelogów i post-mortemów.
Uwaga o backfillu
Dział zatytułowany „Uwaga o backfillu”Tabela rate_change jest zasilana z codziennego crona od momentu
wdrożenia funkcji (zobacz changelog). Historyczne
snapshoty w KV sprzed tej daty istnieją — możesz je dalej pobierać
przez /rates/YYYY-MM-DD — ale strumień diff-ów zawiera
tylko ruchy, które cron miał szansę zaobserwować.