Tutorial: Eine GA4-Collect-Anfrage Parameter für Parameter lesen

Inhalt
Ein GA4-Treffer ist eine einzige HTTP-Anfrage, und alles, was die Property über diesen Moment je erfahren wird, steht in ihrer Abfragezeichenfolge. Sechzig Parameter, alle auf zwei oder drei Zeichen abgekürzt, keiner davon in der Oberfläche erklärt.
Diese Kürzel lesen zu können lohnt sich aus einem Grund: Es ist die einzige Stelle, an der sichtbar wird, was der Browser tatsächlich gesendet hat. Jeder Bericht, jede Vorschau und jede Einwilligungsanzeige liegt hinter dieser Anfrage – und ein Wert, der hier fehlt, wurde vom Browser nie gesendet; nur ein dazwischengeschalteter Servercontainer kann ihn noch ergänzen.

Die Anfrage finden
Die Anfrage geht an /g/collect, entweder direkt zu Google oder an den Servercontainer, sofern einer im Einsatz ist. Im Netzwerkbereich des Browsers reduziert ein Filter auf collect die Liste auf genau diese Treffer.
https://www.google-analytics.com/g/collect
?v=2&tid=G-AB12CD34>m=45je55h0v9182736&_p=1737041234567
&cid=1234567890.1737041234&ul=de-de&sr=2560x1440&_s=2
&sid=1737041234&sct=4&seg=1&dl=https%3A%2F%2Fshop.example%2Fkasse
&dt=Kasse&dr=https%3A%2F%2Fwww.google.com%2F&en=purchase
&ep.payment_type=card&epn.value=129.9&cu=EUR&_et=4312
&pr1=idSKU-42~nmStuhl~caMoebel~pr64.95~qt2&gcs=G111
Zwei praktische Hinweise dazu, wo sie sich versteckt. Kleine Treffer reisen als GET, die Parameter stehen dann in der Adresse; grössere wechseln auf POST, und dann trägt die Adresse nur einen Teil, der Rest sitzt im Anfragekörper. Und mehrere Ereignisse lassen sich in einem POST bündeln, eines je Zeile – ein Körper mit drei Zeilen sind drei Treffer, nicht einer.
Eine Anfrage, die gar nicht erscheint, ist selbst ein Befund, und dafür gibt es drei übliche Ursachen: Die Einwilligung fehlt und das Tag hält zurück, ein Werbeblocker hat das Skript entfernt, oder das Tag hat nie ausgelöst. Diese drei trennt der Tag-Debugger, nicht diese Ansicht.
Die Parameter, die kennzeichnen
Die erste Gruppe beantwortet, wer sendet und an welche Property. Diese Parameter stehen auf jedem Treffer und ändern sich selten.
| Parameter | Bedeutung |
|---|---|
| v=2 | Protokollfassung – 2 ist GA4, 1 war Universal Analytics |
| tid | Mess-ID der Zielproperty |
| cid | Client-ID, der Wert aus dem _ga-Cookie ohne seinen Vorsatz |
| sid | Sitzungs-ID – die Epochensekunde des Sitzungsbeginns |
| sct | Zahl der Sitzungen dieses Clients |
| seg | 1, sobald die Sitzung als interagiert gilt, davor 0 |
| _p | Zufallszahl je Seitenaufbau, bündelt die Treffer einer Seite |
| _s | Zähler innerhalb des Seitenaufbaus – der erste Treffer ist 1 |
Zwei davon sind nützlicher, als sie aussehen. Die Sitzungs-ID ist ein Zeitstempel und sagt damit genau, wann die Sitzung begann – eine Sitzung, die ständig neu startet, ist hier sichtbar, bevor ein Bericht es zeigt. Und _s macht Lücken auffällig: Eine Seite, deren Treffer von 1 auf 3 springen, hat unterwegs einen verloren.
Die Parameter, die die Seite beschreiben
Die zweite Gruppe ist der Zusammenhang, und dort entstehen die meisten falschen Werte, denn diese Parameter kann ein Tag überschreiben.
dl ist die Seitenadresse und kommt prozentkodiert an; aus ihr entstehen der Seitenpfad und jeder Abfrageparameter, den GA4 später ausweist. dr ist der Verweis und bleibt bei direktem Einstieg leer. dt ist der Dokumenttitel, genommen im Augenblick des Auslösens – weshalb eine Einzelseitenanwendung, die vor dem Titelwechsel feuert, den Titel der vorigen Seite meldet.
ul ist die Browsersprache und sr die Bildschirmauflösung. Beide kommen aus dem Browser und sind die zwei Felder, die einen automatisierten Besucher am häufigsten verraten: eine Auflösung von 800×600 zusammen mit einer englischen Spracheinstellung auf einem deutschen Shop ist ein Muster und keine Person.
Hier statt in einem Bericht zu prüfen lohnt sich eines: ob dl Parameter trägt, die in einer Analyse nichts zu suchen haben. Alles hinter dem Fragezeichen landet in der Seitendimension, und ein Formular, das eine Mailadresse in die Adresse schreibt, sendet sie zuerst hierher.
Das Ereignis und seine Parameter
Die dritte Gruppe ist das, was tatsächlich geschehen ist, und sie folgt einer einfachen Benennungsregel.
en=purchase der Ereignisname
ep.payment_type=card Ereignisparameter, Text
epn.value=129.9 Ereignisparameter, Zahl
up.plan=premium Nutzereigenschaft, Text
upn.credits=40 Nutzereigenschaft, Zahl
_et=4312 Interaktionszeit in Millisekunden seit dem letzten Treffer
cu=EUR Währung
Der Unterschied zwischen ep. und epn. ist der, der am meisten Zeit kostet, wenn er falsch steht. Eine als Text gesendete Zahl landet in einer Textdimension, lässt sich nicht summieren und nachträglich nicht in eine Kennzahl verwandeln – und nichts meldet einen Fehler, denn ein Textparameter mit dem Inhalt 129.9 ist völlig gültig.
Die Interaktionszeit ist je Treffer aufgelaufen, nicht je Sitzung: Jede Anfrage trägt die Millisekunden seit der vorigen. Eine Seite, die hier durchweg 0 sendet, wird nicht angesehen – oder etwas setzt den Zähler zurück.
Die E-Commerce-Daten in einem Feld
Artikel bekommen nicht je einen eigenen Parameter. Sie werden in pr1, pr2 und so fort gepackt, ein Feld je Artikel, mit Zwei-Buchstaben-Kürzeln und einer Tilde als Trenner.
pr1=idSKU-42~nmStuhl~caMoebel~pr64.95~qt2~brNordholz~vaEiche
| Kürzel | GA4-Feld | Kürzel | GA4-Feld |
|---|---|---|---|
| id | item_id | pr | price |
| nm | item_name | qt | quantity |
| br | item_brand | ds | discount |
| ca | item_category | cp | coupon |
| c2 … c5 | item_category2 … 5 | ln | item_list_name |
| va | item_variant | lp | index |
Drei Dinge werden prüfbar, sobald das lesbar ist. Ob jeder Artikel ein id trägt – ein Artikel ohne wird stillschweigend verworfen. Ob pr eine reine Zahl ist: Ein Preis, der als 64,95 mit Komma oder mit einem Währungszeichen ankommt, ist keine Zahl, und der Umsatz bleibt leer. Und ob die Summe aus Preis mal Menge zu epn.value passt, denn beide werden unabhängig voneinander gesendet, und eine Abweichung zwischen ihnen ist in keinem Bericht sichtbar.
Die Zahl der Artikel hat eine Obergrenze, die sich leicht erreichen lässt. Eine Anfrage hat eine Längenbeschränkung, und ein Warenkorb mit zweihundert Zeilen überschreitet sie – GA4 wechselt dann auf POST, und darüber hinaus wird gekürzt. Ein Kauf, dessen Artikelliste in den Berichten kürzer ist als im Shop, ist fast immer genau das.
Die Einwilligungsfelder
Die letzte Gruppe ist kurz und entscheidet mehr als der Rest zusammen.
gcs=G111 ad_storage erteilt, analytics_storage erteilt
gcs=G100 beides abgelehnt
gcs=G101 ad_storage abgelehnt, analytics_storage erteilt
gcd=13t3t3t3t5 die Voreinstellungen vor der Entscheidung
Die beiden Ziffern hinter G1 sind Werbespeicher und Analysespeicher in dieser Reihenfolge, 1 für erteilt und 0 für abgelehnt. Ein Treffer mit G100 ist ein Ping ohne Cookie: Er zählt in die Modellierung, schreibt aber keine Kennung, und die Client-ID darin entsteht je Anfrage neu, statt gespeichert zu werden.
Das Feld zum Gegenlesen heisst gcd und hält fest, wie die Voreinstellungen lauteten. Ein Container, dessen Voreinstellungen als erteilt ankommen, obwohl das Banner noch nicht beantwortet wurde, ist eine Fehlkonfiguration, die sich nur hier zeigt – die Berichte sehen normal aus, denn es werden ja Daten erhoben.
Eine letzte Gegenprobe dauert zehn Sekunden und beendet eine ganze Klasse von Streitgesprächen: die Seite mit abgelehnter Einwilligung neu laden und nach der Anfrage sehen. Geht ein Treffer mit gcs=G100 hinaus, arbeitet der Consent Mode wie vorgesehen. Geht überhaupt nichts hinaus, wird das Tag vollständig blockiert – ein anderer Aufbau mit anderen Berichten, und es lohnt sich zu wissen, welcher von beiden vorliegt.
Fragen und Antworten
Beweist der Status 204 im Netzwerkbereich, dass GA4 den Treffer angenommen hat?
Nein. Die Sammelstelle antwortet mit 204 No Content und meldet keine Prüfung zurück: Ein Treffer mit einer als Text gesendeten Zahl oder mit einem Artikel ohne id erhält dieselbe Antwort wie ein fehlerfreier. Was die Property daraus gemacht hat, zeigen erst DebugView oder der Echtzeitbericht.
Woran entscheidet sich, ob ein Parameter als ep. oder als epn. gesendet wird?
Am JavaScript-Typ des Werts im Moment des Auslösens, nicht an seinem Inhalt. Eine Zahl wird zu epn., eine Zeichenkette zu ep., auch wenn sie nur aus Ziffern besteht.
Der Fehler liegt deshalb meist an der Quelle des Werts. Eine Datenschichtvariable gibt den Typ weiter, mit dem die Seite ihn geschoben hat; value: '129.9' in Anführungszeichen wird zu ep.value. Werte, die aus der Seite selbst gelesen werden, etwa aus einem DOM-Element oder aus der URL, sind immer Text. Ebenso wird ein Feld im GA4-Tag, das neben der Variable weiteren Text enthält, zur Zeichenkette. Eine Umwandlung mit Number() in einer eigenen JavaScript-Variable behebt das, solange der Text einen Dezimalpunkt trägt; Number('64,95') ergibt NaN.
Was zeigt der Netzwerkbereich, wenn ein Servercontainer dazwischengeschaltet ist?
Nur die erste Hälfte des Wegs. Der Browser sendet an die Adresse des Servercontainers, und genau diese Anfrage erscheint im Netzwerkbereich, mit denselben Kürzeln wie oben. Was der Servercontainer daraus macht und an GA4 weitergibt, geschieht zwischen zwei Servern und ist im Browser nicht zu sehen.
Dazwischen kann sich einiges ändern. Ein serverseitiges Tag kann Parameter ergänzen, überschreiben oder entfernen, etwa Werte aus dem Backend anfügen oder Felder mit personenbezogenen Daten streichen. Die Regel, ein hier fehlender Wert sei nie gesendet worden, gilt dann für den Browser, nicht aber für die Property: Der Container kann einen Wert ergänzen, den der Browser nie gesendet hat, und einen streichen, den er gesendet hat.
Die zweite Hälfte zeigt der Vorschaumodus des Servercontainers. Er listet zu jeder eingehenden Anfrage den Client, der sie angenommen hat, die ausgelösten Tags und die ausgehenden HTTP-Anfragen samt Parametern. Erst der Vergleich beider Seiten klärt, ob ein falscher Wert aus dem Browser stammt oder im Container entstanden ist.
Praxiskontrolle: mehrere Collect-Requests vergleichen
Der GA4-Parameter-Analyser kann mehrere Browser-Collect-Requests gemeinsam untersuchen. Je Zeile wird eine URL oder ein URL-kodierter Query-/Body-String eingetragen. Gehören Parameter zur gemeinsamen URL eines POST-Requests, macht das separate Feld für gemeinsame Parameter diesen Kontext in jeder Zeile sichtbar.
Die Übersicht zeigt Ereignisnamen, Mess-IDs und wiederholte Parameterschlüssel. Im Vergleich stehen nur Unterschiede: Ein fehlender Schlüssel ist etwas anderes als ein Schlüssel mit leerem Wert. Verschiedene Ereignistypen enthalten naturgemäß unterschiedliche Parameter; eine Abweichung allein belegt deshalb keinen Trackingfehler. Wiederholte Schlüssel bleiben in ihrer ursprünglichen Reihenfolge erhalten. Das Werkzeug behauptet nicht, welches Vorkommen der Empfänger verwendet.
Werte werden einmal dekodiert und als Text dargestellt, auch wenn sie wie HTML aussehen. Die optionale CSV enthält die dekodierten Werte und ist nicht anonymisiert. Damit hilft der Analyser beim Untersuchen einer unerwarteten Seitenadresse oder eines Parameters, ist aber kein vollständiger Detektor für personenbezogene Daten. Ein unauffälliges Ergebnis belegt keine personenbezugsfreie Implementierung.
Kein eingefügter Request wird erneut abgespielt oder hochgeladen. Das Werkzeug beschreibt die Eingabe, nicht deren Annahme durch Google. Die tatsächliche Erfassung lässt sich gegebenenfalls über Google DebugView prüfen. Die Querydekodierung folgt den URL-Formkodierungsregeln; gepackte Artikelsegmente werden nur heuristisch aufgeschlüsselt. Für JSON-Nutzdaten des Measurement Protocol ist der separate Validator vorgesehen.