Microsoft Advertising Conversions API: integracja server-side UET
Spis treści
- Podsumowanie dla kierownictwa
- 1. Kontekst: konwersje server-side w Microsoft Advertising
- 2. Kontrakt techniczny: endpoint, uwierzytelnianie, pola wymagane
- 3. Klucz uwierzytelniający: przewodnik a dokumentacja operacji
- 4. Deduplikacja: jak tag UET i zdarzenie serwerowe odnajdują się nawzajem
- 5. Normalizacja, hashowanie i zgody
- 6. Klient na produkcji: paczki, siedmiodniowe okno, wznawianie
- 7. Monitoring: metryki, które pokazują stan potoku
- Wnioski
Microsoft Advertising przyjmuje obecnie konwersje bezpośrednio z serwerów za pośrednictwem Conversions API, a na początku sierpnia 2026 roku przewodnik po integracji został napisany na nowo, od pierwszej do ostatniej linijki. Ten artykuł jest adresowany do osób, które zbudują tę integrację i będą ją utrzymywać: do właściciela obszaru pomiaru, który ocenia zasadność wdrożenia, do inżyniera, który napisze klienta, oraz do menedżera, któremu wystarczy samo podsumowanie.
Podsumowanie dla kierownictwa
Conversions API (CAPI) pozwala backendowi przesyłać zdarzenia konwersji do Microsoft Advertising niezależnie od tego, czy wyśle je przeglądarka. Jest to zwykły endpoint HTTPS, jedna ścieżka na jeden tag UET, uwierzytelniany tokenem bearer, przyjmujący do tysiąca zdarzeń w jednym żądaniu. Od wydania z maja 2026 token bearer można pobrać programowo, zamiast kopiować go ręcznie z interfejsu — i to właśnie zmienia ręczną konfigurację w proces, który da się zautomatyzować i objąć rotacją sekretów. Aktualna dokumentacja opisuje kształt odpowiedzi zawierającej ten token w dwóch wariantach, a ta rozbieżność bywa przyczyną błędu przy pierwszej próbie integracji — błędu, który wygląda na problem z uprawnieniami, choć nim nie jest. Pozostała część kontraktu jest przewidywalna: normalizacja, hashowanie, deduplikacja, mieszczenie się w siedmiodniowym oknie.
- Czym to jest: endpointem server-to-server pod adresem
https://capi.uet.microsoft.com/v1/{tagId}/events, który przyjmuje zdarzenia konwersji dla jednego tagu UET na ścieżkę i jest uwierzytelniany tokenem bearer w nagłówkuAuthorization. - Dlaczego teraz: przewodnik po integracji został gruntownie zmieniony 04.08.2026, a klucz uwierzytelniający można obecnie pobrać przez Campaign Management API, więc konfigurację daje się oskryptować zamiast wykonywać ręczne kopiowanie.
- Rozbieżność w dokumentacji: przewodnik dokumentuje zagnieżdżoną odpowiedź z kluczem uwierzytelniającym, a dokumentacja operacji — płaski ciąg znaków; klient napisany wyłącznie zgodnie z przewodnikiem rzuci wyjątkiem na odpowiedzi, która w rzeczywistości oznaczała powodzenie. Klient przyjmujący oba kształty jest zabezpieczony wobec obu stanów dokumentacji.
- Ile to kosztuje: jeden inżynier, mniej więcej tydzień do dwóch tygodni do produkcyjnego klienta wraz z uzupełnieniem historii, ponawianiem i monitoringiem — powierzchnia API jest niewielka, a czas pochłaniają normalizacja identyfikatorów, obsługa zgód oraz logika deduplikacji.
- Co się zyskuje: konwersje, które przetrwają blokery reklam, ograniczenia przeglądarek i porzucone sesje, a do tego klucz deduplikacji, który powstrzymuje tag w przeglądarce i serwer przed dwukrotnym zliczeniem tego samego zakupu.
Termin wdrożenia pozostaje kwestią planowania. Tag UET po stronie przeglądarki działa niezależnie od niego, dokładnie tak jak dotąd. Różnicę robi jakość pomiaru tych konwersji, których przeglądarka nigdy nie zgłasza — a ponieważ eventTime musi mieścić się w ostatnich siedmiu dniach, luki starszej niż tydzień nie da się już uzupełnić wstecznie. To jedno ograniczenie przemawia za wcześniejszym rozpoczęciem: każdy tydzień odroczenia to tydzień, którego nigdy nie da się wysłać.
1. Kontekst: konwersje server-side w Microsoft Advertising
Serwerowe API konwersji nie są nowością jako kategoria. Nowa jest dostępność dokumentacji na poziomie pozwalającym wdrożyć integrację wprost z opisu, bez inżynierii wstecznej. Przewodnik po integracji nosi datę dokumentu 04.08.2026 — w chwili pisania tego tekstu sprzed sześciu dni — i jest pełnym przepisaniem, a nie kosmetyczną poprawką. Strona referencyjna operacji pobierającej klucz uwierzytelniający została zaktualizowana dzień wcześniej, 03.08.2026. Gdy dwie powiązane strony zmieniają się w odstępie jednego dnia, zwykle zmieniła się także opisywana przez nie powierzchnia, co uzasadnia ponowną lekturę stron uznawanych już za znane.
Praktyczna przyczyna jest prostsza niż jakakolwiek narracja platformy. Przeglądarka zgłasza tylko część konwersji. Konwersja, która następuje w procesie zakupowym z włączonym blokerem reklam, w sesji kończącej się przed wyrenderowaniem strony potwierdzenia, w opakowaniu aplikacji natywnej albo kilka godzin później w call center, jest konwersją, której tag UET nigdy nie zobaczy. Baza zamówień widzi je wszystkie. Conversions API stanowi rurę łączącą system, który zna komplet zdarzeń, z systemem optymalizującym stawki.
Istnieje drugie, pokrewne zjawisko, o którym warto wiedzieć, lecz na którym nie warto jeszcze budować. Informacje o wydaniu z maja 2026 wprowadziły MSClickIdPerformanceReport, który udostępnia wyniki na poziomie pojedynczego identyfikatora kliknięcia i może dzięki temu zostać połączony z własnym zbiorem wartości msclkid. Kolumna ConversionsQualified ma typ Double. Powodem, by traktować to jako zapowiedź, a nie fundament, jest zdanie na stronie: „Not everyone has this feature yet” — pojawiające się tam dwukrotnie. To pilotaż, a nie ogólna dostępność. Można to uwzględnić w planach, nie uzależniając od tego wdrożenia.
2. Kontrakt techniczny: endpoint, uwierzytelnianie, pola wymagane
Kontrakt jest niewielki i daje się objąć w całości. Istnieje jeden endpoint, https://capi.uet.microsoft.com/v1/{tagId}/events, a identyfikator tagu jest częścią ścieżki, nie treści żądania. Przy obsłudze kilku tagów UET — częstej, gdy jedno konto obsługuje kilka marek lub rynków — integracja korzysta z kilku odrębnych adresów URL, a klient traktuje identyfikator tagu jako pełnoprawny parametr, nie stałą.
Uwierzytelnianie odbywa się tokenem bearer w nagłówku Authorization. Nie ma podpisywania, nagłówka ze znacznikiem czasu ani skrótu treści żądania do policzenia. Token należy do tagu, co oznacza, że zarządzanie tokenami również jest per tag: jeden sekret na identyfikator tagu, przechowywany i rotowany osobno dla każdego identyfikatora.
TAG_ID=123456789
AUTH_KEY="$(cat /etc/uet/authkey-${TAG_ID})" # własny magazyn sekretów
curl -sS -X POST
"https://capi.uet.microsoft.com/v1/${TAG_ID}/events"
-H "Authorization: Bearer ${AUTH_KEY}"
-H "Content-Type: application/json"
--data @batch.json
Jedno żądanie przenosi do 1000 zdarzeń. Wartość eventTime każdego zdarzenia musi mieścić się w ostatnich siedmiu dniach. Każde zdarzenie powinno zawierać eventId na potrzeby deduplikacji oraz wartość adStorageConsent. Identyfikatory użytkowników są normalizowane do małych liter, a następnie hashowane algorytmem SHA-256.
Osobnego omówienia wymaga dyscyplina źródeł. Pola wymienione w tym artykule to te, które źródła określają wprost. Nazwy pól opisujących konkretną konwersję — nazwa celu, wartość przychodu, waluta — pochodzą z własnej konfiguracji tagu oraz z tabeli pól w samym przewodniku po integracji. Tę tabelę warto przeczytać w oryginale, zamiast przejmować nazwy pól z wpisów blogowych, łącznie z tym artykułem. To samo dotyczy kodów błędów i limitów żądań: źródła, na których opiera się ten tekst, ich nie podają, więc ten tekst ich nie uzupełnia. Klienta warto oprzyrządować tak, aby logował wszystko, co endpoint faktycznie zwraca, i oprzeć politykę ponawiania na zachowaniu obserwowanym we własnym środowisku, a nie na wartości przyjętej z góry.
3. Klucz uwierzytelniający: przewodnik a dokumentacja operacji
Przed wydaniem z maja 2026 token bearer dla CAPI uzyskiwało się, otwierając interfejs Microsoft Advertising i kopiując go. Przy jednym tagu jest to wykonalne ręcznie. Zespół z jedenastoma tagami, polityką rotacji sekretów i dyżurem całodobowym potrzebuje drogi programowej. Operacja Campaign Management GetUetTagAuthKey zwraca teraz token dla danego tagu UET programowo i to właśnie ta zmiana czyni całą integrację operacyjnie wykonalną.
Oba dokumenty opisują tę operację odmiennie. Przewodnik po integracji pokazuje wywołanie z treścią żądania {"TagId": 123456789} oraz zagnieżdżoną odpowiedzią postaci {"TagAuthKey": {"AuthKey": "..."}}. Strona referencyjna operacji GetUetTagAuthKey definiuje inaczej: elementem żądania jest UetTagId, a elementem odpowiedzi UetTagAuthKey jako płaski ciąg znaków.
Obie wersje opisują ten sam wywoływany zasób, więc jedna z nich odpowiada bieżącemu zachowaniu usługi. Klient napisany wyłącznie według przewodnika sięga po TagAuthKey["AuthKey"]. Wobec odpowiedzi o kształcie opisanym w dokumentacji operacji taki parser rzuca wyjątkiem — przy wywołaniu, które w rzeczywistości zakończyło się powodzeniem. Ślad stosu wskazuje wtedy na obsługę JSON-a, objaw wygląda jak brak zwróconego klucza, a diagnostyka kieruje się w stronę identyfikatorów kont, identyfikatorów klientów i uprawnień API. Samo wywołanie przebiega przy tym poprawnie, a różnica dotyczy wyłącznie kształtu odpowiedzi.
Ekstraktor przyjmujący oba kształty jest zabezpieczony wobec obu stanów dokumentacji. Logowanie tego, który kształt faktycznie nadszedł, pozwala ustalić, który dokument odpowiada bieżącemu zachowaniu danego konta.
import logging
log = logging.getLogger(__name__)
def extract_auth_key(response):
"""Przyjmuje oba udokumentowane kształty odpowiedzi GetUetTagAuthKey.
Przewodnik : {"TagAuthKey": {"AuthKey": "..."}} (zagnieżdżony)
Dokumentacja: {"UetTagAuthKey": "..."} (płaski ciąg)
"""
# Postać płaska, zgodnie z dokumentacją operacji.
flat = response.get("UetTagAuthKey")
if isinstance(flat, str) and flat:
log.info("auth key: flat shape (reference)")
return flat
# Postać zagnieżdżona, jak pokazuje przewodnik po integracji.
nested = response.get("TagAuthKey")
if isinstance(nested, dict):
key = nested.get("AuthKey")
if isinstance(key, str) and key:
log.info("auth key: nested shape (guide)")
return key
# Część wrapperów zwraca obiekt zamiast słownika.
for attr in ("UetTagAuthKey", "TagAuthKey"):
value = getattr(response, attr, None)
if isinstance(value, str) and value:
log.info("auth key: attribute %s on response object", attr)
return value
raise ValueError(
"GetUetTagAuthKey returned neither the flat nor the nested "
"shape; raw response logged for inspection"
)
Strona żądania daje się potraktować tak samo. Jeżeli wrapper SOAP lub REST pozwala nazwać element żądania, wysyłany jest UetTagId zgodnie z definicją w dokumentacji operacji, a w komentarzu zostaje adnotacja, że przewodnik nazywa go TagId. Jeżeli wywołanie zostanie odrzucone z powodu nieznanego elementu, samo to odrzucenie jest informacją o nazwie obowiązującej w danym środowisku.
4. Deduplikacja: jak tag UET i zdarzenie serwerowe odnajdują się nawzajem
Gdy konwersje zaczną płynąć z serwera, większość z nich będzie wysyłana także z przeglądarki. Nie jest to stan do wyeliminowania — obie ścieżki są pożądane, bo każda obejmuje przypadki umykające drugiej. Do uniknięcia jest natomiast dwukrotne zliczenie jednego zakupu. Służy temu eventId: to pole, po którym deduplikowane są trafienie UET z przeglądarki i trafienie z serwera.
Reguła, która to umożliwia, dotyczy własnej aplikacji, a nie API. Identyfikator musi zostać wygenerowany jeden raz, przez system będący właścicielem zdarzenia, i przekazany obu transportom w niezmienionej postaci. W praktyce oznacza to, że backend tworzy identyfikator w momencie założenia zamówienia, renderuje go na stronie, aby tag UET mógł go wysłać, oraz zapisuje go razem z zamówieniem, aby klient serwerowy mógł później wysłać tę samą wartość.
Wszystkie tryby awarii są wariacjami na temat dwukrotnego wygenerowania identyfikatora. Losowa wartość utworzona w JavaScripcie przy ładowaniu strony i druga losowa wartość utworzona w zadaniu wsadowym nigdy się nie zgodzą. Wartość wywiedziona z identyfikatora sesji nie zgodzi się, gdy użytkownik dokona konwersji w innej sesji. Wartość wywiedziona z identyfikatora zamówienia jest stabilna, unikalna i przetrwa ponowienia — i o to właśnie chodzi, ponieważ ponowienia są drugim powodem, dla którego deduplikacja ma znaczenie. Jeżeli zadanie wsadowe wysyła paczkę ponownie po przekroczeniu limitu czasu, to identyczny eventId powstrzymuje ją przed staniem się drugą konwersją.
- Generowanie tylko raz:
eventIdjest wywodzony z czegoś, co zamówienie już posiada, tak aby to samo zdarzenie zawsze dawało ten sam identyfikator. - Przekazywanie, nigdy ponowne tworzenie: szablon i zadanie wsadowe odczytują zapisaną wartość; żadne z nich nie wylicza własnej.
- Stabilność przy ponowieniach: ponowiona paczka niesie identyczne identyfikatory, w przeciwnym razie ponowienie staje się podwójnym zliczeniem.
- Trwałe zapisanie: identyfikator zostaje utrwalony przy rekordzie zamówienia, ponieważ jest potrzebny do uzgodnień, gdy liczby przestaną się zgadzać.
5. Normalizacja, hashowanie i zgody
Identyfikatory użytkowników nie są przesyłane otwartym tekstem. Udokumentowana procedura to dwa kroki w ustalonej kolejności: najpierw normalizacja do małych liter, potem hashowanie algorytmem SHA-256. Kolejność jest wiążąca, ponieważ hashowanie nie jest niewrażliwe na wielkość liter. Anna@example.com i anna@example.com dają całkowicie niepowiązane skróty, a rozbieżność w tym miejscu nie zgłasza błędu — po cichu produkuje hash, który po drugiej stronie nigdy się z niczym nie dopasuje. Potok raportuje wtedy sukces, a wskaźnik dopasowań utrzymuje się blisko zera.
import hashlib
def hash_identifier(value):
"""Najpierw małe litery, potem SHA-256, zgodnie z dokumentacją.
Przycięcie otaczających białych znaków to higiena obronna wobec
własnej warstwy przechowywania; udokumentowane kroki to małe
litery + SHA-256.
"""
if value is None:
return None
normalised = str(value).strip().lower()
if not normalised:
return None
return hashlib.sha256(normalised.encode("utf-8")).hexdigest()
assert hash_identifier("Anna@Example.COM") == hash_identifier("anna@example.com")
Wszelkie dalsze porządkowanie poszczególnych pól — sposób kanonizacji numerów telefonów, postępowanie z adresacją z plusem w e-mailach, traktowanie nazwisk ze znakami diakrytycznymi — pozostaje własną decyzją i własnym ryzykiem. Źródła definiują małe litery i SHA-256. Nie definiują formatu telefonu specyficznego dla kraju, więc ten artykuł go nie podaje. Reguła zostaje wybrana raz, stosowana identycznie po stronie przeglądarki i serwera oraz spisana.
Zgoda podróżuje razem ze zdarzeniem w polu adStorageConsent, które przyjmuje wartość "G" dla zgody udzielonej i "D" dla odmowy. Wynikają z tego dwa punkty projektowe. Po pierwsze, wartość odzwierciedla stan zgody z chwili konwersji, a nie z chwili uruchomienia zadania wsadowego — co oznacza, że rekord zamówienia musi go utrwalić, a nie odczytywać później. Po drugie, stan nieznany jest traktowany jak odmowa. Jeżeli magazyn zgód nie ma odpowiedzi dla danego zamówienia, wysyłane jest "D". Domyślne przyjmowanie zgody przy brakującym rekordzie nie jest widoczne na pulpicie i ujawnia się dopiero podczas audytu.
6. Klient na produkcji: paczki, siedmiodniowe okno, wznawianie
Klienta kształtują trzy ograniczenia: 1000 zdarzeń na żądanie, eventTime w obrębie ostatnich siedmiu dni oraz brak udokumentowanych wskazówek co do limitowania żądań i kodów błędów. Dwa pierwsze to twarde granice, wokół których projektuje się rozwiązanie. Trzecie oznacza, że klient jest budowany tak, by uczyć się z tego, co obserwuje, a nie z tego, co założono.
Siedmiodniowe okno wyznacza górną granicę czasu, przez jaki potok może być zepsuty, zanim dane zostaną bezpowrotnie utracone. Zadanie, które po cichu zawodzi w piątek i zostaje zauważone dopiero w poniedziałek następnego tygodnia, porzuciło już zdarzenia bez możliwości odzyskania. Okno ogranicza też początkowe uzupełnienie historii: przy starcie można wysłać ostatnie siedem dni i ani chwili więcej. Start warto wokół tego zaplanować, ponieważ uzupełnienie historii starszej niż tydzień nie jest możliwe w późniejszym terminie.
from datetime import datetime, timedelta, timezone
MAX_BATCH = 1000
WINDOW = timedelta(days=7)
# Niewielki margines bezpieczeństwa, aby zdarzenie nie wygasło
# w locie podczas ponowienia. Warto dostroić go do własnych
# obserwowanych opóźnień.
MARGIN = timedelta(hours=1)
def within_window(event_time, now=None):
now = now or datetime.now(timezone.utc)
return (now - event_time) < (WINDOW - MARGIN)
def batches(events):
"""Zwraca paczki w rozmiarze API, odrzucając wszystko poza oknem."""
chunk = []
for event in events:
if not within_window(event.event_time):
# Warto je liczyć. Rosnąca liczba oznacza spóźniony potok.
yield_expired(event)
continue
chunk.append(event)
if len(chunk) >= MAX_BATCH:
yield chunk
chunk = []
if chunk:
yield chunk
Wznawianie opiera się na własnej bazie danych, a nie na jakimkolwiek kursorze, który mogłoby oferować API. Wystarczy kolumna ze stanem wysyłki przy rekordzie zamówienia — pending, sent, expired, failed — z której zadanie odczytuje i do której zapisuje. Wtedy awaria w połowie przebiegu nic nie kosztuje: kolejny przebieg podejmuje dokładnie te wiersze, które nigdy nie zostały potwierdzone, a ponieważ eventId jest stabilny, ponowne wysłanie wiersza, którego potwierdzenie zaginęło po drodze, jest nieszkodliwe.
- Wybór oczekujących zdarzeń uporządkowanych według
eventTime, od najstarszych, tak aby te najbliższe wygaśnięcia wychodziły pierwsze. - Odrzucenie i osobne policzenie wszystkiego, co znalazło się już poza oknem, zamiast pozostawiania tego odrzucenia po stronie API.
- Podział na paczki po maksymalnie 1000 zdarzeń, wysyłka i oznaczenie paczki jako wysłanej dopiero po potwierdzonym powodzeniu.
- Przy niepowodzeniu: odczekanie z narastającym opóźnieniem, zalogowanie faktycznej odpowiedzi dosłownie i pozostawienie wierszy w stanie oczekiwania do kolejnego przebiegu.
- Alert, gdy liczba wygasłych zdarzeń przekroczy samodzielnie ustalony próg — to wskaźnik wczesnego ostrzegania dla całego potoku.
O ponowieniach: ponieważ dostępna tu dokumentacja nie wylicza kodów błędów ani limitów żądań, założenia o tym, które niepowodzenia nadają się do ponowienia, nie są zaszywane w kodzie. Punktem wyjścia bywa wykładnicze odczekiwanie przy błędach transportu i przy każdej odpowiedzi innej niż sukces, logowanie pełnej treści odpowiedzi i doprecyzowanie polityki, gdy zbierze się tydzień rzeczywistych odpowiedzi z własnego konta. Reguła „retry on 429” wpisana bez obserwacji faktycznego zachowania limitującego pozostaje założeniem, a nie pomiarem.
7. Monitoring: metryki, które pokazują stan potoku
Integracja z CAPI zawodzi po cichu. Nie pojawia się użytkownik zgłaszający, że proces zakupowy jest zepsuty; pojawia się powolny dryf liczb, zauważalny po kilku tygodniach. Dlatego monitoring wymaga zaprojektowania, a jego większa część mieszka we własnej bazie danych, nie w pulpicie dostawcy.
-- Dzienna kondycja potoku wysyłki. Nazwy tabeli i kolumn są
-- symbolem zastępczym dla własnego magazynu zamówień / zdarzeń.
SELECT
date_trunc('day', event_time) AS day,
count(*) AS events_total,
count(*) FILTER (WHERE send_state = 'sent') AS sent,
count(*) FILTER (WHERE send_state = 'pending') AS still_pending,
count(*) FILTER (WHERE send_state = 'expired') AS lost_to_window,
count(*) FILTER (WHERE ad_storage_consent = 'D') AS consent_denied,
count(*) FILTER (WHERE hashed_email IS NULL) AS no_identifier,
round(avg(EXTRACT(EPOCH FROM (sent_at - event_time)) / 60.0), 1)
AS avg_lag_minutes
FROM conversion_events
WHERE event_time >= now() - interval '30 days'
GROUP BY 1
ORDER BY 1 DESC;
Pięć sygnałów zasługuje na alerty. Wygasłe zdarzenia powyżej zera oznaczają, że potok się spóźnia i dane są tracone bezpowrotnie; to ten sygnał uzasadnia powiadomienie dyżurnego. Opóźnienie wysyłki jest wskaźnikiem wyprzedzającym tego samego zjawiska — śledzony jest średni dystans między eventTime a momentem wysłania, z alarmem na długo przed zbliżeniem się do siedmiu dni. Pokrycie identyfikatorami, czyli udział zdarzeń niosących w ogóle zahashowany identyfikator, spada tego dnia, w którym zmieni się formularz zakupowy albo domyślne ustawienie zgody; nagły skok wskazuje na zmianę w kodzie, a nie zmianę na rynku. Struktura zgód, czyli stosunek "G" do "D", zmienia się powoli; skok oznacza, że narzędzie do zgód zmieniło zachowanie. Skuteczność paczek mówi, czy endpoint przyjmuje wysyłane dane, i należy do tego samego pulpitu co reszta.
Uzgadnianie danych ze stroną platformy to ostatni element i to właśnie tam przydają się dane na poziomie kliknięć. Porównanie własnej liczby wysłanych zdarzeń z raportowanymi konwersjami pokazuje, czy deduplikacja działa: jeżeli wartość po stronie platformy leży wyraźnie powyżej sumy zdarzeń przeglądarkowych i serwerowych, eventId się nie dopasowuje. Naturalnym narzędziem do tego porównania jest MSClickIdPerformanceReport, ponieważ można go połączyć z własnym zbiorem msclkid po identyfikatorze kliknięcia, a ConversionsQualified daje kolumnę liczbową do zestawienia. Pozostaje przy tym w mocy to, co jego własna strona podaje dwukrotnie — nie każdy ma jeszcze tę funkcję. Uzgadnianie warto zbudować tak, by w razie niedostępności raportu dla danego konta łagodnie degradowało się do porównania zagregowanego.
Wnioski
Na zakres wdrożenia składają się: pobieracz tokenu, normalizator, mechanizm paczkowania i kolumna stanu. Endpoint przyjmuje jedną ścieżkę na tag, token bearer i do tysiąca zdarzeń naraz. Decyzje wymagające najwięcej uwagi leżą poza samym API — są nimi ustalenie, gdzie rodzi się eventId, utrwalenie stanu zgody z chwili, której dotyczy, oraz dopilnowanie, by małe litery zawsze poprzedzały SHA-256.
W zamian otrzymuje się konwersje, których przeglądarka nigdy nie zgłosiła, oraz sygnał dla licytacji odzwierciedlający bazę zamówień, a nie tylko ten jej podzbiór, który przetrwał podróż przez przeglądarkę. Siedmiodniowe okno sprawia, że temat wymaga zaplanowania w czasie: niewysłana historia starsza niż tydzień przepada, więc zakres danych objętych integracją zależy od tego, jak szybko zacznie ona działać.
Otwarta pozostaje sama dokumentacja. Na dzień 10.08.2026 przewodnik po integracji i dokumentacja operacji GetUetTagAuthKey opisują różne elementy żądania i różne kształty odpowiedzi dla tej samej operacji, a obie strony były aktualizowane w ciągu ostatniego tygodnia. Tolerancyjny parser, logowanie otrzymanego kształtu i ponowne sprawdzenie obu stron przed kolejnym wydaniem uwzględniają fakt, że strony te się zmieniają. Źródłami pierwotnymi są przewodnik po integracji UET Conversion API, dokumentacja operacji GetUetTagAuthKey oraz informacje o wydaniach Microsoft Advertising dotyczące zmian z maja 2026. Wszystko, czego nie ma na tych stronach — kody błędów, limity żądań, semantykę ponowień — trzeba zmierzyć we własnym środowisku, a ten artykuł pozostawia te miejsca puste.