Refresh tokeny Amazon Ads: wygasanie po 365 dniach od 30 lipca, bez przypomnienia

Spis treści
Jedenaście dni temu Amazon zmienił okres ważności refresh tokena dla Advertising API. Jeżeli integracja autoryzowała reklamodawcę 1 sierpnia, ten token przestanie działać 01.08.2027 — niezależnie od tego, jak często będzie w międzyczasie używany. Nie ma e-maila, nie ma nagłówka deprecation, nie ma ostrzeżenia w konsoli. Jedyną stroną, która to zauważy, jest zespół utrzymujący integrację — w momencie gdy nocny eksport nie zwróci żadnych danych. Ten artykuł prostuje szeroko powielaną błędną datę, a następnie buduje jedyną rzecz, która naprawdę chroni: rejestr tokenów wraz z zadaniem cron.
1. Co się zmieniło i data, którą wszyscy podają błędnie
Amazon ogłosił zmianę 26.05.2026. Weszła ona w życie 30.07.2026. Refresh tokeny wydane tego dnia lub później wygasają 365 dni po dacie udzielenia zgody przez reklamodawcę, a nie 365 dni po wygenerowaniu tokena ani 365 dni po jego ostatnim użyciu.
Uporczywie krąży błędna data: 30 czerwca. Pojawia się w postach na forach, w changelogach dostawców i w podsumowaniach wyszukiwarek, które z pełnym przekonaniem odpowiadają „30 czerwca”, gdy zapytać, kiedy refresh tokeny Amazona zaczęły wygasać. To pomyłka o cały miesiąc. Jeżeli okno migracji zostało zaplanowane na koniec czerwca albo klient usłyszał, że jego tokeny są już objęte zmianą, warto zweryfikować te założenia. Prawidłowa data graniczna to 30.07.2026, a pierwsze masowe wygaśnięcia nastąpią w związku z tym od 30.07.2027.
- Ogłoszenie: 26.05.2026.
- Wejście w życie: 30.07.2026, a nie 30 czerwca.
- Czas życia: 365 dni od daty zgody reklamodawcy.
- Odzyskanie po wygaśnięciu: nowa zgoda reklamodawcy, udzielona w interaktywnym oknie dialogowym. Nie ma cichej drogi powrotnej.
- Powiadomienie od Amazona: brak.
2. Dlaczego używanie tokena nic nie daje
To właśnie ten szczegół zaskakuje doświadczone zespoły. W niemal każdym innym wdrożeniu OAuth refresh token albo nie wygasa wcale, albo ma ważność przesuwaną: każda wymiana na nowy access token zeruje licznik bezczynności, więc integracja uruchamiana co godzinę praktycznie nigdy nie traci ważności. Zegar Amazona się nie przesuwa. Jest zakotwiczony w dacie zgody i odlicza do zera niezależnie od ruchu. Pipeline, który przez rok co 55 minut poprawnie odświeżał token, zawiedzie 366. dnia dokładnie tak samo jak taki, który od pierwszego dnia stał bezczynnie.
Awaria jest więc cicha i odroczona. Monitoring pokazuje zdrową integrację aż do samej granicy, a potem pojawia się wywołanie refresh, które nie zwraca już access tokena — i nie naprawi tego ani ponowna próba, ani redeploy. Ktoś po stronie reklamodawcy musi jeszcze raz przeklikać okno zgody. W sobotę, dla klienta w innej strefie czasowej, nie jest to pięciominutowa naprawa.
Warto wspomnieć o tym od razu, bo dotyczy tych samych baz kodu: sześć starych endpointów account management jest od lipca 2026 zamkniętych dla nowych zastosowań i od lipca 2027 będzie zwracać HTTP 404. Ich następcy są ogólnie dostępni od 04.06.2026. Tę migrację warto zaplanować w tym samym kwartale co odnowienia zgód.
3. Rejestr tokenów po własnej stronie
Amazon nie poinformuje, kiedy token przestanie działać, dlatego należy zapisać jedyny fakt, który ma znaczenie, czyli datę zgody, i wyprowadzić z niej całą resztę. Wystarczy jedna tabela na środowisko. Kolumna z datą wygaśnięcia jest generowana, więc nigdy nie rozjedzie się z datą zgody.
CREATE TABLE amazon_ads_token_ledger (
advertiser_id text PRIMARY KEY,
account_name text NOT NULL,
region text NOT NULL CHECK (region IN ('na', 'eu', 'fe')),
consent_date date NOT NULL,
token_issued_at timestamptz NOT NULL,
expires_on date GENERATED ALWAYS AS (consent_date + 365) STORED,
last_refresh_ok timestamptz,
owner_email text NOT NULL,
status text NOT NULL DEFAULT 'active'
);
CREATE INDEX ON amazon_ads_token_ledger (expires_on) WHERE status = 'active';
Tabelę wystarczy wypełnić jednorazowo, w razie potrzeby ręcznie. Dla każdego reklamodawcy podłączonego 30.07.2026 lub później należy wpisać datę zgody widniejącą w dokumentacji onboardingu. Dla starszych tokenów warto mimo wszystko zapisać datę i ustawić status = 'legacy': w chwili gdy taki reklamodawca z dowolnego powodu udzieli zgody ponownie, nowa reguła obejmie token zastępczy, a wiersz będzie już przygotowany.
4. Skrypt kontrolny i wpis w crontab
Skrypt nic nie wypisuje, gdy wszystko jest w porządku, dzięki czemu cron milczy. Na 60 dni przed terminem zaczyna wysyłać wiadomości, a gdy coś faktycznie wygasło, kończy działanie kodem różnym od zera, więc wrapper lub monitoring może na tej podstawie uruchomić alert.
#!/usr/bin/env python3
"""Ostrzega o zgodach Amazon Ads zbliżających się do limitu 365 dni."""
import sys
from datetime import date
import psycopg
DSN = "postgresql:///ops"
WARN_DAYS = 60
QUERY = """
SELECT advertiser_id, account_name, region, consent_date, expires_on,
expires_on - CURRENT_DATE AS days_left, owner_email
FROM amazon_ads_token_ledger
WHERE status = 'active'
AND expires_on - CURRENT_DATE <= %s
ORDER BY days_left
"""
def main() -> int:
with psycopg.connect(DSN) as conn:
rows = conn.execute(QUERY, (WARN_DAYS,)).fetchall()
if not rows:
return 0
print(f"Amazon Ads re-consent needed, checked {date.today()}:")
for aid, name, region, consent, expires, days, owner in rows:
state = "EXPIRED" if days < 0 else f"{days} days left"
print(f" {aid} {name} [{region}] consent={consent} "
f"expires={expires} {state} owner={owner}")
return 1 if any(r[5] < 0 for r in rows) else 0
if __name__ == "__main__":
sys.exit(main())
# crontab -e (uruchamiane jako użytkownik usługi będący właścicielem roli bazy ops)
MAILTO=ads-ops@example.com
17 6 * * * /usr/bin/python3 /opt/ads/token_ledger_check.py
Sześćdziesiąt dni nie jest liczbą przypadkową. Ponowne udzielenie zgody to proces po stronie ludzi: trzeba dotrzeć do właściwej osoby u reklamodawcy, ta musi znaleźć kogoś z uprawnieniami do zatwierdzenia, a taki łańcuch rutynowo zajmuje od czterech do sześciu tygodni. last_refresh_ok warto aktualizować również z poziomu zadania odświeżającego, aby niezwiązana z tym awaria ujawniła się w tej samej tabeli.
5. Podsumowanie
Powstał rejestr, który zapisuje datę zgody każdego reklamodawcy i wylicza datę wygaśnięcia jako zgodę plus 365 dni w bazie danych, a nie w kodzie aplikacji, oraz zadanie cron, które zaczyna wysyłać powiadomienia dwa miesiące przed tym, zanim cokolwiek przestanie działać. Łączny koszt: jedna tabela, jeden indeks, czterdzieści linii Pythona, jeden wpis w crontab. Zastępuje to klasę awarii, która nie ma żadnego budżetu błędu, ponieważ ścieżką naprawy jest rozmowa telefoniczna, a nie wdrożenie.
Dwie rzeczy warte zapamiętania. Data graniczna to 30.07.2026, a nie 30 czerwca, cokolwiek twierdzi podsumowanie wyszukiwarki, więc tokeny wydane od tego dnia zaczną wygasać 30.07.2027. Oraz: używanie nie przedłuża czasu życia, i właśnie dlatego integracja, która dziś wygląda na całkowicie zdrową, może być jedenaście miesięcy od twardego zatrzymania. Amazon opisuje to zachowanie w sekcji access tokens w przewodnikach Amazon Advertising API; tę stronę należy traktować jako źródło prawdy, a własny rejestr jako budzik, którego Amazon nie zapewnia.
Komentarze: 2
Wyjaśnienie, dlaczego korzystanie z tokenu niczego nie przedłuża, jest tu kluczowe — w każdym innym wdrożeniu OAuth zegar przesuwa się przy każdym odświeżeniu i to przyzwyczajenie działa tu przeciwko nam.
Pytanie o stronę organizacyjną: skrypt ostrzega na sześćdziesiąt dni przed terminem. Co właściwie powinno się w tym czasie wydarzyć, skoro odnowienie wymaga działania po stronie reklamodawcy?
Dokładnie dlatego próg jest tak wysoki: sześćdziesiąt dni to nie zapas na pracę techniczną, tylko czas potrzebny na dotarcie do właściwej osoby.
Kolejność, która się sprawdza: najpierw ustalenie, kto po stronie reklamodawcy ma uprawnienia do wyrażenia zgody — to często ktoś inny niż osoba kontaktowa w codziennej współpracy. Potem jedna wiadomość z konkretną datą i konsekwencją („po tym dniu raporty przestaną się aktualizować”), a nie prośbą o „ponowną autoryzację”, która brzmi jak czynność techniczna do odłożenia. Na koniec okno w kalendarzu, bo dialog zgody wymaga kilkunastu minut czyjejś uwagi.
Przy większej liczbie kont warto to grupować. Trzydzieści odnowień rozłożonych po jednym dziennie zajmuje półtora miesiąca uwagi; te same trzydzieści zebrane w jeden tydzień to zadanie z początkiem i końcem. Kolumna z właścicielem w tabeli służy właśnie do takiego pogrupowania — i to ona zamienia listę terminów w plan.