Microsoft Advertising Conversions API: Praxisleitfaden für server-seitiges UET
Inhalt
- Management Summary
- 1. Warum server-seitige Conversions bei Microsoft jetzt ein Thema sind
- 2. Der technische Vertrag: Endpoint, Authentifizierung, Pflichtfelder
- 3. Der Auth Key und die Angaben in Leitfaden und Referenz
- 4. Deduplizierung: Wie UET-Tag und Server-Event zueinanderfinden
- 5. Normalisierung, Hashing und Consent
- 6. Der Client im Produktivbetrieb: Batches, Sieben-Tage-Fenster, Wiederaufnahme
- 7. Monitoring: Welche Kennzahlen den Zustand der Integration anzeigen
- Fazit
Microsoft Advertising nimmt Conversions inzwischen direkt von den Servern der werbetreibenden Systeme entgegen – über die Conversions API. Seit Anfang August 2026 liegt der zugehörige Integrationsleitfaden zudem in einer vollständig neu geschriebenen Fassung vor. Dieser Artikel richtet sich an diejenigen, die diese Integration tatsächlich bauen und betreiben: an die Tracking-Verantwortlichen, die über den Aufwand entscheiden, an die Entwicklerinnen und Entwickler, die den Client schreiben, und an die Führungsebene, für die die Zusammenfassung gedacht ist.
Management Summary
Mit der Conversions API (CAPI) meldet das Backend Conversion-Events an Microsoft Advertising, unabhängig davon, ob der Browser sie auslöst. Dahinter steht ein HTTPS-Endpoint, ein Pfad je UET-Tag, authentifiziert über ein Bearer Token, mit bis zu tausend Events pro Request. Seit dem Release vom Mai 2026 lässt sich dieses Bearer Token programmatisch abrufen, statt es von Hand aus der Oberfläche zu kopieren – damit wird aus einem manuellen Setup eines, das sich automatisieren und rotieren lässt. Zur Struktur dieser Token-Antwort machen Leitfaden und Operationsreferenz unterschiedliche Angaben, und dieser Unterschied ist die häufigste Ursache dafür, dass ein erster Integrationsversuch abbricht – mit einem Fehlerbild, das an ein Berechtigungsproblem erinnert, ohne eines zu sein. Der übrige Vertrag ist unkompliziert: normalisieren, hashen, deduplizieren, innerhalb eines Sieben-Tage-Fensters bleiben.
- Worum es geht: Ein Server-zu-Server-Endpoint unter
https://capi.uet.microsoft.com/v1/{tagId}/events, der Conversion-Events für jeweils ein UET-Tag pro Pfad annimmt, authentifiziert über ein Bearer Token imAuthorization-Header. - Warum jetzt: Der Integrationsleitfaden wurde am 04.08.2026 vollständig überarbeitet, und der Auth Key lässt sich nun über die Campaign Management API abrufen – das Setup ist damit skriptbar statt manuell auszuführen.
- Der Unterschied in der Dokumentation: Der Leitfaden dokumentiert eine verschachtelte Antwort für den Auth Key, die Operationsreferenz einen flachen String. Ein Client, der gegen den Leitfaden geschrieben wurde, wirft eine Exception auf eine Antwort, die erfolgreich war. Ein Extraktor, der beide Formen annimmt, ist gegen beide Stände abgesichert.
- Was es kostet: Ein Entwickler, grob ein bis zwei Wochen bis zum produktiven Client inklusive Backfill, Retry und Monitoring – die API-Oberfläche ist klein, die Zeit geht in die Normalisierung der Identifier, die Consent-Behandlung und die Deduplizierungslogik.
- Das Ergebnis: Conversions, die Adblocker, Browser-Restriktionen und abgebrochene Sessions überstehen, dazu einen Deduplizierungsschlüssel, der verhindert, dass Browser-Tag und Server denselben Kauf doppelt zählen.
Die zeitliche Dringlichkeit ergibt sich aus einer einzigen Randbedingung. Ein Aufschub bricht nichts, und das UET-Tag im Browser arbeitet exakt weiter wie bisher. Was ein Aufschub kostet, ist Messqualität bei genau den Conversions, die der Browser nie meldet – und weil eventTime innerhalb der letzten sieben Tage liegen muss, lässt sich eine Lücke nicht rückwirkend schließen, sobald sie älter als eine Woche ist. Diese eine Randbedingung spricht für einen frühen Start: Jede Woche Aufschub ist eine Woche, die sich nie mehr senden lässt.
1. Warum server-seitige Conversions bei Microsoft jetzt ein Thema sind
Server-seitige Conversion-APIs sind als Gattung nichts Neues. Neu ist der Stand der Dokumentation, gegen den sich implementieren lässt. Der Integrationsleitfaden trägt das Dokumentendatum 04.08.2026 – sechs Tage alt, während dieser Text entsteht – und ist eine komplette Neufassung, keine Kosmetik. Die Referenzseite zur Operation für den Auth Key wurde einen Tag früher aktualisiert, am 03.08.2026. Wenn zwei zusammengehörige Seiten innerhalb eines Tages bewegt werden, hat sich meist auch die Oberfläche dahinter bewegt – dann lohnt sich eine erneute Lektüre auch bei Seiten, deren Inhalt als bekannt gilt.
Der praktische Treiber ist schlichter als jedes Plattform-Narrativ. Der Browser meldet nur einen Teil der Conversions. Eine Conversion, die in einem Checkout mit Adblocker stattfindet, in einer Session, die endet, bevor die Bestätigungsseite rendert, in einem nativen App-Wrapper oder Stunden später im Callcenter, ist eine Conversion, die das UET-Tag nie zu Gesicht bekommt. Die Bestelldatenbank sieht sie alle. Die Conversions API ist die Leitung zwischen dem System, in dem die Bestellungen erfasst sind, und dem System, das die Gebote optimiert.
Es gibt eine zweite, verwandte Entwicklung, die zur Einordnung gehört, ohne dass sich schon darauf bauen ließe. Die Release Notes vom Mai 2026 haben den MSClickIdPerformanceReport eingeführt, der Performance auf Ebene der einzelnen Click-ID ausweist und sich damit gegen einen eigenen msclkid-Bestand joinen lässt. Seine Spalte ConversionsQualified ist als Double typisiert. Der Grund, das als Preview und nicht als Fundament zu behandeln: Auf der Seite steht „Not everyone has this feature yet” – und zwar zweimal. Das ist ein Pilot, keine allgemeine Verfügbarkeit. Eine Planung damit ist möglich, eine Abhängigkeit davon nicht.
2. Der technische Vertrag: Endpoint, Authentifizierung, Pflichtfelder
Der Vertrag ist klein genug, um ihn im Kopf zu behalten. Es gibt einen Endpoint, https://capi.uet.microsoft.com/v1/{tagId}/events, und die Tag-ID steht im Pfad, nicht im Body. Wer mehrere UET-Tags betreibt – ein verbreitetes Muster, wenn ein Konto mehrere Marken oder Märkte bedient –, spricht damit mit mehreren verschiedenen URLs, und der Client braucht die Tag-ID als vollwertigen Parameter, nicht als Konstante.
Authentifiziert wird über ein Bearer Token im Authorization-Header. Kein Signieren, kein Timestamp-Header, kein Hash über den Request-Body. Das Token gehört zum Tag, also ist auch das Token-Management pro Tag zu denken: ein Secret je Tag-ID, gespeichert und rotiert je Tag-ID.
TAG_ID=123456789
AUTH_KEY="$(cat /etc/uet/authkey-${TAG_ID})" # aus dem lokalen Secret Store
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
Ein Request transportiert bis zu 1000 Events. Die eventTime jedes Events muss innerhalb der letzten sieben Tage liegen. Jedes Event sollte eine eventId zur Deduplizierung sowie einen Wert für adStorageConsent mitführen. Nutzerbezogene Identifier werden auf Kleinschreibung normalisiert und anschließend mit SHA-256 gehasht.
Ein Wort zur Quellenlage gehört an diese Stelle, denn es trägt weiter als jedes Codebeispiel. Die in diesem Artikel genannten Felder sind diejenigen, die die Quellen ausdrücklich festlegen. Die Feldnamen, die eine konkrete Conversion beschreiben – der Goal Name, der Umsatzwert, die Währung –, stammen aus der jeweiligen Tag-Konfiguration und aus der Feldtabelle im Integrationsleitfaden selbst. Maßgeblich ist diese Tabelle; Feldnamen aus einem Blogbeitrag, auch aus diesem hier, sind es nicht. Dasselbe gilt für Fehlercodes und Rate Limits: Die Quellen, auf die sich dieser Artikel stützt, nennen sie nicht, also erfindet dieser Artikel sie auch nicht. Im Client wird geloggt, was der Endpoint tatsächlich zurückgibt, und die Retry-Strategie entsteht aus dem beobachteten Verhalten in der eigenen Umgebung, nicht aus einer geratenen Zahl.
3. Der Auth Key und die Angaben in Leitfaden und Referenz
Vor dem Release im Mai 2026 wurde das CAPI-Bearer-Token über die Oberfläche von Microsoft Advertising abgerufen und von Hand herauskopiert. Für ein einzelnes Tag ist das praktikabel. Für ein Team mit elf Tags, einer Rotationsrichtlinie für Secrets und einem Bereitschaftsdienst, der sich um zwei Uhr nachts nicht durch eine Web-UI klicken soll, ist es das nicht mehr. Die Campaign-Management-Operation GetUetTagAuthKey liefert das Token für ein gegebenes UET-Tag nun programmatisch – und genau diese Änderung macht den automatisierten Betrieb der Integration möglich.
Die beiden Quellen beschreiben diesen Aufruf unterschiedlich. Der Integrationsleitfaden zeigt ihn mit einem Request-Body {"TagId": 123456789} und einer verschachtelten Antwort der Form {"TagAuthKey": {"AuthKey": "..."}}. Die Referenzseite zu GetUetTagAuthKey definiert etwas anderes: Das Request-Element heißt UetTagId, das Response-Element UetTagAuthKey und ist ein flacher String.
Beide Beschreibungen lassen sich nicht gleichzeitig umsetzen, und das Fehlerbild ist unspezifisch. Ein Parser, der dem Leitfaden folgt, greift nach TagAuthKey["AuthKey"]. Gegen eine Antwort in der Form, die die Referenz beschreibt, wirft dieser Parser eine Exception – bei einem Aufruf, der in Wahrheit erfolgreich war. Der Stacktrace zeigt auf die JSON-Verarbeitung, das Symptom liest sich als „es kam kein Key zurück”, und die naheliegende Reaktion ist eine Prüfung von Account-IDs, Customer-IDs und API-Berechtigungen. Diese Suche bleibt ergebnislos: Der Aufruf war in Ordnung, abweichend war das Schema im Leitfaden.
Die Lösung besteht darin, sich gar nicht erst festzulegen. Ein Extraktor, der beide Formen akzeptiert, und ein Log, das festhält, welche Form tatsächlich eintrifft, zeigen, welches Dokument für das jeweilige Konto gerade zutrifft.
import logging
log = logging.getLogger(__name__)
def extract_auth_key(response):
"""Beide dokumentierten Formen der GetUetTagAuthKey-Antwort annehmen.
Leitfaden : {"TagAuthKey": {"AuthKey": "..."}} (verschachtelt)
Referenz : {"UetTagAuthKey": "..."} (flacher String)
"""
# Flache Form, wie in der Operationsreferenz definiert.
flat = response.get("UetTagAuthKey")
if isinstance(flat, str) and flat:
log.info("auth key: flat shape (reference)")
return flat
# Verschachtelte Form, wie im Integrationsleitfaden gezeigt.
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
# Manche Wrapper liefern ein Objekt zurueck, kein dict.
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"
)
Die Request-Seite verdient dieselbe Behandlung. Lässt der SOAP- oder REST-Wrapper eine Benennung des Request-Elements zu, wird UetTagId gesendet, wie in der Referenz definiert – mit einem Codekommentar, der festhält, dass der Leitfaden es TagId nennt. Wird der Aufruf wegen eines unbekannten Elements rundheraus abgelehnt, steht das Ergebnis nach dreißig Sekunden fest, statt Gegenstand einer Vermutung zu bleiben.
4. Deduplizierung: Wie UET-Tag und Server-Event zueinanderfinden
Sobald Conversions vom Server gesendet werden, kommen die meisten davon auch vom Browser. Das ist kein Fehler, der wegzukonstruieren wäre – beide Wege sind erwünscht, weil jeder Fälle abdeckt, die der andere verpasst. Zu vermeiden ist allein ein Kauf, der doppelt gezählt wird. Der Mechanismus dafür ist eventId: Über dieses Feld werden der browserseitige UET-Hit und der serverseitige Hit dedupliziert.
Die Regel, die das trägt, ist eine Regel über die eigene Anwendung, nicht über die API. Der Identifier wird einmal erzeugt, und zwar von dem System, dem das Event gehört, und unverändert an beide Transportwege übergeben. In der Praxis heißt das: Das Backend erzeugt die ID, wenn die Bestellung entsteht, rendert sie in die Seite, damit das UET-Tag sie senden kann, und speichert sie zur Bestellung, damit der Server-Client später denselben Wert schicken kann.
Alle Fehlerbilder sind Varianten davon, die ID zweimal zu erzeugen. Ein Zufallswert, der beim Seitenaufbau in JavaScript entsteht, und ein zweiter Zufallswert aus dem Batch-Job werden nie zusammenpassen. Ein Wert, der aus einer Session-ID abgeleitet ist, passt nicht, wenn der Nutzer in einer anderen Session konvertiert. Ein Wert, der aus der Bestellnummer abgeleitet ist, ist stabil, eindeutig und übersteht Retries – und genau das ist erforderlich, denn Retries sind der zweite Grund, warum Deduplizierung wichtig ist. Wenn der Batch-Job nach einem Timeout einen Chunk erneut sendet, ist die identische eventId das, was daraus keine zweite Conversion werden lässt.
- Einmal erzeugen:
eventIdleitet sich aus etwas ab, das die Bestellung ohnehin besitzt, damit dasselbe Event immer dieselbe ID ergibt. - Durchreichen, nie neu erzeugen: Template und Batch-Job lesen beide den gespeicherten Wert; keiner von beiden berechnet einen eigenen.
- Über Retries stabil halten: Ein wiederholter Batch trägt die identischen IDs, sonst wird aus dem Retry eine Doppelzählung.
- Speichern: Die ID gehört zum Bestelldatensatz, denn sie wird für den Abgleich gebraucht, wenn die Zahlen auseinanderlaufen.
5. Normalisierung, Hashing und Consent
Nutzerbezogene Identifier werden nicht im Klartext gesendet. Das dokumentierte Verfahren besteht aus zwei Schritten in fester Reihenfolge: zuerst auf Kleinschreibung normalisieren, dann mit SHA-256 hashen. Die Reihenfolge ist nicht verhandelbar, denn Hashing ist nicht case-insensitiv. Anna@example.com und anna@example.com ergeben völlig unabhängige Digests, und eine Verwechslung an dieser Stelle wirft keinen Fehler – sie erzeugt stillschweigend einen Hash, der auf der Gegenseite nie zu irgendetwas passen wird. Der Effekt bleibt unbemerkt: Die Pipeline meldet Erfolg, und die Match Rate liegt still und leise nahe null.
import hashlib
def hash_identifier(value):
"""Erst kleinschreiben, dann SHA-256, wie die Doku es vorgibt.
Das Abschneiden umgebender Leerzeichen ist defensive Hygiene
gegen die eigene Speicherschicht; dokumentiert sind die beiden
Schritte Kleinschreibung + 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")
Jede weitere Bereinigung pro Feld – die Kanonisierung von Telefonnummern, der Umgang mit Plus-Adressierung in E-Mails, die Behandlung von Namen mit diakritischen Zeichen – liegt im Ermessen des implementierenden Teams. Die Quellen legen Kleinschreibung und SHA-256 fest. Ein länderspezifisches Telefonformat legen sie nicht fest, also nimmt dieser Artikel auch keines an. Tragfähig ist eine einmal festgelegte Regel, die auf Browser- und Serverseite identisch angewendet und schriftlich festgehalten wird.
Der Consent reist im Feld adStorageConsent mit dem Event mit und nimmt den Wert "G" für erteilt und "D" für verweigert an. Daraus folgen zwei Entwurfsentscheidungen. Erstens muss der Wert den Consent-Zustand zum Zeitpunkt der Conversion abbilden, nicht den Zustand zum Zeitpunkt, an dem der Batch-Job läuft – der Bestelldatensatz muss ihn also persistieren und darf ihn nicht später nachschlagen. Zweitens wird „unbekannt” wie „verweigert” behandelt. Hat der Consent-Speicher zu einer Bestellung keine Antwort, wird "D" gesendet. Ein fehlender Datensatz, der standardmäßig als erteilt gewertet wird, bleibt im Dashboard unsichtbar und fällt erst im Audit auf.
6. Der Client im Produktivbetrieb: Batches, Sieben-Tage-Fenster, Wiederaufnahme
Drei Randbedingungen prägen den Client: 1000 Events pro Request, eventTime innerhalb der letzten sieben Tage und keinerlei dokumentierte Hinweise zu Rate Limiting oder Fehlercodes. Die ersten beiden sind harte Grenzen, um die herum entworfen wird. Die dritte bedeutet, dass der Client so gebaut sein muss, dass er aus dem lernt, was er beobachtet, und nicht aus dem, was angenommen wurde.
Das Sieben-Tage-Fenster ist die Randbedingung mit der größten Wirkung auf den Betrieb. Das Fenster setzt eine Obergrenze dafür, wie lange eine Pipeline ausfallen darf, bevor Daten endgültig verloren sind. Ein Job, der an einem Freitag stillschweigend ausfällt und erst am übernächsten Montag auffällt, hat bereits Events jenseits jeder Rettung verloren. Das Fenster begrenzt außerdem den initialen Backfill: Zum Start lassen sich die letzten sieben Tage Historie senden und kein Tag mehr. Der Starttermin ist entsprechend zu planen – einen Nachholdurchlauf im dritten Monat gibt es nicht.
from datetime import datetime, timedelta, timezone
MAX_BATCH = 1000
WINDOW = timedelta(days=7)
# Kleiner Sicherheitspuffer, damit ein Event waehrend eines Retry
# nicht mitten im Flug verfaellt. An eigener Latenz ausrichten.
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):
"""Chunks in API-Groesse liefern, Abgelaufenes verwerfen."""
chunk = []
for event in events:
if not within_window(event.event_time):
# Mitzaehlen. Eine steigende Zahl heisst: Pipeline haengt.
yield_expired(event)
continue
chunk.append(event)
if len(chunk) >= MAX_BATCH:
yield chunk
chunk = []
if chunk:
yield chunk
Die Wiederaufnahme setzt auf der eigenen Datenbank auf, nicht auf einem Cursor, den die API vielleicht anbietet. Am Bestelldatensatz steht eine Spalte für den Sendestatus – pending, sent, expired, failed –, aus der der Job liest und in die er zurückschreibt. Dann bleibt ein Absturz mitten im Lauf folgenlos: Der nächste Lauf greift genau die Zeilen, die nie bestätigt wurden, und weil eventId stabil ist, ist das erneute Senden einer Zeile, deren Bestätigung unterwegs verloren ging, harmlos.
- Offene Events nach
eventTimesortiert auswählen, älteste zuerst, damit die dem Verfall am nächsten stehenden zuerst hinausgehen. - Alles, was bereits außerhalb des Fensters liegt, verwerfen und separat zählen, statt es von der API ablehnen zu lassen.
- In Chunks von höchstens 1000 Events aufteilen, senden und den Chunk erst nach einem bestätigten Erfolg als gesendet markieren.
- Bei Fehlern zurückstufen, die tatsächliche Antwort wortgetreu loggen und die Zeilen für den nächsten Lauf offen lassen.
- Alarm auslösen, sobald die Zahl abgelaufener Events einen zuvor festgelegten Schwellwert überschreitet – dieses Signal zeigt beginnenden Datenverlust an.
Zum Thema Retries: Weil die hier verfügbare Dokumentation weder Fehlercodes noch Rate Limits aufzählt, bleiben Annahmen darüber, welche Fehler wiederholbar sind, besser unverdrahtet. Ein Einstieg ist exponentielles Backoff bei Transportfehlern und bei jeder nicht erfolgreichen Antwort, dazu ein vollständiges Log des Bodys; die Strategie verfeinert sich, sobald eine Woche echter Antworten aus dem eigenen Konto vorliegt. Ein fest eingebautes „Retry bei 429″ bezieht sich auf ein Rate-Limit-Verhalten, das bis dahin nicht beobachtet wurde.
7. Monitoring: Welche Kennzahlen den Zustand der Integration anzeigen
Eine CAPI-Integration fällt leise aus. Es gibt keine Beschwerde über einen kaputten Checkout, sondern ein langsames Abdriften der Zahlen, das sechs Wochen später auffällt. Das Monitoring muss deshalb bewusst gesetzt werden – und der größte Teil davon lebt in der eigenen Datenbank, nicht in einem Anbieter-Dashboard.
-- Taegliche Gesundheit der Sende-Pipeline. Tabellen- und Spalten-
-- namen sind Platzhalter fuer den lokalen Order-/Event-Speicher.
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;
Fünf Signale sind eine Alarmierung wert. Abgelaufene Events oberhalb von null heißen, dass die Pipeline hinterherhinkt und Daten verloren gehen; dieses Signal hat die höchste Priorität. Sendeverzug ist der Frühindikator für dasselbe Problem – beobachtet wird der durchschnittliche Abstand zwischen eventTime und dem Sendezeitpunkt, mit einer Alarmschwelle lange vor Erreichen der sieben Tage. Identifier-Abdeckung, also der Anteil der Events, die überhaupt einen gehashten Identifier tragen, bricht an dem Tag ein, an dem ein Checkout-Formular oder eine Consent-Voreinstellung geändert wird; ein plötzlicher Sprung dort ist eine Codeänderung, keine Marktverschiebung. Consent-Verteilung, das Verhältnis von "G" zu "D", bewegt sich normalerweise langsam; ein Sprung bedeutet, dass das Consent-Tool sein Verhalten geändert hat. Erfolgsquote der Batches zeigt, ob der Endpoint annimmt, was gesendet wird, und gehört auf dasselbe Dashboard wie der Rest, auch wenn sie die naheliegendste Kennzahl ist.
Der Abgleich mit der Plattformseite ist das letzte Stück, und dafür sind Daten auf Klick-Ebene der nächste Schritt. Der Vergleich der gesendeten Menge mit den ausgewiesenen Conversions zeigt, ob die Deduplizierung greift: Liegt der Plattformwert spürbar über der Vereinigungsmenge aus Browser- und Server-Events, passt die eventId nicht zusammen. Der MSClickIdPerformanceReport ist das naheliegende Werkzeug für diesen Vergleich, weil er sich über die Click-ID gegen den eigenen msclkid-Bestand joinen lässt und ConversionsQualified eine numerische Vergleichsspalte liefert. Zu berücksichtigen bleibt, was seine eigene Seite zweimal sagt – noch hat nicht jeder dieses Feature. Der Abgleich ist deshalb so zu bauen, dass er sauber auf den aggregierten Vergleich zurückfällt, wenn der Report für das jeweilige Konto nicht verfügbar ist.
Fazit
Zur Integration gehören ein Token-Abruf, ein Normalisierer, ein Batcher und eine Statusspalte. Der Endpoint nimmt einen Pfad je Tag, ein Bearer Token und bis zu tausend Events auf einmal auf. Die aufwendigeren Teile liegen außerhalb der API – sie bestehen darin, zu entscheiden, wo eventId entsteht, den Consent-Zustand zu dem Zeitpunkt zu persistieren, zu dem er gilt, und dafür zu sorgen, dass Kleinschreibung ausnahmslos vor SHA-256 passiert.
Der Ertrag sind die Conversions, die der Browser nie gemeldet hat, und ein Gebotssignal, das die Bestelldatenbank abbildet statt nur den Teil davon, der die Reise durch einen Browser überstanden hat. Das Sieben-Tage-Fenster ist der Grund, dieses Vorhaben zu terminieren statt zu vertagen: Ungesendete Historie, die älter als eine Woche ist, lässt sich nicht mehr übermitteln – der Wert der Integration ist also dadurch begrenzt, wie früh sie zu laufen beginnt.
Offen bleibt der Stand der Dokumentation selbst. Stand 10.08.2026 beschreiben der Integrationsleitfaden und die Referenz zu GetUetTagAuthKey unterschiedliche Request-Elemente und unterschiedliche Antwortformen für dieselbe Operation, und beide Seiten wurden innerhalb der letzten Woche aktualisiert. Dem trägt ein toleranter Parser Rechnung, dazu ein Log der tatsächlich erhaltenen Form und eine erneute Prüfung beider Seiten vor dem nächsten Release – die Seiten sind in Bewegung. Die Primärquellen sind der Integrationsleitfaden zur UET Conversion API, die Referenz zur Operation GetUetTagAuthKey und die Release Notes von Microsoft Advertising zu den Änderungen vom Mai 2026. Alles, was nicht auf diesen Seiten steht – Fehlercodes, Rate Limits, Retry-Semantik –, ist in der eigenen Umgebung zu messen, und dieser Artikel hat diese Lücken bewusst offen gelassen, statt sie mit einer plausibel klingenden Vermutung zu füllen.