{"id":9357,"date":"2026-08-10T09:30:00","date_gmt":"2026-08-10T07:30:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=9357"},"modified":"2026-08-10T09:10:33","modified_gmt":"2026-08-10T07:10:33","slug":"microsoft-advertising-conversions-api-przewodnik-pl","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/","title":{"rendered":"Microsoft Advertising Conversions API: integracja server-side UET"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Microsoft Advertising przyjmuje obecnie konwersje bezpo\u015brednio z serwer\u00f3w za po\u015brednictwem Conversions API, a na pocz\u0105tku sierpnia 2026 roku przewodnik po integracji zosta\u0142 napisany na nowo, od pierwszej do ostatniej linijki. Ten artyku\u0142 jest adresowany do os\u00f3b, kt\u00f3re zbuduj\u0105 t\u0119 integracj\u0119 i b\u0119d\u0105 j\u0105 utrzymywa\u0107: do w\u0142a\u015bciciela obszaru pomiaru, kt\u00f3ry ocenia zasadno\u015b\u0107 wdro\u017cenia, do in\u017cyniera, kt\u00f3ry napisze klienta, oraz do mened\u017cera, kt\u00f3remu wystarczy samo podsumowanie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Podsumowanie dla kierownictwa<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Conversions API (CAPI) pozwala backendowi przesy\u0142a\u0107 zdarzenia konwersji do Microsoft Advertising niezale\u017cnie od tego, czy wy\u015ble je przegl\u0105darka. Jest to zwyk\u0142y endpoint HTTPS, jedna \u015bcie\u017cka na jeden tag UET, uwierzytelniany tokenem bearer, przyjmuj\u0105cy do tysi\u0105ca zdarze\u0144 w jednym \u017c\u0105daniu. Od wydania z maja 2026 token bearer mo\u017cna pobra\u0107 programowo, zamiast kopiowa\u0107 go r\u0119cznie z interfejsu \u2014 i to w\u0142a\u015bnie zmienia r\u0119czn\u0105 konfiguracj\u0119 w proces, kt\u00f3ry da si\u0119 zautomatyzowa\u0107 i obj\u0105\u0107 rotacj\u0105 sekret\u00f3w. Aktualna dokumentacja opisuje kszta\u0142t odpowiedzi zawieraj\u0105cej ten token w dw\u00f3ch wariantach, a ta rozbie\u017cno\u015b\u0107 bywa przyczyn\u0105 b\u0142\u0119du przy pierwszej pr\u00f3bie integracji \u2014 b\u0142\u0119du, kt\u00f3ry wygl\u0105da na problem z uprawnieniami, cho\u0107 nim nie jest. Pozosta\u0142a cz\u0119\u015b\u0107 kontraktu jest przewidywalna: normalizacja, hashowanie, deduplikacja, mieszczenie si\u0119 w siedmiodniowym oknie.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Czym to jest:<\/strong> endpointem server-to-server pod adresem <code>https:\/\/capi.uet.microsoft.com\/v1\/{tagId}\/events<\/code>, kt\u00f3ry przyjmuje zdarzenia konwersji dla jednego tagu UET na \u015bcie\u017ck\u0119 i jest uwierzytelniany tokenem bearer w nag\u0142\u00f3wku <code>Authorization<\/code>.<\/li>\n<li><strong>Dlaczego teraz:<\/strong> przewodnik po integracji zosta\u0142 gruntownie zmieniony 04.08.2026, a klucz uwierzytelniaj\u0105cy mo\u017cna obecnie pobra\u0107 przez Campaign Management API, wi\u0119c konfiguracj\u0119 daje si\u0119 oskryptowa\u0107 zamiast wykonywa\u0107 r\u0119czne kopiowanie.<\/li>\n<li><strong>Rozbie\u017cno\u015b\u0107 w dokumentacji:<\/strong> przewodnik dokumentuje zagnie\u017cd\u017con\u0105 odpowied\u017a z kluczem uwierzytelniaj\u0105cym, a dokumentacja operacji \u2014 p\u0142aski ci\u0105g znak\u00f3w; klient napisany wy\u0142\u0105cznie zgodnie z przewodnikiem rzuci wyj\u0105tkiem na odpowiedzi, kt\u00f3ra w rzeczywisto\u015bci oznacza\u0142a powodzenie. Klient przyjmuj\u0105cy oba kszta\u0142ty jest zabezpieczony wobec obu stan\u00f3w dokumentacji.<\/li>\n<li><strong>Ile to kosztuje:<\/strong> jeden in\u017cynier, mniej wi\u0119cej tydzie\u0144 do dw\u00f3ch tygodni do produkcyjnego klienta wraz z uzupe\u0142nieniem historii, ponawianiem i monitoringiem \u2014 powierzchnia API jest niewielka, a czas poch\u0142aniaj\u0105 normalizacja identyfikator\u00f3w, obs\u0142uga zg\u00f3d oraz logika deduplikacji.<\/li>\n<li><strong>Co si\u0119 zyskuje:<\/strong> konwersje, kt\u00f3re przetrwaj\u0105 blokery reklam, ograniczenia przegl\u0105darek i porzucone sesje, a do tego klucz deduplikacji, kt\u00f3ry powstrzymuje tag w przegl\u0105darce i serwer przed dwukrotnym zliczeniem tego samego zakupu.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Termin wdro\u017cenia pozostaje kwesti\u0105 planowania. Tag UET po stronie przegl\u0105darki dzia\u0142a niezale\u017cnie od niego, dok\u0142adnie tak jak dot\u0105d. R\u00f3\u017cnic\u0119 robi jako\u015b\u0107 pomiaru tych konwersji, kt\u00f3rych przegl\u0105darka nigdy nie zg\u0142asza \u2014 a poniewa\u017c <code>eventTime<\/code> musi mie\u015bci\u0107 si\u0119 w ostatnich siedmiu dniach, luki starszej ni\u017c tydzie\u0144 nie da si\u0119 ju\u017c uzupe\u0142ni\u0107 wstecznie. To jedno ograniczenie przemawia za wcze\u015bniejszym rozpocz\u0119ciem: ka\u017cdy tydzie\u0144 odroczenia to tydzie\u0144, kt\u00f3rego nigdy nie da si\u0119 wys\u0142a\u0107.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Kontekst: konwersje server-side w Microsoft Advertising<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Serwerowe API konwersji nie s\u0105 nowo\u015bci\u0105 jako kategoria. Nowa jest dost\u0119pno\u015b\u0107 dokumentacji na poziomie pozwalaj\u0105cym wdro\u017cy\u0107 integracj\u0119 wprost z opisu, bez in\u017cynierii wstecznej. Przewodnik po integracji nosi dat\u0119 dokumentu 04.08.2026 \u2014 w chwili pisania tego tekstu sprzed sze\u015bciu dni \u2014 i jest pe\u0142nym przepisaniem, a nie kosmetyczn\u0105 poprawk\u0105. Strona referencyjna operacji pobieraj\u0105cej klucz uwierzytelniaj\u0105cy zosta\u0142a zaktualizowana dzie\u0144 wcze\u015bniej, 03.08.2026. Gdy dwie powi\u0105zane strony zmieniaj\u0105 si\u0119 w odst\u0119pie jednego dnia, zwykle zmieni\u0142a si\u0119 tak\u017ce opisywana przez nie powierzchnia, co uzasadnia ponown\u0105 lektur\u0119 stron uznawanych ju\u017c za znane.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Praktyczna przyczyna jest prostsza ni\u017c jakakolwiek narracja platformy. Przegl\u0105darka zg\u0142asza tylko cz\u0119\u015b\u0107 konwersji. Konwersja, kt\u00f3ra nast\u0119puje w procesie zakupowym z w\u0142\u0105czonym blokerem reklam, w sesji ko\u0144cz\u0105cej si\u0119 przed wyrenderowaniem strony potwierdzenia, w opakowaniu aplikacji natywnej albo kilka godzin p\u00f3\u017aniej w call center, jest konwersj\u0105, kt\u00f3rej tag UET nigdy nie zobaczy. Baza zam\u00f3wie\u0144 widzi je wszystkie. Conversions API stanowi rur\u0119 \u0142\u0105cz\u0105c\u0105 system, kt\u00f3ry zna komplet zdarze\u0144, z systemem optymalizuj\u0105cym stawki.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Istnieje drugie, pokrewne zjawisko, o kt\u00f3rym warto wiedzie\u0107, lecz na kt\u00f3rym nie warto jeszcze budowa\u0107. Informacje o wydaniu z maja 2026 wprowadzi\u0142y <code>MSClickIdPerformanceReport<\/code>, kt\u00f3ry udost\u0119pnia wyniki na poziomie pojedynczego identyfikatora klikni\u0119cia i mo\u017ce dzi\u0119ki temu zosta\u0107 po\u0142\u0105czony z w\u0142asnym zbiorem warto\u015bci <code>msclkid<\/code>. Kolumna <code>ConversionsQualified<\/code> ma typ <code>Double<\/code>. Powodem, by traktowa\u0107 to jako zapowied\u017a, a nie fundament, jest zdanie na stronie: \u201eNot everyone has this feature yet\u201d \u2014 pojawiaj\u0105ce si\u0119 tam dwukrotnie. To pilota\u017c, a nie og\u00f3lna dost\u0119pno\u015b\u0107. Mo\u017cna to uwzgl\u0119dni\u0107 w planach, nie uzale\u017cniaj\u0105c od tego wdro\u017cenia.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Kontrakt techniczny: endpoint, uwierzytelnianie, pola wymagane<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kontrakt jest niewielki i daje si\u0119 obj\u0105\u0107 w ca\u0142o\u015bci. Istnieje jeden endpoint, <code>https:\/\/capi.uet.microsoft.com\/v1\/{tagId}\/events<\/code>, a identyfikator tagu jest cz\u0119\u015bci\u0105 \u015bcie\u017cki, nie tre\u015bci \u017c\u0105dania. Przy obs\u0142udze kilku tag\u00f3w UET \u2014 cz\u0119stej, gdy jedno konto obs\u0142uguje kilka marek lub rynk\u00f3w \u2014 integracja korzysta z kilku odr\u0119bnych adres\u00f3w URL, a klient traktuje identyfikator tagu jako pe\u0142noprawny parametr, nie sta\u0142\u0105.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uwierzytelnianie odbywa si\u0119 tokenem bearer w nag\u0142\u00f3wku <code>Authorization<\/code>. Nie ma podpisywania, nag\u0142\u00f3wka ze znacznikiem czasu ani skr\u00f3tu tre\u015bci \u017c\u0105dania do policzenia. Token nale\u017cy do tagu, co oznacza, \u017ce zarz\u0105dzanie tokenami r\u00f3wnie\u017c jest per tag: jeden sekret na identyfikator tagu, przechowywany i rotowany osobno dla ka\u017cdego identyfikatora.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-bash\">TAG_ID=123456789\nAUTH_KEY=\"$(cat \/etc\/uet\/authkey-${TAG_ID})\"   # w\u0142asny magazyn sekret\u00f3w\n\ncurl -sS -X POST \n  \"https:\/\/capi.uet.microsoft.com\/v1\/${TAG_ID}\/events\" \n  -H \"Authorization: Bearer ${AUTH_KEY}\" \n  -H \"Content-Type: application\/json\" \n  --data @batch.json<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Jedno \u017c\u0105danie przenosi do 1000 zdarze\u0144. Warto\u015b\u0107 <code>eventTime<\/code> ka\u017cdego zdarzenia musi mie\u015bci\u0107 si\u0119 w ostatnich siedmiu dniach. Ka\u017cde zdarzenie powinno zawiera\u0107 <code>eventId<\/code> na potrzeby deduplikacji oraz warto\u015b\u0107 <code>adStorageConsent<\/code>. Identyfikatory u\u017cytkownik\u00f3w s\u0105 normalizowane do ma\u0142ych liter, a nast\u0119pnie hashowane algorytmem SHA-256.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Osobnego om\u00f3wienia wymaga dyscyplina \u017ar\u00f3de\u0142. Pola wymienione w tym artykule to te, kt\u00f3re \u017ar\u00f3d\u0142a okre\u015blaj\u0105 wprost. Nazwy p\u00f3l opisuj\u0105cych <em>konkretn\u0105<\/em> konwersj\u0119 \u2014 nazwa celu, warto\u015b\u0107 przychodu, waluta \u2014 pochodz\u0105 z w\u0142asnej konfiguracji tagu oraz z tabeli p\u00f3l w samym przewodniku po integracji. T\u0119 tabel\u0119 warto przeczyta\u0107 w oryginale, zamiast przejmowa\u0107 nazwy p\u00f3l z wpis\u00f3w blogowych, \u0142\u0105cznie z tym artyku\u0142em. To samo dotyczy kod\u00f3w b\u0142\u0119d\u00f3w i limit\u00f3w \u017c\u0105da\u0144: \u017ar\u00f3d\u0142a, na kt\u00f3rych opiera si\u0119 ten tekst, ich nie podaj\u0105, wi\u0119c ten tekst ich nie uzupe\u0142nia. Klienta warto oprzyrz\u0105dowa\u0107 tak, aby logowa\u0142 wszystko, co endpoint faktycznie zwraca, i oprze\u0107 polityk\u0119 ponawiania na zachowaniu obserwowanym we w\u0142asnym \u015brodowisku, a nie na warto\u015bci przyj\u0119tej z g\u00f3ry.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Klucz uwierzytelniaj\u0105cy: przewodnik a dokumentacja operacji<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Przed wydaniem z maja 2026 token bearer dla CAPI uzyskiwa\u0142o si\u0119, otwieraj\u0105c interfejs Microsoft Advertising i kopiuj\u0105c go. Przy jednym tagu jest to wykonalne r\u0119cznie. Zesp\u00f3\u0142 z jedenastoma tagami, polityk\u0105 rotacji sekret\u00f3w i dy\u017curem ca\u0142odobowym potrzebuje drogi programowej. Operacja Campaign Management <code>GetUetTagAuthKey<\/code> zwraca teraz token dla danego tagu UET programowo i to w\u0142a\u015bnie ta zmiana czyni ca\u0142\u0105 integracj\u0119 operacyjnie wykonaln\u0105.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Oba dokumenty opisuj\u0105 t\u0119 operacj\u0119 odmiennie. Przewodnik po integracji pokazuje wywo\u0142anie z tre\u015bci\u0105 \u017c\u0105dania <code>{\"TagId\": 123456789}<\/code> oraz <em>zagnie\u017cd\u017con\u0105<\/em> odpowiedzi\u0105 postaci <code>{\"TagAuthKey\": {\"AuthKey\": \"...\"}}<\/code>. Strona referencyjna operacji <code>GetUetTagAuthKey<\/code> definiuje inaczej: elementem \u017c\u0105dania jest <code>UetTagId<\/code>, a elementem odpowiedzi <code>UetTagAuthKey<\/code> jako <em>p\u0142aski<\/em> ci\u0105g znak\u00f3w.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Obie wersje opisuj\u0105 ten sam wywo\u0142ywany zas\u00f3b, wi\u0119c jedna z nich odpowiada bie\u017c\u0105cemu zachowaniu us\u0142ugi. Klient napisany wy\u0142\u0105cznie wed\u0142ug przewodnika si\u0119ga po <code>TagAuthKey[\"AuthKey\"]<\/code>. Wobec odpowiedzi o kszta\u0142cie opisanym w dokumentacji operacji taki parser rzuca wyj\u0105tkiem \u2014 przy wywo\u0142aniu, kt\u00f3re w rzeczywisto\u015bci zako\u0144czy\u0142o si\u0119 powodzeniem. \u015alad stosu wskazuje wtedy na obs\u0142ug\u0119 JSON-a, objaw wygl\u0105da jak brak zwr\u00f3conego klucza, a diagnostyka kieruje si\u0119 w stron\u0119 identyfikator\u00f3w kont, identyfikator\u00f3w klient\u00f3w i uprawnie\u0144 API. Samo wywo\u0142anie przebiega przy tym poprawnie, a r\u00f3\u017cnica dotyczy wy\u0142\u0105cznie kszta\u0142tu odpowiedzi.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ekstraktor przyjmuj\u0105cy oba kszta\u0142ty jest zabezpieczony wobec obu stan\u00f3w dokumentacji. Logowanie tego, kt\u00f3ry kszta\u0142t faktycznie nadszed\u0142, pozwala ustali\u0107, kt\u00f3ry dokument odpowiada bie\u017c\u0105cemu zachowaniu danego konta.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-python\">import logging\n\nlog = logging.getLogger(__name__)\n\n\ndef extract_auth_key(response):\n    \"\"\"Przyjmuje oba udokumentowane kszta\u0142ty odpowiedzi GetUetTagAuthKey.\n\n    Przewodnik  : {\"TagAuthKey\": {\"AuthKey\": \"...\"}}   (zagnie\u017cd\u017cony)\n    Dokumentacja: {\"UetTagAuthKey\": \"...\"}             (p\u0142aski ci\u0105g)\n    \"\"\"\n    # Posta\u0107 p\u0142aska, zgodnie z dokumentacj\u0105 operacji.\n    flat = response.get(\"UetTagAuthKey\")\n    if isinstance(flat, str) and flat:\n        log.info(\"auth key: flat shape (reference)\")\n        return flat\n\n    # Posta\u0107 zagnie\u017cd\u017cona, jak pokazuje przewodnik po integracji.\n    nested = response.get(\"TagAuthKey\")\n    if isinstance(nested, dict):\n        key = nested.get(\"AuthKey\")\n        if isinstance(key, str) and key:\n            log.info(\"auth key: nested shape (guide)\")\n            return key\n\n    # Cz\u0119\u015b\u0107 wrapper\u00f3w zwraca obiekt zamiast s\u0142ownika.\n    for attr in (\"UetTagAuthKey\", \"TagAuthKey\"):\n        value = getattr(response, attr, None)\n        if isinstance(value, str) and value:\n            log.info(\"auth key: attribute %s on response object\", attr)\n            return value\n\n    raise ValueError(\n        \"GetUetTagAuthKey returned neither the flat nor the nested \"\n        \"shape; raw response logged for inspection\"\n    )<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Strona \u017c\u0105dania daje si\u0119 potraktowa\u0107 tak samo. Je\u017celi wrapper SOAP lub REST pozwala nazwa\u0107 element \u017c\u0105dania, wysy\u0142any jest <code>UetTagId<\/code> zgodnie z definicj\u0105 w dokumentacji operacji, a w komentarzu zostaje adnotacja, \u017ce przewodnik nazywa go <code>TagId<\/code>. Je\u017celi wywo\u0142anie zostanie odrzucone z powodu nieznanego elementu, samo to odrzucenie jest informacj\u0105 o nazwie obowi\u0105zuj\u0105cej w danym \u015brodowisku.<\/p>\n\n\n\n<figure class=\"lw-diagram\">\n<img src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/hand-mscapi-pl.png\" width=\"1120\" height=\"720\" decoding=\"async\" loading=\"lazy\"\n     alt=\"Jedno wywo\u0142anie uwierzytelniaj\u0105ce rozga\u0142\u0119zia si\u0119 na dwie udokumentowane postacie odpowiedzi, obiekt zagnie\u017cd\u017cony z przewodnika i p\u0142aski string z dokumentacji, obie prowadz\u0105 do klienta akceptuj\u0105cego ka\u017cd\u0105 z nich\">\n<figcaption>Ta sama operacja jest udokumentowana w dw\u00f3ch postaciach: przewodnik pokazuje obiekt zagnie\u017cd\u017cony, dokumentacja p\u0142aski string. Klient czytaj\u0105cy obie postacie zwraca klucz w ka\u017cdym przypadku i zg\u0142asza b\u0142\u0105d dopiero wtedy, gdy nie ma \u017cadnego z nich.<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">4. Deduplikacja: jak tag UET i zdarzenie serwerowe odnajduj\u0105 si\u0119 nawzajem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Gdy konwersje zaczn\u0105 p\u0142yn\u0105\u0107 z serwera, wi\u0119kszo\u015b\u0107 z nich b\u0119dzie wysy\u0142ana tak\u017ce z przegl\u0105darki. Nie jest to stan do wyeliminowania \u2014 obie \u015bcie\u017cki s\u0105 po\u017c\u0105dane, bo ka\u017cda obejmuje przypadki umykaj\u0105ce drugiej. Do unikni\u0119cia jest natomiast dwukrotne zliczenie jednego zakupu. S\u0142u\u017cy temu <code>eventId<\/code>: to pole, po kt\u00f3rym deduplikowane s\u0105 trafienie UET z przegl\u0105darki i trafienie z serwera.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Regu\u0142a, kt\u00f3ra to umo\u017cliwia, dotyczy w\u0142asnej aplikacji, a nie API. Identyfikator musi zosta\u0107 wygenerowany jeden raz, przez system b\u0119d\u0105cy w\u0142a\u015bcicielem zdarzenia, i przekazany obu transportom w niezmienionej postaci. W praktyce oznacza to, \u017ce backend tworzy identyfikator w momencie za\u0142o\u017cenia zam\u00f3wienia, renderuje go na stronie, aby tag UET m\u00f3g\u0142 go wys\u0142a\u0107, oraz zapisuje go razem z zam\u00f3wieniem, aby klient serwerowy m\u00f3g\u0142 p\u00f3\u017aniej wys\u0142a\u0107 t\u0119 sam\u0105 warto\u015b\u0107.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wszystkie tryby awarii s\u0105 wariacjami na temat dwukrotnego wygenerowania identyfikatora. Losowa warto\u015b\u0107 utworzona w JavaScripcie przy \u0142adowaniu strony i druga losowa warto\u015b\u0107 utworzona w zadaniu wsadowym nigdy si\u0119 nie zgodz\u0105. Warto\u015b\u0107 wywiedziona z identyfikatora sesji nie zgodzi si\u0119, gdy u\u017cytkownik dokona konwersji w innej sesji. Warto\u015b\u0107 wywiedziona z identyfikatora zam\u00f3wienia jest stabilna, unikalna i przetrwa ponowienia \u2014 i o to w\u0142a\u015bnie chodzi, poniewa\u017c ponowienia s\u0105 drugim powodem, dla kt\u00f3rego deduplikacja ma znaczenie. Je\u017celi zadanie wsadowe wysy\u0142a paczk\u0119 ponownie po przekroczeniu limitu czasu, to identyczny <code>eventId<\/code> powstrzymuje j\u0105 przed staniem si\u0119 drug\u0105 konwersj\u0105.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Generowanie tylko raz:<\/strong> <code>eventId<\/code> jest wywodzony z czego\u015b, co zam\u00f3wienie ju\u017c posiada, tak aby to samo zdarzenie zawsze dawa\u0142o ten sam identyfikator.<\/li>\n<li><strong>Przekazywanie, nigdy ponowne tworzenie:<\/strong> szablon i zadanie wsadowe odczytuj\u0105 zapisan\u0105 warto\u015b\u0107; \u017cadne z nich nie wylicza w\u0142asnej.<\/li>\n<li><strong>Stabilno\u015b\u0107 przy ponowieniach:<\/strong> ponowiona paczka niesie identyczne identyfikatory, w przeciwnym razie ponowienie staje si\u0119 podw\u00f3jnym zliczeniem.<\/li>\n<li><strong>Trwa\u0142e zapisanie:<\/strong> identyfikator zostaje utrwalony przy rekordzie zam\u00f3wienia, poniewa\u017c jest potrzebny do uzgodnie\u0144, gdy liczby przestan\u0105 si\u0119 zgadza\u0107.<\/li>\n<\/ul>\n\n\n\n<figure class=\"lw-diagram\">\n<img src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/hand-mscapiflow-pl.png\" width=\"1120\" height=\"820\" decoding=\"async\" loading=\"lazy\"\n     alt=\"Diagram sekwencji z trzema torami \u2014 przegl\u0105darka, w\u0142asny backend i Microsoft \u2014 w kt\u00f3rym zakup tworzy zdarzenie po stronie klienta i po stronie serwera, oba z tym samym eventId, scalane w jedn\u0105 konwersj\u0119\">\n<figcaption>Obie \u015bcie\u017cki nios\u0105 to samo eventId. Trafienie przegl\u0105darkowe zale\u017cy od \u015brodowiska, wi\u0119c dopiero serwerowe czyni konwersj\u0119 wiarygodn\u0105 \u2014 a wsp\u00f3lny identyfikator chroni przed policzeniem jej dwa razy.<\/figcaption>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">5. Normalizacja, hashowanie i zgody<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Identyfikatory u\u017cytkownik\u00f3w nie s\u0105 przesy\u0142ane otwartym tekstem. Udokumentowana procedura to dwa kroki w ustalonej kolejno\u015bci: najpierw normalizacja do ma\u0142ych liter, potem hashowanie algorytmem SHA-256. Kolejno\u015b\u0107 jest wi\u0105\u017c\u0105ca, poniewa\u017c hashowanie nie jest niewra\u017cliwe na wielko\u015b\u0107 liter. <code>Anna@example.com<\/code> i <code>anna@example.com<\/code> daj\u0105 ca\u0142kowicie niepowi\u0105zane skr\u00f3ty, a rozbie\u017cno\u015b\u0107 w tym miejscu nie zg\u0142asza b\u0142\u0119du \u2014 po cichu produkuje hash, kt\u00f3ry po drugiej stronie nigdy si\u0119 z niczym nie dopasuje. Potok raportuje wtedy sukces, a wska\u017anik dopasowa\u0144 utrzymuje si\u0119 blisko zera.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-python\">import hashlib\n\n\ndef hash_identifier(value):\n    \"\"\"Najpierw ma\u0142e litery, potem SHA-256, zgodnie z dokumentacj\u0105.\n\n    Przyci\u0119cie otaczaj\u0105cych bia\u0142ych znak\u00f3w to higiena obronna wobec\n    w\u0142asnej warstwy przechowywania; udokumentowane kroki to ma\u0142e\n    litery + SHA-256.\n    \"\"\"\n    if value is None:\n        return None\n    normalised = str(value).strip().lower()\n    if not normalised:\n        return None\n    return hashlib.sha256(normalised.encode(\"utf-8\")).hexdigest()\n\n\nassert hash_identifier(\"Anna@Example.COM\") == hash_identifier(\"anna@example.com\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wszelkie dalsze porz\u0105dkowanie poszczeg\u00f3lnych p\u00f3l \u2014 spos\u00f3b kanonizacji numer\u00f3w telefon\u00f3w, post\u0119powanie z adresacj\u0105 z plusem w e-mailach, traktowanie nazwisk ze znakami diakrytycznymi \u2014 pozostaje w\u0142asn\u0105 decyzj\u0105 i w\u0142asnym ryzykiem. \u0179r\u00f3d\u0142a definiuj\u0105 ma\u0142e litery i SHA-256. Nie definiuj\u0105 formatu telefonu specyficznego dla kraju, wi\u0119c ten artyku\u0142 go nie podaje. Regu\u0142a zostaje wybrana raz, stosowana identycznie po stronie przegl\u0105darki i serwera oraz spisana.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zgoda podr\u00f3\u017cuje razem ze zdarzeniem w polu <code>adStorageConsent<\/code>, kt\u00f3re przyjmuje warto\u015b\u0107 <code>\"G\"<\/code> dla zgody udzielonej i <code>\"D\"<\/code> dla odmowy. Wynikaj\u0105 z tego dwa punkty projektowe. Po pierwsze, warto\u015b\u0107 odzwierciedla stan zgody z chwili konwersji, a nie z chwili uruchomienia zadania wsadowego \u2014 co oznacza, \u017ce rekord zam\u00f3wienia musi go utrwali\u0107, a nie odczytywa\u0107 p\u00f3\u017aniej. Po drugie, stan nieznany jest traktowany jak odmowa. Je\u017celi magazyn zg\u00f3d nie ma odpowiedzi dla danego zam\u00f3wienia, wysy\u0142ane jest <code>\"D\"<\/code>. Domy\u015blne przyjmowanie zgody przy brakuj\u0105cym rekordzie nie jest widoczne na pulpicie i ujawnia si\u0119 dopiero podczas audytu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Klient na produkcji: paczki, siedmiodniowe okno, wznawianie<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Klienta kszta\u0142tuj\u0105 trzy ograniczenia: 1000 zdarze\u0144 na \u017c\u0105danie, <code>eventTime<\/code> w obr\u0119bie ostatnich siedmiu dni oraz brak udokumentowanych wskaz\u00f3wek co do limitowania \u017c\u0105da\u0144 i kod\u00f3w b\u0142\u0119d\u00f3w. Dwa pierwsze to twarde granice, wok\u00f3\u0142 kt\u00f3rych projektuje si\u0119 rozwi\u0105zanie. Trzecie oznacza, \u017ce klient jest budowany tak, by uczy\u0107 si\u0119 z tego, co obserwuje, a nie z tego, co za\u0142o\u017cono.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Siedmiodniowe okno wyznacza g\u00f3rn\u0105 granic\u0119 czasu, przez jaki potok mo\u017ce by\u0107 zepsuty, zanim dane zostan\u0105 bezpowrotnie utracone. Zadanie, kt\u00f3re po cichu zawodzi w pi\u0105tek i zostaje zauwa\u017cone dopiero w poniedzia\u0142ek nast\u0119pnego tygodnia, porzuci\u0142o ju\u017c zdarzenia bez mo\u017cliwo\u015bci odzyskania. Okno ogranicza te\u017c pocz\u0105tkowe uzupe\u0142nienie historii: przy starcie mo\u017cna wys\u0142a\u0107 ostatnie siedem dni i ani chwili wi\u0119cej. Start warto wok\u00f3\u0142 tego zaplanowa\u0107, poniewa\u017c uzupe\u0142nienie historii starszej ni\u017c tydzie\u0144 nie jest mo\u017cliwe w p\u00f3\u017aniejszym terminie.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-python\">from datetime import datetime, timedelta, timezone\n\nMAX_BATCH = 1000\nWINDOW = timedelta(days=7)\n\n# Niewielki margines bezpiecze\u0144stwa, aby zdarzenie nie wygas\u0142o\n# w locie podczas ponowienia. Warto dostroi\u0107 go do w\u0142asnych\n# obserwowanych op\u00f3\u017anie\u0144.\nMARGIN = timedelta(hours=1)\n\n\ndef within_window(event_time, now=None):\n    now = now or datetime.now(timezone.utc)\n    return (now - event_time) &lt; (WINDOW - MARGIN)\n\n\ndef batches(events):\n    \"\"\"Zwraca paczki w rozmiarze API, odrzucaj\u0105c wszystko poza oknem.\"\"\"\n    chunk = []\n    for event in events:\n        if not within_window(event.event_time):\n            # Warto je liczy\u0107. Rosn\u0105ca liczba oznacza sp\u00f3\u017aniony potok.\n            yield_expired(event)\n            continue\n        chunk.append(event)\n        if len(chunk) &gt;= MAX_BATCH:\n            yield chunk\n            chunk = []\n    if chunk:\n        yield chunk<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wznawianie opiera si\u0119 na w\u0142asnej bazie danych, a nie na jakimkolwiek kursorze, kt\u00f3ry mog\u0142oby oferowa\u0107 API. Wystarczy kolumna ze stanem wysy\u0142ki przy rekordzie zam\u00f3wienia \u2014 pending, sent, expired, failed \u2014 z kt\u00f3rej zadanie odczytuje i do kt\u00f3rej zapisuje. Wtedy awaria w po\u0142owie przebiegu nic nie kosztuje: kolejny przebieg podejmuje dok\u0142adnie te wiersze, kt\u00f3re nigdy nie zosta\u0142y potwierdzone, a poniewa\u017c <code>eventId<\/code> jest stabilny, ponowne wys\u0142anie wiersza, kt\u00f3rego potwierdzenie zagin\u0119\u0142o po drodze, jest nieszkodliwe.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Wyb\u00f3r oczekuj\u0105cych zdarze\u0144 uporz\u0105dkowanych wed\u0142ug <code>eventTime<\/code>, od najstarszych, tak aby te najbli\u017csze wyga\u015bni\u0119cia wychodzi\u0142y pierwsze.<\/li>\n<li>Odrzucenie i osobne policzenie wszystkiego, co znalaz\u0142o si\u0119 ju\u017c poza oknem, zamiast pozostawiania tego odrzucenia po stronie API.<\/li>\n<li>Podzia\u0142 na paczki po maksymalnie 1000 zdarze\u0144, wysy\u0142ka i oznaczenie paczki jako wys\u0142anej dopiero po potwierdzonym powodzeniu.<\/li>\n<li>Przy niepowodzeniu: odczekanie z narastaj\u0105cym op\u00f3\u017anieniem, zalogowanie faktycznej odpowiedzi dos\u0142ownie i pozostawienie wierszy w stanie oczekiwania do kolejnego przebiegu.<\/li>\n<li>Alert, gdy liczba wygas\u0142ych zdarze\u0144 przekroczy samodzielnie ustalony pr\u00f3g \u2014 to wska\u017anik wczesnego ostrzegania dla ca\u0142ego potoku.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">O ponowieniach: poniewa\u017c dost\u0119pna tu dokumentacja nie wylicza kod\u00f3w b\u0142\u0119d\u00f3w ani limit\u00f3w \u017c\u0105da\u0144, za\u0142o\u017cenia o tym, kt\u00f3re niepowodzenia nadaj\u0105 si\u0119 do ponowienia, nie s\u0105 zaszywane w kodzie. Punktem wyj\u015bcia bywa wyk\u0142adnicze odczekiwanie przy b\u0142\u0119dach transportu i przy ka\u017cdej odpowiedzi innej ni\u017c sukces, logowanie pe\u0142nej tre\u015bci odpowiedzi i doprecyzowanie polityki, gdy zbierze si\u0119 tydzie\u0144 rzeczywistych odpowiedzi z w\u0142asnego konta. Regu\u0142a \u201eretry on 429\u201d wpisana bez obserwacji faktycznego zachowania limituj\u0105cego pozostaje za\u0142o\u017ceniem, a nie pomiarem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Monitoring: metryki, kt\u00f3re pokazuj\u0105 stan potoku<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Integracja z CAPI zawodzi po cichu. Nie pojawia si\u0119 u\u017cytkownik zg\u0142aszaj\u0105cy, \u017ce proces zakupowy jest zepsuty; pojawia si\u0119 powolny dryf liczb, zauwa\u017calny po kilku tygodniach. Dlatego monitoring wymaga zaprojektowania, a jego wi\u0119ksza cz\u0119\u015b\u0107 mieszka we w\u0142asnej bazie danych, nie w pulpicie dostawcy.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"language-sql\">-- Dzienna kondycja potoku wysy\u0142ki. Nazwy tabeli i kolumn s\u0105\n-- symbolem zast\u0119pczym dla w\u0142asnego magazynu zam\u00f3wie\u0144 \/ zdarze\u0144.\nSELECT\n    date_trunc('day', event_time)                       AS day,\n    count(*)                                            AS events_total,\n    count(*) FILTER (WHERE send_state = 'sent')         AS sent,\n    count(*) FILTER (WHERE send_state = 'pending')      AS still_pending,\n    count(*) FILTER (WHERE send_state = 'expired')      AS lost_to_window,\n    count(*) FILTER (WHERE ad_storage_consent = 'D')    AS consent_denied,\n    count(*) FILTER (WHERE hashed_email IS NULL)        AS no_identifier,\n    round(avg(EXTRACT(EPOCH FROM (sent_at - event_time)) \/ 60.0), 1)\n                                                        AS avg_lag_minutes\nFROM conversion_events\nWHERE event_time &gt;= now() - interval '30 days'\nGROUP BY 1\nORDER BY 1 DESC;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pi\u0119\u0107 sygna\u0142\u00f3w zas\u0142uguje na alerty. <strong>Wygas\u0142e zdarzenia<\/strong> powy\u017cej zera oznaczaj\u0105, \u017ce potok si\u0119 sp\u00f3\u017ania i dane s\u0105 tracone bezpowrotnie; to ten sygna\u0142 uzasadnia powiadomienie dy\u017curnego. <strong>Op\u00f3\u017anienie wysy\u0142ki<\/strong> jest wska\u017anikiem wyprzedzaj\u0105cym tego samego zjawiska \u2014 \u015bledzony jest \u015bredni dystans mi\u0119dzy <code>eventTime<\/code> a momentem wys\u0142ania, z alarmem na d\u0142ugo przed zbli\u017ceniem si\u0119 do siedmiu dni. <strong>Pokrycie identyfikatorami<\/strong>, czyli udzia\u0142 zdarze\u0144 nios\u0105cych w og\u00f3le zahashowany identyfikator, spada tego dnia, w kt\u00f3rym zmieni si\u0119 formularz zakupowy albo domy\u015blne ustawienie zgody; nag\u0142y skok wskazuje na zmian\u0119 w kodzie, a nie zmian\u0119 na rynku. <strong>Struktura zg\u00f3d<\/strong>, czyli stosunek <code>\"G\"<\/code> do <code>\"D\"<\/code>, zmienia si\u0119 powoli; skok oznacza, \u017ce narz\u0119dzie do zg\u00f3d zmieni\u0142o zachowanie. <strong>Skuteczno\u015b\u0107 paczek<\/strong> m\u00f3wi, czy endpoint przyjmuje wysy\u0142ane dane, i nale\u017cy do tego samego pulpitu co reszta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Uzgadnianie danych ze stron\u0105 platformy to ostatni element i to w\u0142a\u015bnie tam przydaj\u0105 si\u0119 dane na poziomie klikni\u0119\u0107. Por\u00f3wnanie w\u0142asnej liczby wys\u0142anych zdarze\u0144 z raportowanymi konwersjami pokazuje, czy deduplikacja dzia\u0142a: je\u017celi warto\u015b\u0107 po stronie platformy le\u017cy wyra\u017anie powy\u017cej sumy zdarze\u0144 przegl\u0105darkowych i serwerowych, <code>eventId<\/code> si\u0119 nie dopasowuje. Naturalnym narz\u0119dziem do tego por\u00f3wnania jest <code>MSClickIdPerformanceReport<\/code>, poniewa\u017c mo\u017cna go po\u0142\u0105czy\u0107 z w\u0142asnym zbiorem <code>msclkid<\/code> po identyfikatorze klikni\u0119cia, a <code>ConversionsQualified<\/code> daje kolumn\u0119 liczbow\u0105 do zestawienia. Pozostaje przy tym w mocy to, co jego w\u0142asna strona podaje dwukrotnie \u2014 nie ka\u017cdy ma jeszcze t\u0119 funkcj\u0119. Uzgadnianie warto zbudowa\u0107 tak, by w razie niedost\u0119pno\u015bci raportu dla danego konta \u0142agodnie degradowa\u0142o si\u0119 do por\u00f3wnania zagregowanego.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wnioski<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Na zakres wdro\u017cenia sk\u0142adaj\u0105 si\u0119: pobieracz tokenu, normalizator, mechanizm paczkowania i kolumna stanu. Endpoint przyjmuje jedn\u0105 \u015bcie\u017ck\u0119 na tag, token bearer i do tysi\u0105ca zdarze\u0144 naraz. Decyzje wymagaj\u0105ce najwi\u0119cej uwagi le\u017c\u0105 poza samym API \u2014 s\u0105 nimi ustalenie, gdzie rodzi si\u0119 <code>eventId<\/code>, utrwalenie stanu zgody z chwili, kt\u00f3rej dotyczy, oraz dopilnowanie, by ma\u0142e litery zawsze poprzedza\u0142y SHA-256.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W zamian otrzymuje si\u0119 konwersje, kt\u00f3rych przegl\u0105darka nigdy nie zg\u0142osi\u0142a, oraz sygna\u0142 dla licytacji odzwierciedlaj\u0105cy baz\u0119 zam\u00f3wie\u0144, a nie tylko ten jej podzbi\u00f3r, kt\u00f3ry przetrwa\u0142 podr\u00f3\u017c przez przegl\u0105dark\u0119. Siedmiodniowe okno sprawia, \u017ce temat wymaga zaplanowania w czasie: niewys\u0142ana historia starsza ni\u017c tydzie\u0144 przepada, wi\u0119c zakres danych obj\u0119tych integracj\u0105 zale\u017cy od tego, jak szybko zacznie ona dzia\u0142a\u0107.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Otwarta pozostaje sama dokumentacja. Na dzie\u0144 10.08.2026 przewodnik po integracji i dokumentacja operacji <code>GetUetTagAuthKey<\/code> opisuj\u0105 r\u00f3\u017cne elementy \u017c\u0105dania i r\u00f3\u017cne kszta\u0142ty odpowiedzi dla tej samej operacji, a obie strony by\u0142y aktualizowane w ci\u0105gu ostatniego tygodnia. Tolerancyjny parser, logowanie otrzymanego kszta\u0142tu i ponowne sprawdzenie obu stron przed kolejnym wydaniem uwzgl\u0119dniaj\u0105 fakt, \u017ce strony te si\u0119 zmieniaj\u0105. \u0179r\u00f3d\u0142ami pierwotnymi s\u0105 <a href=\"https:\/\/learn.microsoft.com\/en-us\/advertising\/guides\/uet-conversion-api-integration?view=bingads-13\">przewodnik po integracji UET Conversion API<\/a>, <a href=\"https:\/\/learn.microsoft.com\/en-us\/advertising\/campaign-management-service\/getuettagauthkey?view=bingads-13\">dokumentacja operacji GetUetTagAuthKey<\/a> oraz <a href=\"https:\/\/learn.microsoft.com\/en-us\/advertising\/guides\/release-notes?view=bingads-13\">informacje o wydaniach Microsoft Advertising<\/a> dotycz\u0105ce zmian z maja 2026. Wszystko, czego nie ma na tych stronach \u2014 kody b\u0142\u0119d\u00f3w, limity \u017c\u0105da\u0144, semantyk\u0119 ponowie\u0144 \u2014 trzeba zmierzy\u0107 we w\u0142asnym \u015brodowisku, a ten artyku\u0142 pozostawia te miejsca puste.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Opis kontraktu Conversions API w Microsoft Advertising: endpoint, uwierzytelnianie tokenem bearer, deduplikacja przez eventId, normalizacja i hashowanie identyfikator\u00f3w, siedmiodniowe okno eventTime oraz monitoring potoku. Uwzgl\u0119dnia r\u00f3\u017cnic\u0119 w opisie operacji GetUetTagAuthKey mi\u0119dzy przewodnikiem po integracji a dokumentacj\u0105 operacji.<\/p>\n","protected":false},"author":1,"featured_media":9398,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[92035,92038,92041,92044],"class_list":["post-9357","post","type-post","status-publish","format-standard","hentry","category-digital-marketing-pl","tag-conversion-tracking-pl","tag-marketing-cyfrowy-pl-pl","tag-first-party-data-pl","tag-tracking-pl"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Microsoft Advertising Conversions API: integracja server-side UET - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Microsoft Advertising Conversions API: integracja server-side UET - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Opis kontraktu Conversions API w Microsoft Advertising: endpoint, uwierzytelnianie tokenem bearer, deduplikacja przez eventId, normalizacja i hashowanie identyfikator\u00f3w, siedmiodniowe okno eventTime oraz monitoring potoku. Uwzgl\u0119dnia r\u00f3\u017cnic\u0119 w opisie operacji GetUetTagAuthKey mi\u0119dzy przewodnikiem po integracji a dokumentacj\u0105 operacji.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-10T07:30:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"luky\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"luky\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/\"},\"author\":{\"name\":\"luky\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"Microsoft Advertising Conversions API: integracja server-side UET\",\"datePublished\":\"2026-08-10T07:30:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/\"},\"wordCount\":3081,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg\",\"keywords\":[\"Conversion Tracking\",\"Digital Marketing\",\"First-Party Data\",\"Tracking\"],\"articleSection\":[\"Digital Marketing\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/\",\"name\":\"Microsoft Advertising Conversions API: integracja server-side UET - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg\",\"datePublished\":\"2026-08-10T07:30:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg\",\"width\":1200,\"height\":630,\"caption\":\"Microsoft Advertising Conversions API: integracja server-side UET\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/digital-marketing-pl\\\/microsoft-advertising-conversions-api-przewodnik-pl\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Microsoft Advertising Conversions API: integracja server-side UET\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"],\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/author\\\/luky\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Microsoft Advertising Conversions API: integracja server-side UET - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/","og_locale":"en_US","og_type":"article","og_title":"Microsoft Advertising Conversions API: integracja server-side UET - Lukas Wojcik - Blog","og_description":"Opis kontraktu Conversions API w Microsoft Advertising: endpoint, uwierzytelnianie tokenem bearer, deduplikacja przez eventId, normalizacja i hashowanie identyfikator\u00f3w, siedmiodniowe okno eventTime oraz monitoring potoku. Uwzgl\u0119dnia r\u00f3\u017cnic\u0119 w opisie operacji GetUetTagAuthKey mi\u0119dzy przewodnikiem po integracji a dokumentacj\u0105 operacji.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-08-10T07:30:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg","type":"image\/jpeg"}],"author":"luky","twitter_card":"summary_large_image","twitter_misc":{"Written by":"luky","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/"},"author":{"name":"luky","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"Microsoft Advertising Conversions API: integracja server-side UET","datePublished":"2026-08-10T07:30:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/"},"wordCount":3081,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg","keywords":["Conversion Tracking","Digital Marketing","First-Party Data","Tracking"],"articleSection":["Digital Marketing"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/","url":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/","name":"Microsoft Advertising Conversions API: integracja server-side UET - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg","datePublished":"2026-08-10T07:30:00+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/fi-9357-microsoft-advertising-conversions-api-integracja-ser.jpg","width":1200,"height":630,"caption":"Microsoft Advertising Conversions API: integracja server-side UET"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/microsoft-advertising-conversions-api-przewodnik-pl\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Microsoft Advertising Conversions API: integracja server-side UET"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"],"url":"https:\/\/www.lukaswojcik.com\/blog\/author\/luky\/"}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/9357","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=9357"}],"version-history":[{"count":2,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/9357\/revisions"}],"predecessor-version":[{"id":9395,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/9357\/revisions\/9395"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/9398"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=9357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=9357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=9357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}