# GA4 Auditor - Full content dump
Generated for LLM crawlers. Site description: Audit-Tool für Google Analytics 4 Properties.
## GA4 einrichten - Schritt für Schritt + die häufigsten Setup-Fehler
- URL: https://ga4-auditor.dev/de/blog/ga4-einrichten
- lang: de
- updated: 2026-06-26
- description: GA4 verständlich einrichten - ohne Technik-Studium: Property, Datenstream, GTM, Consent Mode v2 und die wichtigste Frage zum Schluss - kommen deine Daten wirklich sauber an?
Google Analytics 4 ist schnell installiert - aber „installiert" heißt nicht
„misst richtig". Und genau das ist das teure Missverständnis: Du triffst
Marketing-Entscheidungen auf Basis von Zahlen, die niemand je geprüft hat.
Budget wird umgeschichtet, Kampagnen werden abgeschaltet, Reportings landen im
Management - und darunter liegen Daten, in denen ein Drittel des Traffics als
`(not set)` verbucht ist oder jede Bestellung doppelt zählt.
Dieser Guide führt dich durch die GA4-Einrichtung so, wie ein Marketing-Team
sie wirklich braucht: zuerst die Frage, was du überhaupt messen willst, dann
das saubere, datenschutzkonforme Setup - und am Ende der Schritt, den fast alle
Anleitungen überspringen: **prüfen, ob die Daten stimmen.** Du brauchst dafür
kein Entwickler-Wissen. Wo es technisch wird, verlinken wir in die Tiefe und
bleiben hier auf der Was-und-Warum-Ebene.
## Bevor du startest: Was willst du eigentlich messen?
Der häufigste Fehler passiert vor dem ersten Klick in GA4: einfach „alles
tracken" und hoffen, dass die Erkenntnisse von selbst kommen. Das Ergebnis ist
ein überladenes Konto, in dem niemand mehr die drei Zahlen findet, die das
Geschäft wirklich bewegen.
Dreh die Reihenfolge um und schreib **vor** der Technik ein Mini-Messkonzept.
Ein einfaches Satzmuster reicht:
> Als **[Rolle]** möchte ich **[diese Auswertung]**, um **[diese Entscheidung]**
> treffen zu können.
Zum Beispiel: „Als Marketing-Leiterin möchte ich sehen, welcher Kanal
Newsletter-Anmeldungen bringt, um das Budget umzuschichten." Aus solchen Sätzen
ergeben sich automatisch deine **Key Events** (früher: Conversions) und die
Berichte, die du brauchst - und alles andere darfst du bewusst weglassen.
Datensparsamkeit ist hier kein Verzicht, sondern Fokus: weniger Rauschen,
klarere Entscheidungen, und nebenbei ein Datenschutz-Pluspunkt.
Halte das Konzept in einer simplen Tabelle fest (Rolle, Frage, Event, Priorität).
Diese Liste ist später dein Prüfmaßstab: Wenn GA4 steht, kontrollierst du genau
diese Punkte - und nicht „irgendwas sieht ja nach Daten aus".
## Was ist GA4 - und was kostet es?
Wenn du von Universal Analytics kommst, ist die wichtigste Umstellung im Kopf:
GA4 denkt nicht mehr in **Sitzungen und Seitenaufrufen**, sondern in
**Ereignissen (Events)**. Jeder Seitenaufruf, jeder Klick, jeder Kauf ist ein
Event mit Parametern. Das klingt technisch, hat aber einen praktischen Vorteil:
Du misst Interaktionen über Website und App hinweg in einer einheitlichen Logik.
Die Struktur von GA4 lässt sich wie ein **Aktenschrank** denken:
- **Konto** = der Aktenschrank (meist dein Unternehmen).
- **Property** = eine Schublade darin (meist eine Website oder App).
- **Datenstream** = die einzelne Akte, die die Daten tatsächlich hereinträgt.
Diese Hierarchie hilft dir später bei Rechten und Datentrennung - eine Property
pro Marke/Website ist die saubere Faustregel.
**Und die Kostenfrage**, weil sie fast immer aufkommt:
| Variante | Kosten | Für wen |
|---|---|---|
| GA4 Standard | kostenlos | praktisch alle Websites und kleinen bis mittleren Shops |
| GA4 360 | ab ~50.000 USD/Jahr | Enterprise mit sehr hohem Datenvolumen / SLAs |
| BigQuery-Export | meist kostenlos, ab hohem Volumen nutzungsabhängig | Rohdaten-Analysen, Data-Teams |
| Consent-Tool (CMP) | 0 - mehrere 100 €/Jahr | rechtskonformes Einwilligungs-Management |
| Agentur-Setup | ~990-4.000 € einmalig | wenn Setup + Conversions + Shop ausgelagert werden |
Kurz: Das Tool selbst kostet nichts. Geld fließt erst in Consent-Management, in
optionale Rohdaten und - falls gewünscht - in die Dienstleistung, es richtig
aufzusetzen.
## GA4 einrichten: Schritt für Schritt
Jetzt das eigentliche Setup. Du brauchst nur ein Google-Konto.
1. **Konto und Property anlegen.** Melde dich unter analytics.google.com an,
öffne unten links die **Verwaltung** (Zahnrad). Lege - falls noch nicht
vorhanden - ein **Konto** an (z. B. dein Firmenname) und darin eine
**Property** mit Name, Zeitzone und Währung. Wähle die Zeitzone bewusst:
Sie bestimmt, wann ein „Tag" in deinen Berichten beginnt und endet.
2. **Web-Datenstream erstellen.** GA4 fragt nach der Plattform - wähle **Web**,
trage deine vollständige URL und einen Stream-Namen ein und klicke auf
**Stream erstellen**.
3. **Mess-ID kopieren.** In der Stream-Übersicht steht oben rechts die
**Mess-ID** (beginnt mit `G-`). Sie ist der Schlüssel, der deine Website
später mit dieser Property verbindet - du brauchst sie im nächsten Schritt.
Das war die Grundlage. Wie der Mess-Code jetzt auf deine Seite kommt, hängt
davon ab, womit deine Website gebaut ist - und genau dafür ist die nächste
Entscheidung da.
## GTM oder direkter Code - welcher Weg für wen?
Es gibt drei übliche Wege, GA4 mit der Website zu verbinden. Für die meisten
Marketing-Teams ist Weg 3 (GTM) auf Dauer der beste.
### GA4 in WordPress, Shopify oder Shopware einrichten
In CMS und Shops trägst du die Mess-ID meist nur in ein Plugin-Feld ein -
schnell und einsteigerfreundlich, bei Consent und Conversions aber oft
eingeschränkt. In **WordPress** (z. B. via Site Kit oder GA-Plugins),
**Shopify** (native GA4-Integration), **Shopware** oder **TYPO3** reicht dafür
die **Mess-ID** aus der Stream-Übersicht.
### GA4 ohne Google Tag Manager einrichten - geht das?
Ja - du kannst GA4 per Google-Tag (gtag.js) direkt in den `
` einbinden,
ohne GTM. Für ein einzelnes Tag reicht das; sobald Consent-Logik und weitere
Tools dazukommen, wird GTM aber schnell übersichtlicher. Du kopierst das
Tag-Snippet aus den Stream-Details in den `` jeder Seite - das
funktioniert, wird aber unübersichtlich, sobald mehr als ein Tool dazukommt.
### Wie binde ich GA4 über den Google Tag Manager ein?
Im GTM legst du ein **Google-Tag** an, hinterlegst die **Mess-ID** (G-) und
löst es über den Trigger **Initialisierung - alle Seiten** aus - genau hier
setzt das Consent-Handling an (weiter unten mehr dazu). **Empfohlen** ist GTM,
weil du danach **alle** Tags, Trigger und das Consent-Handling zentral
verwaltest, ohne den Quellcode erneut anzufassen. Genau diese Trennung von
Website und Tracking macht dich als Marketing-Team unabhängig von der
Entwicklung.
> **Faustregel:** Wenn du heute nur GA4 willst, morgen aber vielleicht Google
> Ads, Meta-Pixel oder ein Newsletter-Tool ergänzt, richte gleich GTM ein. Du
> sparst dir das spätere Umbauen.
## Consent-konform einrichten (DSGVO)
In Deutschland und der EU darf GA4 **erst nach aktiver Einwilligung** laden -
ein vorab gesetztes Analytics-Cookie ist ein Datenschutzverstoß. Praktisch
heißt das: Ein **Consent-Tool (CMP)** wie Cookiebot, Usercentrics oder CCM19
steuert das Banner, und deine Tags feuern erst, wenn der Besucher zustimmt.
Der heutige Standard dafür heißt **Consent Mode v2**. Er übergibt Google die
Einwilligungssignale - inklusive der seit 2024 verpflichtenden Signale
`ad_user_data` und `ad_personalization`. Sind die nicht korrekt gesetzt, setzen
Remarketing und Conversion-Modelling still aus, ohne Fehlermeldung. Das ist
einer der häufigsten und teuersten Fehler im DACH-Raum.
Weil hier viel schiefgehen kann und es schwer von außen sichtbar ist, haben wir
das in einem eigenen Leitfaden vertieft: Wie du
[Consent Mode v2 in Minuten prüfst](/de/blog/ga4-consent-mode-v2), inklusive
der sechs Consent-Signale und der typischen Stolperfallen. Für die Einrichtung
merke dir drei Regeln:
1. Default-Consent **vor** dem ersten Tag-Aufruf auf `denied` setzen.
2. Nach der Banner-Entscheidung **sofort** auf `granted` aktualisieren - ohne
Seiten-Reload.
3. Eine Datenschutzerklärung pflegen und den **AVV** mit Google abschließen.
## Die wichtigsten Grundeinstellungen
Diese Häkchen entscheiden über die Qualität deiner Daten - und werden trotzdem
am häufigsten vergessen:
| Einstellung | Warum sie wichtig ist |
|---|---|
| **Key Events (Conversions)** definieren | Ohne sie misst du Traffic, aber keine Ergebnisse. Markiere die Events aus deinem Messkonzept als Key Event. |
| **Enhanced Measurement** prüfen | Automatische Events (Scrolls, Klicks, Datei-Downloads, Site-Search) sind praktisch - aber nicht alle sinnvoll. Bewusst aktivieren, nicht blind alles anlassen. |
| **Data Retention** hochsetzen | Standard sind 2 Monate; für Explorationen auf **14 Monate** stellen (Verwaltung > Datenerhebung > Datenaufbewahrung). |
| **Interne Zugriffe filtern** | Eigene Besuche verzerren die Zahlen. Eigene IP als internen Traffic definieren und ausschließen. |
| **Unerwünschte Referrer ausschließen** | Payment- und Login-Domains nicht als Quelle zählen lassen - sonst verschwinden deine echten Kanäle. |
Brauchst du eigene Felder - etwa Login-Status, Artikelkategorie oder
Kundensegment? Dann lohnt ein Blick auf
[Custom Dimensions in GA4](/de/blog/custom-dimensions-ga4). Für den Start
reichen aber die Punkte oben.
## GA4 testen - woran sehe ich, dass es läuft?
Öffne den DebugView (Verwaltung > DebugView) und den Echtzeitbericht: Nach
erteilter Einwilligung muss pro Seite genau ein `page_view` ankommen und jede
Conversion ihr Event. Das ist der Schritt, der über „Daten" und „verlässliche
Daten" entscheidet - und der in fast jeder Anleitung fehlt. Zwei Werkzeuge
brauchst du:
- **Echtzeitbericht** (Berichte > Echtzeit): Öffne deine Seite in einem zweiten
Tab - tauchst du dort als aktiver Nutzer auf, kommt grundsätzlich etwas an.
- **DebugView** (Verwaltung > DebugView): Hier siehst du **einzelne Events mit
ihren Parametern** in Echtzeit. Aktivierst du den Debug-Modus (z. B. über die
GTM-Vorschau oder die Tag-Assistant-Erweiterung), prüfst du Event für Event,
ob `page_view`, deine Key Events und die Consent-Signale korrekt feuern.
Geh dabei deine Liste aus dem Messkonzept durch - eine kleine
**Go-Live-Checkliste**:
1. Feuert auf jeder Seite genau **ein** `page_view` (nicht null, nicht zwei)?
2. Löst jede definierte Conversion das passende Event aus?
3. Stehen die Consent-Signale **vor** der Zustimmung auf `denied` und danach
auf `granted`?
4. Kommen nach Ablehnung **keine** personenbezogenen Daten durch?
Erst wenn diese vier Punkte sitzen, ist GA4 wirklich „eingerichtet". Wer das
nicht Event für Event von Hand prüfen will, lässt die Property in Minuten
gegen die echten Daten abgleichen - [Property jetzt prüfen](/de/). Welche
Konfigurations- und Datenqualitäts-Checks darüber hinaus sinnvoll sind, zeigt
die [komplette GA4-Audit-Checkliste](/de/blog/features-testkatalog).
## Die häufigsten Setup-Fehler (die ein Audit findet)
Die meisten Tracking-Probleme melden sich nicht mit einer Fehlermeldung - sie
zeigen sich erst Wochen später als unplausible Zahlen im Reporting. Das sind die
Klassiker, die wir in echten Audits am häufigsten sehen:
| Fehler | Symptom im Reporting |
|---|---|
| Tag doppelt eingebunden (GTM **und** Plugin/gtag.js) | doppelte Events, überhöhte Nutzer- und Seitenzahlen |
| Tracking durch Consent blockiert | starker Datenverlust direkt nach dem Banner |
| Domain-/Cross-Domain-Setup fehlt | [Self-Referrals](/de/blog/self-referrals-cross-domain-tracking) - die eigene Domain als Quelle |
| UTM-/Kampagnen-Disziplin fehlt | [(not set) als Quelle](/de/blog/not-set-quellen-analyse) und nicht zugeordnete Sitzungen |
| Channel-Regeln unvollständig | [Unassigned Traffic](/de/blog/unassigned-traffic-ga4) statt klarer Kanäle |
| Thank-You-Page neu geladen | [doppelte Transaktionen](/de/blog/duplicate-transactions-deduplication) im Umsatz |
| Auto-Tagging/Verknüpfung lückenhaft | [Google Ads ohne Zuordnung](/de/blog/gclid-attribution-bug) trotz `gclid` |
Jede dieser Zeilen kostet im Zweifel echtes Geld - weil falsche Zahlen zu
falschen Budget-Entscheidungen führen. Statt blind zu vertrauen, kannst du dein
Setup gegen die Realität prüfen: Der [GA4 Auditor](/de/) liest deine
Konfiguration über die offizielle Admin-API und gleicht sie mit den real
ankommenden Daten ab - doppelte Events, durch Consent blockiertes Tracking,
`(not set)` und fehlende Conversions werden in Minuten sichtbar.
## Fortgeschritten: Cross-Domain und BigQuery
Zwei Themen, die fast jede Einstiegs-Anleitung auslässt - die aber genau dann
wichtig werden, wenn dein Setup wächst:
- **Cross-Domain-Tracking** - Hast du mehrere Domains (z. B. Marketing-Site und
Shop auf einer anderen Domain) oder einen externen Checkout, musst du die
Domains in den Datenstrom-Einstellungen als zusammengehörig definieren. Sonst
startet bei jedem Domainwechsel eine neue Sitzung und deine eigene Domain
taucht als Quelle auf. Details und Behebung stehen im Artikel zu
[Self-Referrals und Cross-Domain-Tracking](/de/blog/self-referrals-cross-domain-tracking).
- **BigQuery-Export** - GA4 kann seine **Rohdaten** kostenlos nach Google
BigQuery exportieren. Für Marketing-Teams ist das der Schritt von
„Standardberichten" zu „beliebigen Auswertungen ohne Sampling" - und die
Grundlage für tiefe Datenqualitäts-Checks. Wann sich das lohnt, erklärt der
[BigQuery-Export für GA4](/de/blog/bigquery-export-fuer-ga4).
Beides ist optional für den Start - aber gut zu wissen, bevor du das Setup als
„fertig" abhakst.
## Erste Auswertungen
Sind Daten da und geprüft, geht es ans Auswerten. Drei Ebenen:
1. **Standardberichte** (Berichte) - Akquisition, Engagement, Monetarisierung.
Ideal für den schnellen Überblick und das Reporting.
2. **Explorationen** (Werbung/Explorationen) - frei baubare Analysen, z. B.
Trichter (Funnel) oder Pfade. Hier zahlt sich die auf 14 Monate erhöhte
Datenaufbewahrung aus.
3. **Looker Studio** - für Dashboards, die Stakeholder ohne GA4-Login lesen
können. GA4 lässt sich als Datenquelle direkt anbinden.
Mach dir früh eine **monatliche Routine**: dieselben drei, vier Kennzahlen aus
deinem Messkonzept, immer im gleichen Format. Reporting wird dadurch
vergleichbar - und du merkst sofort, wenn Tracking bricht.
## Einrichten ist der Anfang, nicht das Ziel
GA4 einzurichten ist in einer halben Stunde getan. Es **richtig** einzurichten -
mit klarem Messkonzept, sauberem Consent und geprüften Daten - ist die Arbeit,
die den Unterschied macht. Denn jede Entscheidung, die du später aus diesen
Berichten ableitest, ist nur so gut wie die Daten darunter.
Der ehrlichste Test ist deshalb nicht „Sehe ich Zahlen?", sondern „Stimmen
diese Zahlen?". [Prüf deine Property jetzt](/de/) oder geh die
[komplette Audit-Checkliste](/de/blog/features-testkatalog) durch - bevor das
nächste Reporting auf wackeligen Daten steht.
## Verwandte Themen
- [Consent Mode v2 in GA4 prüfen](/de/blog/ga4-consent-mode-v2) - datenschutzkonform tracken.
- [GA4-Audit-Checkliste](/de/blog/features-testkatalog) - alle Checks auf einen Blick.
- [(not set) in GA4 - Quellenanalyse](/de/blog/not-set-quellen-analyse)
- [Self-Referrals und Cross-Domain-Tracking](/de/blog/self-referrals-cross-domain-tracking)
- [BigQuery-Export für GA4](/de/blog/bigquery-export-fuer-ga4)
- [Custom Dimensions in GA4](/de/blog/custom-dimensions-ga4)
---
## Custom Dimensions in GA4: einrichten und auditieren
- URL: https://ga4-auditor.dev/de/blog/custom-dimensions-ga4
- lang: de
- updated: 2026-06-16
- description: Was sind Custom Dimensions in GA4, wie richtest du sie ein und welche Fehler findet ein Audit? Event- vs. user-scoped, Limits und Cardinality erklärt.
Benutzerdefinierte Dimensionen (Custom Dimensions) sind der Hebel, mit dem aus
generischem GA4-Tracking eine wirklich auswertbare Datenbasis wird. Standardmäßig
weiß GA4 nicht, ob ein Besucher eingeloggt war, welche Artikelkategorie er sich
angesehen hat oder ob er Premium-Kunde ist. Genau solche Informationen machst du
mit Custom Dimensions sichtbar - in den Berichten, in den Explorationen und im
BigQuery-Export.
Der Haken: Custom Dimensions funktionieren nur, wenn zwei Dinge zusammenkommen -
das Senden des Parameters **und** ein Setup-Schritt in der GA4-Oberfläche. Wird
einer davon vergessen, bleibt die Dimension leer. Deshalb gehören sie zu den
häufigsten Fehlerquellen, die wir in Audits sehen. Dieser Artikel erklärt
Schritt für Schritt, was Scopes praktisch bedeuten, wie die Einrichtung wirklich
abläuft und woran typische Setups scheitern.
## Was sind Custom Dimensions in GA4?
**Custom Dimensions (benutzerdefinierte Dimensionen) sind eigene, selbst
definierte Attribute, mit denen du zusätzliche Event- oder Nutzer-Eigenschaften
in GA4 auswertbar machst** - also Informationen, die GA4 standardmäßig nicht
erfasst. Typische Beispiele: `article_category` (Artikelkategorie),
`login_status` (eingeloggt ja/nein) oder `membership_level` (Mitgliedsstufe).
Sobald eine Custom Dimension eingerichtet ist, kannst du sie überall nutzen, wo
GA4 Dimensionen anbietet: als primäre oder sekundäre Dimension in
Standardberichten, als Spalte oder Filter in Explorationen, beim Erstellen von
Zielgruppen (Audiences) und als eigene Spalte im BigQuery-Export.
**Dimension vs. Metrik:** Eine *Dimension* beschreibt ein Merkmal (das „Was" -
z. B. die Artikelkategorie), eine *Metrik* ist ein messbarer Zahlenwert (das
„Wie viel" - z. B. die Anzahl Käufe). Custom Dimensions erweitern also die
**Merkmale** deiner Daten, nicht die Kennzahlen.
## Die drei Scopes - und was sie praktisch bedeuten
Der Scope (Geltungsbereich) entscheidet, *worauf* sich ein Wert bezieht: auf ein
einzelnes Ereignis, auf den Nutzer insgesamt oder auf einen einzelnen
E-Commerce-Artikel. Diese Entscheidung triffst du einmal bei der Registrierung -
und sie lässt sich später **nicht mehr ändern**. Deshalb lohnt es sich, den
Scope vorab zu verstehen.
### Event-scoped: ein Wert pro Ereignis
Eine event-scoped Dimension beschreibt **ein einzelnes Event**. Der Wert gilt
genau für dieses eine Ereignis und kann sich beim nächsten Event wieder ändern.
Praktisches Beispiel: Beim Event `view_item` schickst du den Parameter
`article_category` mit dem Wert „Sneaker". Sieht sich derselbe Nutzer als
Nächstes eine Jacke an, sendet das nächste `view_item` den Wert „Jacken". In den
Berichten kannst du nun z. B. die Conversion-Rate je Artikelkategorie auswerten
oder „Aufrufe nach Kategorie" als Tabelle bauen.
In der UI taucht eine event-scoped Dimension überall auf, wo du Ereignisse
analysierst - etwa als sekundäre Dimension im Bericht „Ereignisse" oder als
Aufschlüsselung in einer freien Exploration. Event-Scope ist der häufigste Fall;
nimm ihn immer dann, wenn die Eigenschaft zum *Moment* der Aktion gehört.
### User-scoped: ein Wert, der am Nutzer „klebt"
Eine user-scoped Dimension beschreibt den **Nutzer über Sitzungen hinweg**. Der
Wert wird einmal als User Property gesetzt und bleibt am Nutzer haften, bis er
überschrieben wird - auch in späteren Besuchen.
Praktisches Beispiel: `membership_level` mit dem Wert „gold". Egal, welche Events
der Nutzer auslöst, GA4 ordnet ihm „gold" zu, bis sich seine Stufe ändert. Damit
beantwortest du Fragen wie „Wie verhalten sich Gold-Mitglieder im Vergleich zu
Free-Nutzern?" - über mehrere Sitzungen hinweg.
In der Praxis nutzt du user-scoped Dimensionen vor allem zum **Bilden von
Zielgruppen** und für nutzerbezogene Auswertungen. Wichtig: User Properties
werden anders gesetzt als Event-Parameter (dazu unten beim Setup) - das ist eine
der häufigsten Verwechslungen.
### Item-scoped: ein Wert pro Produkt
Eine item-scoped Dimension beschreibt **einen einzelnen Artikel innerhalb eines
E-Commerce-Events**. Sie lebt im `items`-Array, das du bei Events wie
`add_to_cart` oder `purchase` mitsendest.
Praktisches Beispiel: Du ergänzt jedes Produkt im Warenkorb um `material` =
„Leder" oder `lieferzeit` = „24h". So lässt sich der Umsatz nach Material oder
Lieferzeit aufschlüsseln - zusätzlich zu den eingebauten Item-Feldern wie
`item_category`. Item-Scope ist E-Commerce-spezifisch; in der Standard-Property
sind hier die wenigsten Slots verfügbar (10).
### Welchen Scope wählst du?
Eine einfache Faustregel:
- Gehört die Eigenschaft zum **Moment der Aktion**? → Event-Scope.
- Beschreibt sie den **Menschen dahinter** (dauerhaft)? → User-Scope.
- Beschreibt sie ein **einzelnes Produkt** im Warenkorb? → Item-Scope.
Bist du unsicher, ist Event-Scope meist die sichere Wahl. Eine falsch gewählte
Scope-Zuordnung lässt sich nur durch Löschen und Neuanlegen korrigieren - mit
neuem Namen und einem Datenbruch.
## Custom Dimension einrichten - Schritt für Schritt
Hier kommt der entscheidende Punkt, an dem die meisten Setups scheitern: Eine
Custom Dimension entsteht aus **zwei** Teilen. Der Parameter muss erstens mit dem
Event ankommen und zweitens in der Property **registriert** werden. Erst die
Registrierung macht aus einem rohen Parameter eine auswertbare Dimension. Ohne
diesen Setup-Schritt sammelt GA4 den Wert zwar (im Rohdaten-Export sichtbar),
zeigt ihn aber in **keinem** Standardbericht an.
### Schritt 1: Den Parameter zuverlässig senden
Zuerst muss der Wert überhaupt bei GA4 ankommen - bei jedem relevanten Event und
mit exakt dem Namen, den du später registrierst (Groß-/Kleinschreibung zählt).
Event-Parameter direkt über gtag.js:
```javascript
gtag('event', 'view_item', {
article_category: 'Sneaker'
});
```
Über den Google Tag Manager: Im GA4-Ereignis-Tag unter „Ereignisparameter" einen
Parameter `article_category` ergänzen und den Wert aus einer dataLayer-Variable
ziehen.
Eine User Property (für user-scoped Dimensionen) wird **anders** gesetzt - nicht
als Event-Parameter:
```javascript
gtag('set', 'user_properties', {
membership_level: 'gold'
});
```
Im GTM passiert das im Abschnitt „Nutzereigenschaften" des GA4-Tags. Diese
Trennung ist wichtig: Sendest du `membership_level` versehentlich als
Event-Parameter, lässt es sich nicht als user-scoped Dimension registrieren.
### Schritt 2: Die Dimension in GA4 registrieren (der Pflicht-Setup-Schritt)
Das ist der Schritt, der gern vergessen wird. So gehst du vor:
1. Öffne **Verwaltung** (Admin) und dort den Bereich **Datenanzeige >
Benutzerdefinierte Definitionen**.
2. Reiter **Benutzerdefinierte Dimensionen** → Button **Benutzerdefinierte
Dimensionen erstellen**.
3. Fülle die Felder:
- **Dimensionsname:** der sprechende Anzeigename in den Berichten, z. B.
„Artikelkategorie".
- **Bereich (Scope):** Ereignis, Nutzer oder Artikel - **jetzt** richtig
wählen, später nicht änderbar.
- **Beschreibung:** kurz dokumentieren, wofür die Dimension steht (hilft dem
Team und im Audit).
- **Ereignisparameter** bzw. **Nutzereigenschaft:** exakt den Parameternamen
eintragen, den du in Schritt 1 sendest (`article_category`). Tippfehler oder
abweichende Schreibweise sind hier der Klassiker-Fehler.
4. Speichern.
Beachte die Limits: 50 event-scoped, 25 user-scoped, 10 item-scoped in der
Standard-Property. Lege also nicht „auf Vorrat" an, sondern nur, was du
tatsächlich auswertest.
### Schritt 3: Prüfen, ob es funktioniert
- **Sofort:** Im **DebugView** (mit aktiviertem Debug-Modus bzw. GTM-Vorschau)
siehst du in Echtzeit, ob der Parameter mit dem Event ankommt und welchen Wert
er hat.
- **Nach 24-48 Stunden:** erscheinen die Werte in den Standardberichten und
Explorationen.
- **Wichtig:** Custom Dimensions wirken **nicht rückwirkend**. Erst ab dem
Zeitpunkt der Registrierung werden Werte befüllt - alles davor bleibt
`(not set)`. Registriere die Dimension daher *vor* einer wichtigen Kampagne,
nicht danach.
## Häufige Fehlerquellen - mit Beispielen
In Audits begegnen uns immer wieder dieselben Muster. Hier die typischen Fälle
mit konkreten Beispielen:
- **Gesendet, aber nie registriert.** Das Entwicklerteam schickt brav
`article_category` mit jedem `view_item` - aber niemand hat die Dimension in
GA4 angelegt. Im Bericht taucht sie gar nicht erst zur Auswahl auf. Der Wert
liegt nur im BigQuery-Export. *Lösung:* Schritt 2 nachholen.
- **Tippfehler / falsche Schreibweise.** Registriert ist `articleCategory`,
gesendet wird `article_category`. GA4 findet keine Übereinstimmung, die
Dimension bleibt vollständig `(not set)`. *Lösung:* Namen exakt angleichen
(inkl. Groß-/Kleinschreibung).
- **Falscher Scope.** `membership_level` wurde als **event-scoped** registriert
statt user-scoped. Folge: Du kannst damit keine sauberen Nutzer-Zielgruppen
bilden, und der Wert „springt", weil er nur am einzelnen Event hängt. *Lösung:*
als user-scoped neu anlegen, User Property korrekt setzen.
- **Hohe Cardinality.** Jemand legt `seiten_url_mit_parametern` als Custom
Dimension an - mit Tausenden eindeutigen Werten durch Query-Strings.
Oberhalb der Tageslimits fasst GA4 die Werte unter `(other)` zusammen, eine
Detailauswertung wird unmöglich. *Lösung:* Werte vorab gruppieren/normalisieren
(z. B. Pfad ohne Parameter).
- **Personenbezogene Daten (PII).** E-Mail-Adresse oder Telefonnummer landen als
Custom-Dimension-Wert in GA4 - ein Verstoß gegen die Google-Richtlinien und
ein Datenschutzproblem. *Lösung:* niemals PII als Parameter senden; im Zweifel
serverseitig entfernen.
- **Limit gesprengt / tote Slots.** Die 50 event-scoped Slots sind mit alten
Test-Dimensionen voll, eine neue wichtige Dimension lässt sich nicht mehr
anlegen. *Lösung:* registrierte, aber nie gesendete Dimensionen archivieren.
## Wie der GA4 Auditor das prüft
Der GA4 Auditor liest deine Custom Definitions über die Admin-API und gleicht
sie mit den real ankommenden Parametern aus dem BigQuery-Export ab. So siehst du
auf einen Blick: registrierte, aber leere Dimensionen (Schreibfehler oder nie
gesendet), gesendete, aber **nicht** registrierte Parameter (verschenktes
Potenzial), Scope-Konflikte sowie Dimensionen mit auffällig hoher Cardinality.
Statt manuell durch die Definitionen zu klicken, bekommst du die Lücken direkt
benannt. [Property jetzt prüfen](/de/).
## Verwandte Themen
- [GA4-Audit-Checkliste](/de/blog/features-testkatalog) - alle Config-Checks.
- [(not set) in GA4 - Quellenanalyse](/de/blog/not-set-quellen-analyse)
- [BigQuery-Export für GA4](/de/blog/bigquery-export-fuer-ga4) - Custom
Dimensions im Rohdaten-Export.
---
## Custom dimensions in GA4: setting up and auditing
- URL: https://ga4-auditor.dev/en/blog/custom-dimensions-ga4
- lang: en
- updated: 2026-06-16
- description: What are custom dimensions in GA4, how do you set them up and which mistakes does an audit find? Event- vs. user-scoped, limits and cardinality explained.
Custom dimensions are the lever that turns generic GA4 tracking into a genuinely
analysable data basis. By default GA4 does not know whether a visitor was logged
in, which article category they looked at or whether they are a premium customer.
Custom dimensions make exactly this kind of information visible - in reports, in
explorations and in the BigQuery export.
The catch: custom dimensions only work when two things come together - sending
the parameter **and** a setup step inside the GA4 interface. Forget one of them
and the dimension stays empty. That is why they are among the most common sources
of error we see in audits. This article explains, step by step, what scopes mean
in practice, how the setup really works and where typical setups go wrong.
## What are custom dimensions in GA4?
**Custom dimensions are your own, self-defined attributes that make additional
event or user properties analysable in GA4** - that is, information GA4 does not
capture by default. Typical examples: `article_category`, `login_status`
(logged in yes/no) or `membership_level`.
Once a custom dimension is set up, you can use it everywhere GA4 offers
dimensions: as a primary or secondary dimension in standard reports, as a column
or filter in explorations, when building audiences, and as a dedicated column in
the BigQuery export.
**Dimension vs. metric:** A *dimension* describes an attribute (the "what" -
e.g. the article category), a *metric* is a measurable number (the "how much" -
e.g. the number of purchases). So custom dimensions extend the **attributes** of
your data, not the metrics.
## The three scopes - and what they mean in practice
The scope determines *what* a value refers to: a single event, the user overall,
or a single e-commerce item. You make this decision once, when you register the
dimension - and it **cannot be changed** afterwards. That is why it pays to
understand the scope up front.
### Event-scoped: one value per event
An event-scoped dimension describes **a single event**. The value applies to
exactly that one event and can change again with the next event.
Practical example: on the `view_item` event you send the parameter
`article_category` with the value "Sneakers". If the same user looks at a jacket
next, the next `view_item` sends the value "Jackets". In reports you can now,
for example, analyse the conversion rate per article category or build a "views
by category" table.
In the UI, an event-scoped dimension shows up wherever you analyse events - for
instance as a secondary dimension in the "Events" report or as a breakdown in a
free-form exploration. Event scope is the most common case; use it whenever the
attribute belongs to the *moment* of the action.
### User-scoped: a value that sticks to the user
A user-scoped dimension describes the **user across sessions**. The value is set
once as a user property and stays attached to the user until it is overwritten -
including in later visits.
Practical example: `membership_level` with the value "gold". No matter which
events the user triggers, GA4 assigns them "gold" until their level changes.
This answers questions such as "how do gold members behave compared to free
users?" - across several sessions.
In practice you mainly use user-scoped dimensions for **building audiences** and
for user-level analysis. Important: user properties are set differently from
event parameters (see the setup section below) - one of the most common mix-ups.
### Item-scoped: one value per product
An item-scoped dimension describes **a single article inside an e-commerce
event**. It lives in the `items` array that you send with events like
`add_to_cart` or `purchase`.
Practical example: you add `material` = "leather" or `delivery_time` = "24h" to
each product in the cart. This lets you break revenue down by material or
delivery time - in addition to the built-in item fields such as `item_category`.
Item scope is e-commerce specific; the standard property offers the fewest slots
here (10).
### Which scope should you choose?
A simple rule of thumb:
- Does the attribute belong to the **moment of the action**? → event scope.
- Does it describe the **person behind it** (persistently)? → user scope.
- Does it describe a **single product** in the cart? → item scope.
If in doubt, event scope is usually the safe choice. A wrongly chosen scope can
only be fixed by deleting and recreating the dimension - with a new name and a
break in the data.
## Setting up a custom dimension - step by step
Here is the crucial point where most setups fail: a custom dimension is made of
**two** parts. The parameter must, first, arrive with the event and, second, be
**registered** in the property. Only the registration turns a raw parameter into
an analysable dimension. Without this setup step, GA4 does collect the value
(visible in the raw export) but shows it in **no** standard report.
### Step 1: Send the parameter reliably
First, the value has to reach GA4 at all - on every relevant event and with
exactly the name you register later (case matters).
Event parameter directly via gtag.js:
```javascript
gtag('event', 'view_item', {
article_category: 'Sneakers'
});
```
Via Google Tag Manager: in the GA4 event tag, add a parameter `article_category`
under "Event Parameters" and pull the value from a dataLayer variable.
A user property (for user-scoped dimensions) is set **differently** - not as an
event parameter:
```javascript
gtag('set', 'user_properties', {
membership_level: 'gold'
});
```
In GTM this happens in the "User Properties" section of the GA4 tag. This
distinction matters: if you accidentally send `membership_level` as an event
parameter, it cannot be registered as a user-scoped dimension.
### Step 2: Register the dimension in GA4 (the mandatory setup step)
This is the step that tends to be forgotten. Here is how:
1. Open **Admin** and go to **Data display > Custom definitions**.
2. Tab **Custom dimensions** → button **Create custom dimensions**.
3. Fill in the fields:
- **Dimension name:** the human-readable display name in reports, e.g.
"Article category".
- **Scope:** event, user or item - choose correctly **now**, it cannot be
changed later.
- **Description:** briefly document what the dimension stands for (helps the
team and the audit).
- **Event parameter** or **User property:** enter the exact parameter name
you send in step 1 (`article_category`). Typos or a different spelling are
the classic mistake here.
4. Save.
Mind the limits: 50 event-scoped, 25 user-scoped, 10 item-scoped in the standard
property. So do not create dimensions "just in case" - only what you actually
analyse.
### Step 3: Check that it works
- **Immediately:** in **DebugView** (with debug mode or GTM preview enabled) you
see in real time whether the parameter arrives with the event and what value
it has.
- **After 24-48 hours:** the values appear in standard reports and explorations.
- **Important:** custom dimensions do **not** work retroactively. Values are only
filled from the moment of registration onward - everything before stays
`(not set)`. So register the dimension *before* an important campaign, not
after.
## Common sources of error - with examples
In audits we keep seeing the same patterns. Here are the typical cases with
concrete examples:
- **Sent but never registered.** The dev team dutifully sends
`article_category` with every `view_item` - but nobody created the dimension
in GA4. It does not even appear in the report picker. The value only lives in
the BigQuery export. *Fix:* complete step 2.
- **Typo / wrong spelling.** Registered is `articleCategory`, sent is
`article_category`. GA4 finds no match, the dimension stays entirely
`(not set)`. *Fix:* align the names exactly (including case).
- **Wrong scope.** `membership_level` was registered as **event-scoped** instead
of user-scoped. Result: you cannot build clean user audiences with it, and the
value "jumps" because it only hangs off the individual event. *Fix:* recreate
it as user-scoped and set the user property correctly.
- **High cardinality.** Someone creates `page_url_with_parameters` as a custom
dimension - with thousands of distinct values due to query strings. Above the
daily limits GA4 groups the values under `(other)`, making a detailed analysis
impossible. *Fix:* group/normalise the values up front (e.g. path without
parameters).
- **Personally identifiable information (PII).** An email address or phone number
ends up as a custom dimension value in GA4 - a breach of Google's policies and
a data-protection problem. *Fix:* never send PII as a parameter; strip it
server-side if in doubt.
- **Limit exceeded / dead slots.** The 50 event-scoped slots are full of old
test dimensions, so a new important dimension can no longer be created.
*Fix:* archive registered but never-sent dimensions.
## How the GA4 Auditor checks this
The GA4 Auditor reads your custom definitions via the Admin API and reconciles
them with the parameters actually arriving from the BigQuery export. At a glance
you see: registered but empty dimensions (typos or never sent), sent but **not**
registered parameters (wasted potential), scope conflicts, and dimensions with
suspiciously high cardinality. Instead of clicking through the definitions
manually, the gaps are named for you. [Check your property now](/en/).
## Related topics
- [GA4 audit checklist](/en/blog/features-testkatalog) - all config checks.
- [(not set) in GA4 - source analysis](/en/blog/not-set-quellen-analyse)
- [BigQuery export for GA4](/en/blog/bigquery-export-fuer-ga4) - custom
dimensions in the raw data export.
---
## Unassigned Traffic in GA4: Ursachen finden und beheben
- URL: https://ga4-auditor.dev/de/blog/unassigned-traffic-ga4
- lang: de
- updated: 2026-06-01
- description: Was bedeutet Unassigned in GA4 und wie wirst du es los? Ursachen, Fix und die Abgrenzung zu (not set) - mit automatischer Prüfung im GA4 Auditor.
Ein wachsender Anteil deiner Sitzungen landet in GA4 unter „Unassigned"? Das
heißt nicht, dass die Daten fehlen - Google konnte die Quelle nur keiner
Kanalgruppe zuordnen. Im Akquisitions-Bericht sieht das aus wie ein blinder
Fleck. Diese Seite zeigt dir, woher Unassigned kommt und wie du es Quelle für
Quelle beseitigst.
## Was bedeutet „Unassigned" in GA4?
„Unassigned" ist die Auffangkategorie für Sitzungen, die GA4 keiner
Standard-Kanalgruppe (Direct, Organic Search, Paid Search, Referral, …)
zuordnen kann. Anders als bei `(not set)` ist eine Quelle vorhanden - sie
passt nur in keine der definierten Channel-Regeln. Ein hoher Unassigned-Anteil
verwässert jede Attribution.
## Häufige Ursachen
| Ursache | Symptom | Fix-Richtung |
|---|---|---|
| Ungültige `utm_medium`-Werte | Medium außerhalb der Channel-Definition | UTMs auf erkannte Werte vereinheitlichen |
| Fehlende UTM-Parameter | nur `source`, kein `medium` | Kampagnen-Links vollständig taggen |
| Consent-Lücke | Quelle wird vor Einwilligung nicht erfasst | Consent Mode v2 prüfen |
| Kaputtes Cross-Domain-Tracking | Self-Referral statt Originalquelle | Linker-Konfiguration korrigieren |
| Tag-Timing | Tag feuert vor dem Setzen der Quelle | Tag-Reihenfolge / `gtag`-Sequenz |
## So behebst du Unassigned Traffic
1. Filtere im Bericht auf `Session default channel group = Unassigned` und
splitte nach Quelle/Medium - so siehst du, welche Kampagnen betroffen sind.
2. Vereinheitliche die `utm_medium`-Werte auf das, was GA4 als Channel kennt
(`cpc`, `organic`, `referral`, `email`, …).
3. Prüfe [Consent Mode v2](/de/blog/ga4-consent-mode-v2) - fehlt die Quelle
schon vor der Einwilligung, hilft kein UTM.
4. Kontrolliere Cross-Domain- und Self-Referral-Probleme.
## „Unassigned" vs. „(not set)"
Beides sieht nach „kaputter Quelle" aus, hat aber verschiedene Wurzeln:
`(not set)` heißt, GA4 hat **gar keinen** Wert erhalten (Erfassungs- oder
Timing-Problem); „Unassigned" heißt, ein Wert ist da, lässt sich aber
**keiner Kanalgruppe** zuordnen. Die Detailanalyse zu fehlenden Werten steht
in der [(not set)-Quellenanalyse](/de/blog/not-set-quellen-analyse).
## Wie der Auditor das automatisch flaggt
Der GA4 Auditor prüft den Unassigned- und Direct-Anteil sowohl über die
Data-API (Live-Check) als auch auf Event-Level aus dem BigQuery-Export und
zeigt dir die wahrscheinlichste Ursache pro Quelle - statt nur die Zahl.
[Property jetzt prüfen](/de/).
## Verwandte Themen
- [(not set) in GA4 - Quellenanalyse](/de/blog/not-set-quellen-analyse)
- [Self-Referrals & Cross-Domain-Tracking](/de/blog/self-referrals-cross-domain-tracking)
- [GA4-Audit-Checkliste](/de/blog/features-testkatalog)
---
## Unassigned traffic in GA4: finding and fixing the causes
- URL: https://ga4-auditor.dev/en/blog/unassigned-traffic-ga4
- lang: en
- updated: 2026-06-01
- description: What does Unassigned mean in GA4 and how do you get rid of it? Causes, fix and the distinction from (not set) - with an automatic check in the GA4 Auditor.
A growing share of your sessions ends up under "Unassigned" in GA4? That
does not mean the data is missing - Google just could not assign the source
to any channel group. In the acquisition report this looks like a blind
spot. This page shows you where Unassigned comes from and how to eliminate
it source by source.
## What does "Unassigned" mean in GA4?
"Unassigned" is the catch-all category for sessions that GA4 cannot assign
to any default channel group (Direct, Organic Search, Paid Search,
Referral, …). Unlike with `(not set)`, a source is present - it just does
not fit any of the defined channel rules. A high Unassigned share dilutes
every attribution.
## Common causes
| Cause | Symptom | Fix direction |
|---|---|---|
| Invalid `utm_medium` values | medium outside the channel definition | standardise UTMs to recognised values |
| Missing UTM parameters | only `source`, no `medium` | tag campaign links completely |
| Consent gap | source not captured before consent | check Consent Mode v2 |
| Broken cross-domain tracking | self-referral instead of original source | fix linker configuration |
| Tag timing | tag fires before the source is set | tag order / `gtag` sequence |
## How to fix Unassigned traffic
1. Filter the report on `Session default channel group = Unassigned` and
split by source/medium - this shows you which campaigns are affected.
2. Standardise the `utm_medium` values to what GA4 knows as a channel
(`cpc`, `organic`, `referral`, `email`, …).
3. Check [Consent Mode v2](/en/blog/ga4-consent-mode-v2) - if the source is
already missing before consent, no UTM will help.
4. Check for cross-domain and self-referral problems.
## "Unassigned" vs. "(not set)"
Both look like a "broken source", but they have different roots:
`(not set)` means GA4 received **no value at all** (a capture or timing
problem); "Unassigned" means a value is present but cannot be assigned to
**any channel group**. The detailed analysis of missing values is in the
[(not set) source analysis](/en/blog/not-set-quellen-analyse).
## How the auditor flags this automatically
The GA4 Auditor checks the Unassigned and Direct share both via the Data
API (live check) and at event level from the BigQuery export and shows you
the most likely cause per source - instead of just the number.
[Check your property now](/en/).
## Related topics
- [(not set) in GA4 - source analysis](/en/blog/not-set-quellen-analyse)
- [Self-referrals & cross-domain tracking](/en/blog/self-referrals-cross-domain-tracking)
- [GA4 audit checklist](/en/blog/features-testkatalog)
---
## Doppelte Käufe in GA4 - warum sie entstehen und wie der Auditor sie findet
- URL: https://ga4-auditor.dev/de/blog/duplicate-transactions-deduplication
- lang: de
- updated: 2026-05-19
- description: Doppelte purchase-Events verfälschen Revenue-Reports. So erkennt der Auditor sie über Sekunden-Buckets - und so verhinderst du sie.
In den GA4-E-Commerce-Reports erscheint plötzlich der doppelte Umsatz für
dieselbe Bestellung. Drei Wochen später fragt das Reporting-Team, warum
die Order-Zahl nicht zum Shop-Backend passt. Doppelte
`purchase`-Events sind ein klassischer GTM-Bug - und einer, den der
Auditor in unter einer Minute auffinden kann.
## Was im Code passiert
Der Check in [`app/queries/checks/duplicate_events.sql`](app/queries/checks/duplicate_events.sql)
gruppiert Events in **Sekunden-Buckets** und markiert mehrfach gefeuerte
Events innerhalb derselben Session:
```sql
duplicates_marked AS (
SELECT *,
COUNT(*) OVER (
PARTITION BY session_id, user_pseudo_id, event_name, second_bucket
) AS duplicate_count,
ROW_NUMBER() OVER (
PARTITION BY session_id, user_pseudo_id, event_name, second_bucket
ORDER BY event_timestamp_micros ASC
) AS occurrence_number
FROM events_with_bucket
)
```
Die Bucket-Berechnung erfolgt vorher über
`TIMESTAMP_SECONDS(event_timestamp_micros / 1000000)`. Mehrere
`purchase`-Events innerhalb derselben Sekunde, gleicher Session und
gleicher `user_pseudo_id` werden als Duplikat markiert.
## Schwellenwerte
| Status | Bedingung |
|---|---|
| Grün | 0 Duplikate |
| Gelb | 1-5 Duplikate |
| Rot | >5 Duplikate oder >5 % der Purchases |
## Typische Ursachen
- **Double-Click am Checkout-Button** - Der Nutzer klickt schnell zweimal,
beide Klicks lösen einen Ajax-Call innerhalb derselben Sekunde aus.
- **GTM-Trigger feuert mehrfach** - Der `purchase`-Trigger ist nicht auf
`Once per Page` gesetzt, oder ein History-Change-Listener feuert ihn
zusätzlich noch einmal.
- **Plugin-Konflikt** - Ein E-Commerce-Plugin (z. B. WooCommerce GA4-Plugin)
sendet den Purchase parallel zu einem Custom-GTM-Tag.
- **Browser-Retry** - Bei Netzwerk-Latenz wiederholt der Browser den
Request, der Server verarbeitet beide Calls.
- **Universal-Analytics-Migration unvollständig** - Das alte UA-Snippet
läuft noch mit, parallel zum neuen GA4-Tag.
## So zeigt's der Auditor
Die Sektion `create_duplicate_transactions_section` in
[`app/components/dashboard/sections/ecommerce_transactions.py`](app/components/dashboard/sections/ecommerce_transactions.py)
liefert:
- **Warnung mit Anzahl und Umsatz-Impact** - wie viele Käufe sind doppelt,
wie viel Umsatz hängt daran?
- **Summary-Karten** für Duplikat-Anzahl und betroffene Transaction-IDs.
- **Detail-Tabelle** mit konkreten `transaction_id`, `event_timestamp`,
`purchase_revenue` und der Anzahl Wiederholungen.
Damit lässt sich nicht nur das *Ob*, sondern auch das *Wo* eingrenzen -
oft sind Duplikate auf wenige Trigger-Konfigurationen zurückführbar.
## So verhinderst du sie
1. **`transaction_id` als Dedup-Key in GA4 nutzen.** GA4 selbst dedupliziert
`purchase`-Events mit identischer `transaction_id` für eine begrenzte
Zeit, aber nicht zuverlässig - daher solltest du den Bug an der Quelle
beheben.
2. **GTM-Trigger auf `Once per Page` setzen** und sicherstellen, dass kein
parallele History-Change-Listener mit feuert.
3. **Plugin-Audit** - wenn dein Shop ein dediziertes E-Commerce-Plugin
hat, prüfe, ob es Purchases parallel zu deinem Custom-Tracking sendet.
4. **Idempotenz im Server-Side-Tagging** - wenn dein SST-Setup auf Retries
reagiert, sicherstellen, dass identische `transaction_id`-Calls
innerhalb von z. B. 60 Sekunden verworfen werden.
5. Im Auditor unter [E-Commerce-Checks](/de/hilfe/ecommerce-checks) nach
24 h erneut prüfen.
## Verwandte Themen
- Hilfeseite [E-Commerce-Checks im Detail](/de/hilfe/ecommerce-checks)
- Hilfeseite [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
- Blog [Wenn der `gclid` da ist - und Google Ads trotzdem nicht](/de/blog/gclid-attribution-bug)
---
## Duplicate purchases in GA4 - why they happen and how the auditor finds them
- URL: https://ga4-auditor.dev/en/blog/duplicate-transactions-deduplication
- lang: en
- updated: 2026-05-19
- description: Duplicate purchase events distort revenue reports. Here is how the auditor detects them via second buckets - and how you prevent them.
In the GA4 e-commerce reports, double the revenue suddenly appears for the
same order. Three weeks later the reporting team asks why the order count
does not match the shop backend. Duplicate `purchase` events are a classic
GTM bug - and one that the auditor can find in under a minute.
## What happens in the code
The check in [`app/queries/checks/duplicate_events.sql`](app/queries/checks/duplicate_events.sql)
groups events into **second buckets** and marks events fired multiple times
within the same session:
```sql
duplicates_marked AS (
SELECT *,
COUNT(*) OVER (
PARTITION BY session_id, user_pseudo_id, event_name, second_bucket
) AS duplicate_count,
ROW_NUMBER() OVER (
PARTITION BY session_id, user_pseudo_id, event_name, second_bucket
ORDER BY event_timestamp_micros ASC
) AS occurrence_number
FROM events_with_bucket
)
```
The bucket calculation happens beforehand via
`TIMESTAMP_SECONDS(event_timestamp_micros / 1000000)`. Multiple
`purchase` events within the same second, the same session and the same
`user_pseudo_id` are marked as a duplicate.
## Thresholds
| Status | Condition |
|---|---|
| Green | 0 duplicates |
| Yellow | 1-5 duplicates |
| Red | >5 duplicates or >5 % of purchases |
## Typical causes
- **Double-click on the checkout button** - the user clicks twice quickly,
both clicks trigger an Ajax call within the same second.
- **GTM trigger fires multiple times** - the `purchase` trigger is not set
to `Once per Page`, or a history-change listener fires it again on top.
- **Plugin conflict** - an e-commerce plugin (e.g. the WooCommerce GA4
plugin) sends the purchase in parallel with a custom GTM tag.
- **Browser retry** - on network latency the browser repeats the request,
the server processes both calls.
- **Incomplete Universal Analytics migration** - the old UA snippet still
runs alongside the new GA4 tag.
## How the auditor shows it
The `create_duplicate_transactions_section` section in
[`app/components/dashboard/sections/ecommerce_transactions.py`](app/components/dashboard/sections/ecommerce_transactions.py)
delivers:
- **Warning with count and revenue impact** - how many purchases are
duplicated, how much revenue depends on it?
- **Summary cards** for the duplicate count and affected transaction IDs.
- **Detail table** with concrete `transaction_id`, `event_timestamp`,
`purchase_revenue` and the number of repetitions.
This lets you narrow down not only the *whether*, but also the *where* -
often duplicates trace back to a few trigger configurations.
## How to prevent them
1. **Use `transaction_id` as the dedup key in GA4.** GA4 itself deduplicates
`purchase` events with an identical `transaction_id` for a limited time,
but not reliably - so you should fix the bug at the source.
2. **Set the GTM trigger to `Once per Page`** and make sure no parallel
history-change listener fires along with it.
3. **Plugin audit** - if your shop has a dedicated e-commerce plugin, check
whether it sends purchases in parallel with your custom tracking.
4. **Idempotency in server-side tagging** - if your SST setup reacts to
retries, make sure identical `transaction_id` calls within, say, 60
seconds are discarded.
5. In the auditor, check again after 24 h under
[E-commerce checks](/en/help/ecommerce-checks).
## Related topics
- Help page [E-commerce checks in detail](/en/help/ecommerce-checks)
- Help page [Event quality & PII hints](/en/help/event-qualitaet)
- Blog [When the `gclid` is there - and Google Ads still is not](/en/blog/gclid-attribution-bug)
---
## Wenn der gclid da ist - und Google Ads trotzdem nicht
- URL: https://ga4-auditor.dev/de/blog/gclid-attribution-bug
- lang: de
- updated: 2026-05-19
- description: Ein bekannter GA4-Bug: Sessions mit gültigem gclid landen als Organic oder Direct. So zeigt der Auditor das Problem auf Event-Level.
Du klickst in deiner Google-Ads-Kampagne. Der Klick führt mit Auto-Tagging
und gültigem `gclid` auf deine Site. Die Session läuft, der Nutzer
konvertiert - und in GA4 landet die Bestellung als `Organic Search` oder
`Direct`. Klingt nach einem Implementierungsfehler? Oft ist es einer,
manchmal aber auch ein dokumentierter GA4-Bug.
## Was im Code passiert
Der Check in [`app/queries/checks/google_ads_attribution.sql`](app/queries/checks/google_ads_attribution.sql)
klassifiziert jede Purchase-Session in eine von vier Klassen:
```sql
CASE
-- gclid vorhanden UND korrekt als Paid Search/Cross-network klassifiziert
WHEN gclid IS NOT NULL AND gclid != ''
AND (LOWER(session_default_channel) IN ('paid search', 'cross-network')
OR (LOWER(session_source) = 'google'
AND LOWER(session_medium) IN ('cpc', 'ppc', 'paidsearch')))
THEN 'gclid_attributed_ok'
-- gclid da, ABER falsch klassifiziert (der GA4-Bug)
WHEN gclid IS NOT NULL AND gclid != ''
AND (LOWER(session_default_channel) NOT IN ('paid search', 'cross-network')
OR session_default_channel IS NULL)
THEN 'gclid_misattributed'
-- Kein gclid, aber Channel = Paid Search (manuelles UTM, SA360)
WHEN (gclid IS NULL OR gclid = '') AND LOWER(session_default_channel) = 'paid search'
THEN 'paid_without_gclid'
ELSE 'no_gclid_other'
END AS gads_status
```
Die Klasse `gclid_misattributed` ist das Diagnose-Werkzeug: Sessions mit
gültigem `gclid`, die GA4 trotzdem nicht als Google-Ads-Traffic zählt.
## Schwellenwerte
| Status | Bedingung |
|---|---|
| Grün | 0 Misattribution |
| Gelb | 1-5 % der Google-Ads-Sessions |
| Rot | >5 % |
Bei einer mittleren Property entspricht das schnell hunderten falsch
zugeordneter Käufe - und damit einer signifikanten ROAS-Verzerrung.
## Warum landet `gclid` auf Organic oder Direct?
- **GA4-Default-Channel-Grouping-Bug** - In bestimmten Fällen wird `gclid`
vom Default-Channel-Grouping ignoriert, vor allem wenn parallel manuelle
UTMs gesetzt sind, die Google nicht als Paid-Search-Muster erkennt.
- **Session-Timeout zwischen Klick und Conversion** - Wenn der Nutzer
zwischen Klick und Kauf länger als 24 h inaktiv ist, kann der
`gclid`-Wert verloren gehen, je nach Cookie-Konfiguration.
- **gclid wird vor GTM erfasst** - Wenn eigener Code den `gclid` aus der
URL liest und in ein falsches Event-Feld schreibt, landet der Wert nicht
in dem Feld, das GA4 für Auto-Tagging-Auswertung nutzt.
- **Cross-Domain / Subdomain** - Beim Domain-Wechsel ohne Linker-Param
kann der URL-Parameter verloren gehen - das passende Symptom dazu
beschreibt der Blog [Self-Referrals - wenn deine eigene Domain als Quelle auftaucht](/de/blog/self-referrals-cross-domain-tracking).
- **Payment-Provider als Referrer** - Wenn der Checkout über
3D-Secure/SOFORT/PayPal läuft, kann die `gclid`-Quelle überschrieben
werden. Details im Blog
[Bank- und Payment-Provider als Referrer](/de/blog/payment-referrer-exclusions).
## So zeigt's der Auditor
Die Sektion `create_google_ads_attribution_section` in
[`app/components/dashboard/sections/ecommerce_gads.py`](app/components/dashboard/sections/ecommerce_gads.py)
liefert:
- Eine Summary-Karte pro `gads_status`-Klasse (mit Sessions, Käufen, Umsatz).
- Eine Time-Series-Auswertung nach Status (steigt das Problem über die Zeit?).
- Eine Detail-Tabelle der falsch klassifizierten Sessions mit
Landing-Page-URL und Session-Quelle.
So lässt sich das Problem nicht nur **erkennen**, sondern auch die Ursache
einkreisen - Landing-Page-Muster, Session-Source, Tagestrend.
## So gehst du vor
1. Im Auditor die **Google-Ads-Attribution-Sektion** öffnen und den Anteil
`gclid_misattributed` prüfen.
2. Sessions in der Detail-Tabelle nach Landing-Page gruppieren - wenn nur
bestimmte Pfade betroffen sind, liegt das Problem meist an einem
bestimmten Redirect.
3. **GA4-Setup prüfen**: Auto-Tagging in Google Ads aktiv? Auto-Tagging
in GA4-Property unter *Google Ads Linking* verbunden?
4. Bei Verdacht auf Cross-Domain-Verlust: In der GA4-Property unter
*Define internal domains* alle Subdomains eintragen und im GTM die
`gtag('config', ...)` mit `linker: {domains: [...]}` ergänzen.
5. Der Blog [E-Commerce-Attribution: Live API vs. BigQuery](/de/blog/attribution-live-api-vs-bigquery)
erklärt zusätzlich, warum Live-API und BigQuery für dieselbe Bestellung
unterschiedliche Channels zeigen können.
## Verwandte Themen
- Hilfeseite [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
- Blog [E-Commerce-Attribution: Live API vs. BigQuery](/de/blog/attribution-live-api-vs-bigquery)
- Blog [Self-Referrals - Cross-Domain-Tracking](/de/blog/self-referrals-cross-domain-tracking)
- Blog [Bank- und Payment-Provider als Referrer](/de/blog/payment-referrer-exclusions)
---
## „(not set)" in GA4 - wo das Auditing wirklich anfängt
- URL: https://ga4-auditor.dev/de/blog/not-set-quellen-analyse
- lang: de
- updated: 2026-05-19
- description: Wenn Page-Titles, Traffic-Quellen oder UTM-Parameter als (not set) erscheinen, sind die Reports schon wertlos. So zerlegt der Auditor das Problem.
`(not set)` ist das vielleicht häufigste Symptom in GA4-Reports - und
gleichzeitig das am häufigsten ignorierte. Wer einen Page-Title nicht
weiß, einen Channel nicht zuordnen kann oder eine `sessionSource`
verliert, hat im Reporting nichts mehr in der Hand. Der Auditor prüft
das auf zwei Ebenen.
Viele dieser Lücken entstehen schon bei der Installation: Wer GA4
[von Anfang an sauber einrichtet](/de/blog/ga4-einrichten), verhindert
einen Großteil der `(not set)`-Fälle von vornherein.
## Was im Code passiert
### Page-Title (BigQuery-Sicht)
Der Check in [`app/queries/checks/page_quality.sql`](app/queries/checks/page_quality.sql)
klassifiziert jeden Page-View in eine Status-Klasse:
```sql
CASE
WHEN page_title IS NULL OR page_title = '' OR page_title = '(not set)'
THEN 'not_set_page'
WHEN page_title LIKE '%404%' OR page_title LIKE '%not found%'
THEN 'error_page'
ELSE 'ok'
END AS page_status
```
### Traffic-Source (Data-API-Sicht)
Auf der Live-API-Seite prüft
[`app/services/ga4_api_check_service.py`](app/services/ga4_api_check_service.py)
den Anteil der Sessions mit `sessionSource = (not set)`:
```python
not_set_sessions = _safe_int(_get_single_metric_value(source_not_set_report))
share = (not_set_sessions / total_sessions) if total_sessions > 0 else 0.0
status_traffic = _evaluate_threshold(
share,
warning=THRESHOLDS["traffic_not_set_share"]["warning"], # 5 %
fail=THRESHOLDS["traffic_not_set_share"]["fail"], # 15 %
)
```
## Schwellenwerte (kombiniert)
| Check | Grün | Gelb | Rot |
|---|---|---|---|
| Page-Title `(not set)` | <1 % | 1-5 % | >5 % |
| `sessionSource = (not set)` | <5 % | 5-15 % | >15 % |
Die beiden Schwellen sind bewusst unterschiedlich: Ein `(not set)`-Page-Title
ist immer ein Tracking-Bug (jede Seite hat einen Titel), während eine
gewisse `(not set)`-Quote bei Traffic-Sources unvermeidbar ist
(z. B. direkte Adress-Eingaben).
## Typische Ursachen
- **``-Tag fehlt oder kommt zu spät** - Single-Page-Applications,
die den Titel erst nach dem ersten `page_view` über JavaScript setzen,
liefern dem GTM-Trigger einen leeren Wert.
- **UTM-Parameter fehlen** - Organische Sessions landen im Fallback,
sobald `utm_source` nicht durchgereicht wird. Newsletter-Klicks,
Social-Posts und Affiliate-Links ohne UTM landen alle hier.
- **No-Referrer-Policy im Browser** - Wenn die Site oder die
Werbeplattform `Referrer-Policy: no-referrer` setzt, sieht GA4 weder
Source noch Medium.
- **Bot-/Crawler-Traffic** - Suchmaschinen-Bots ohne User-Agent-Klassifikation
landen oft als `(not set)`.
- **Ungetaggte Affiliate-Links** - Partner setzen Links ohne UTM, der
Traffic landet als Direct oder `(not set)`.
## „(not set)" vs. „Unassigned" und „landing page (not set)"
Drei Begriffe, die oft verwechselt werden:
- **`(not set)`** - GA4 hat **gar keinen** Wert erhalten (Erfassungs- oder
Timing-Problem). Betrifft Page-Title, `sessionSource` und auch die
**Landing Page**: „landing page `(not set)`" heißt, die erste Sitzung hatte
kein gültiges `page_view` mit `page_location` - meist SPA-Timing,
Consent-Lücke oder Redirect-Kette.
- **„Unassigned"** - ein Wert ist **da**, lässt sich aber keiner Kanalgruppe
zuordnen. Das ist ein Channel-/UTM-Problem, kein Erfassungsproblem - Details
in [Unassigned Traffic in GA4](/de/blog/unassigned-traffic-ga4).
- **`(not provided)`** - historisches UA-Relikt für verschlüsselte organische
Keywords.
## Wo der Auditor das Problem zeigt
Die Sektion `create_page_quality_section` in
[`app/components/dashboard/sections/content.py`](app/components/dashboard/sections/content.py)
zeigt die Page-Title-Probleme:
- **Summary-Karten** zu `(not set)`- und Error-Page-Anteilen.
- **Detail-Tabelle** mit konkreten URLs, Views und Status.
Den Traffic-Source-Anteil siehst du im **Live-Check** als eigene Karte -
ohne dedizierte BigQuery-Sektion, aber mit klarer Ampel.
## So gehst du vor
1. **Page-Title-`(not set)`-Anteil zuerst** - er ist immer behebbar.
- Bei SPAs den Titel direkt vor dem ersten `page_view`-Tag setzen
(z. B. via History-Change-Listener im GTM, der wartet bis `document.title` befüllt ist).
- Bei Multi-Page-Apps prüfen, ob jede Seite einen ``-Tag im
`` hat.
2. **`sessionSource = (not set)` zerlegen** - über die GA4-UI nach
Landing-Page gruppieren und die Top-Landing-Pages auditieren.
3. **UTM-Disziplin etablieren** - Newsletter-Tool, Social-Scheduler und
Affiliate-Programme verpflichten, UTMs zu setzen.
4. **Referral-Exclusion prüfen** - siehe Blog
[Bank- und Payment-Provider als Referrer](/de/blog/payment-referrer-exclusions)
und [Self-Referrals](/de/blog/self-referrals-cross-domain-tracking).
5. Im Auditor unter [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
den Fortschritt nach 48 h prüfen.
## Verwandte Themen
- Blog [Unassigned Traffic in GA4 beheben](/de/blog/unassigned-traffic-ga4)
- Blog [GA4-Audit-Checkliste](/de/blog/features-testkatalog)
- Hilfeseite [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
- Hilfeseite [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
- Blog [E-Commerce-Attribution: Live API vs. BigQuery](/de/blog/attribution-live-api-vs-bigquery)
- Blog [Wenn der `gclid` da ist - und Google Ads trotzdem nicht](/de/blog/gclid-attribution-bug)
---
## "(not set)" in GA4 - where auditing really begins
- URL: https://ga4-auditor.dev/en/blog/not-set-quellen-analyse
- lang: en
- updated: 2026-05-19
- description: When page titles, traffic sources or UTM parameters show up as (not set), the reports are already worthless. Here is how the auditor breaks the problem apart.
`(not set)` is perhaps the most common symptom in GA4 reports - and at the
same time the most frequently ignored one. If you do not know a page title,
cannot assign a channel or lose a `sessionSource`, you have nothing left to
work with in reporting. The auditor checks this on two levels.
## What happens in the code
### Page title (BigQuery view)
The check in [`app/queries/checks/page_quality.sql`](app/queries/checks/page_quality.sql)
classifies every page view into a status class:
```sql
CASE
WHEN page_title IS NULL OR page_title = '' OR page_title = '(not set)'
THEN 'not_set_page'
WHEN page_title LIKE '%404%' OR page_title LIKE '%not found%'
THEN 'error_page'
ELSE 'ok'
END AS page_status
```
### Traffic source (Data API view)
On the live API side,
[`app/services/ga4_api_check_service.py`](app/services/ga4_api_check_service.py)
checks the share of sessions with `sessionSource = (not set)`:
```python
not_set_sessions = _safe_int(_get_single_metric_value(source_not_set_report))
share = (not_set_sessions / total_sessions) if total_sessions > 0 else 0.0
status_traffic = _evaluate_threshold(
share,
warning=THRESHOLDS["traffic_not_set_share"]["warning"], # 5 %
fail=THRESHOLDS["traffic_not_set_share"]["fail"], # 15 %
)
```
## Thresholds (combined)
| Check | Green | Yellow | Red |
|---|---|---|---|
| Page title `(not set)` | <1 % | 1-5 % | >5 % |
| `sessionSource = (not set)` | <5 % | 5-15 % | >15 % |
The two thresholds are deliberately different: a `(not set)` page title is
always a tracking bug (every page has a title), whereas a certain
`(not set)` rate for traffic sources is unavoidable (e.g. direct address
entries).
## Typical causes
- **`` tag missing or arriving too late** - single-page applications
that set the title only after the first `page_view` via JavaScript deliver
an empty value to the GTM trigger.
- **UTM parameters missing** - organic sessions fall into the fallback as
soon as `utm_source` is not passed through. Newsletter clicks, social
posts and affiliate links without UTM all end up here.
- **No-referrer policy in the browser** - if the site or the ad platform
sets `Referrer-Policy: no-referrer`, GA4 sees neither source nor medium.
- **Bot/crawler traffic** - search engine bots without user-agent
classification often land as `(not set)`.
- **Untagged affiliate links** - partners set links without UTM, the traffic
ends up as Direct or `(not set)`.
## "(not set)" vs. "Unassigned" and "landing page (not set)"
Three terms that are often confused:
- **`(not set)`** - GA4 received **no value at all** (a capture or timing
problem). Affects page title, `sessionSource` and also the **landing
page**: "landing page `(not set)`" means the first session had no valid
`page_view` with `page_location` - usually SPA timing, a consent gap or a
redirect chain.
- **"Unassigned"** - a value **is** present but cannot be assigned to any
channel group. That is a channel/UTM problem, not a capture problem -
details in [Unassigned traffic in GA4](/en/blog/unassigned-traffic-ga4).
- **`(not provided)`** - a historical UA relic for encrypted organic
keywords.
## Where the auditor shows the problem
The `create_page_quality_section` section in
[`app/components/dashboard/sections/content.py`](app/components/dashboard/sections/content.py)
shows the page title problems:
- **Summary cards** for `(not set)` and error-page shares.
- **Detail table** with concrete URLs, views and status.
You see the traffic source share in the **live check** as a separate card -
without a dedicated BigQuery section, but with a clear traffic light.
## How to proceed
1. **Page title `(not set)` share first** - it is always fixable.
- For SPAs, set the title right before the first `page_view` tag
(e.g. via a history-change listener in GTM that waits until `document.title` is filled).
- For multi-page apps, check whether every page has a `` tag in the
``.
2. **Break down `sessionSource = (not set)`** - group by landing page in the
GA4 UI and audit the top landing pages.
3. **Establish UTM discipline** - require the newsletter tool, social
scheduler and affiliate programmes to set UTMs.
4. **Check referral exclusion** - see the blog post
[Banks and payment providers as referrers](/en/blog/payment-referrer-exclusions)
and [Self-referrals](/en/blog/self-referrals-cross-domain-tracking).
5. In the auditor, check the progress after 48 h under
[Attribution & acquisition quality](/en/help/attribution-akquisition).
## Related topics
- Blog [Fixing unassigned traffic in GA4](/en/blog/unassigned-traffic-ga4)
- Blog [GA4 audit checklist](/en/blog/features-testkatalog)
- Help page [Attribution & acquisition quality](/en/help/attribution-akquisition)
- Help page [Event quality & PII hints](/en/help/event-qualitaet)
- Blog [E-commerce attribution: live API vs. BigQuery](/en/blog/attribution-live-api-vs-bigquery)
- Blog [When the `gclid` is there - and Google Ads still is not](/en/blog/gclid-attribution-bug)
---
## Bank- und Payment-Provider als Referrer - die unsichtbare Channel-Verzerrung
- URL: https://ga4-auditor.dev/de/blog/payment-referrer-exclusions
- lang: de
- updated: 2026-05-19
- description: Wenn PayPal, Klarna, SOFORT oder 3D-Secure als Quelle deiner Bestellungen erscheinen, ist die Attribution kaputt. So findet der Auditor das Problem.
Du analysierst deine E-Commerce-Akquisition und siehst plötzlich
`paypal.com`, `pay.klarna.com` oder `sofort.com` als Top-Referrer für
deine Bestellungen. Das ist kein gutes Zeichen - und meistens auch kein
echter Traffic. Es bedeutet, dass dein Payment-Flow die ursprüngliche
Akquisitions-Quelle überschreibt.
## Was im Code passiert
Der Check in [`app/queries/checks/payment_referrals.sql`](app/queries/checks/payment_referrals.sql)
matched die `referrer_domain` jeder Session gegen eine kuratierte Liste
bekannter Payment- und Bank-Provider:
```sql
CASE
WHEN LOWER(referrer_domain) LIKE '%paypal%' THEN 'paypal'
WHEN LOWER(referrer_domain) LIKE '%klarna%' THEN 'klarna'
WHEN LOWER(referrer_domain) LIKE '%stripe%' THEN 'stripe'
WHEN LOWER(referrer_domain) LIKE '%adyen%' THEN 'adyen'
WHEN LOWER(referrer_domain) LIKE '%mollie%' THEN 'mollie'
WHEN LOWER(referrer_domain) LIKE '%sofort%' THEN 'sofort'
WHEN LOWER(referrer_domain) LIKE '%giropay%' THEN 'giropay'
WHEN LOWER(referrer_domain) LIKE '%ideal%' THEN 'ideal'
WHEN LOWER(referrer_domain) LIKE '%3dsecure%' THEN '3ds_generic'
WHEN LOWER(referrer_domain) LIKE '%afterpay%' THEN 'afterpay'
WHEN LOWER(referrer_domain) LIKE '%sparkasse%' THEN 'sparkasse'
WHEN LOWER(referrer_domain) LIKE '%bank%' THEN 'bank_generic'
ELSE NULL
END AS payment_provider
```
Die Liste deckt PSPs, BNPL-Anbieter (Buy Now, Pay Later), 3D-Secure und
Online-Banking-Direktüberweisung ab - alles Domains, die im Checkout-Flow
auftauchen können und niemals echter Akquisitions-Traffic sind.
## Schwellenwerte
| Status | Bedingung |
|---|---|
| Grün | 0 oder <5 % der Sessions |
| Gelb | 5-10 % - Referral-Exclusion fehlt |
| Rot | >10 % ohne Ignore-Referrer-Konfiguration |
## Warum entstehen Payment-Referrer?
- **3D-Secure-Redirects** - Bei Kartenzahlungen wird der Nutzer kurz zum
Issuer (z. B. visa.com, mastercard.com) und zurück geleitet. Der
Referrer ist dann die 3DS-Domain.
- **SOFORT/Giropay/iDEAL** - Online-Banking-Direktüberweisung läuft
zwingend über die Drittanbieter-Domain. Die Session-Cookie ist beim
Rücksprung weg, die neue Session startet mit dem Payment-Referrer.
- **BNPL-Flows (Klarna, Afterpay, Ratepay)** - Nutzer wird zum
Kreditgeber geleitet und kommt zurück. Wenn dein Cookie nicht
Cross-Domain-fähig ist, startet eine neue Session.
- **Session-Timeout im Payment-Flow** - Eine besonders lange
Auth-Bestätigung kann die 30-Minuten-Session-Schwelle überschreiten.
## Wo der Auditor das Problem zeigt
⚠️ **Wichtig:** Für diesen Check gibt es im Auditor **keine dedizierte
Dashboard-Sektion**. Der Befund taucht ausschließlich im **Health-Overview**
des Live-Checks auf - als Warnung in der Ampel-Reihe, sobald die
Payment-Referral-Quote die Schwelle reißt.
Wer die konkreten Sessions sehen will, muss in der BigQuery-Konsole die
SQL-Query manuell laufen lassen oder die Acquisition-Sektion ansteuern,
um in den Channel-Verteilung-Auffälligkeiten Hinweise zu finden.
## So behebst du es
1. **In GA4 alle relevanten Payment-Domains als Referral-Exclusion
eintragen.** Unter *Admin → Data Streams → Web-Stream → Configure tag
settings → List unwanted referrals*. Die SQL-Liste oben ist eine gute
Basis-Vorlage.
2. **Cross-Domain-Tracking aktivieren**, wenn dein Payment-Flow zwingend
über eine zweite Domain läuft, die zu dir gehört (z. B. eigener PSP).
Linker-Parameter im GTM setzen.
3. **Session-Timeout in GA4 prüfen** - Default ist 30 Minuten. Wenn
typische Payment-Flows länger dauern, die Session-Dauer erhöhen.
4. **Anschließend 48 h warten und im Auditor unter
[Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
erneut prüfen.**
## Verwandte Themen
- Hilfeseite [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
- Blog [Self-Referrals - wenn deine eigene Domain als Quelle auftaucht](/de/blog/self-referrals-cross-domain-tracking) - verwandtes Problem mit eigener Domain
- Blog [Wenn der `gclid` da ist - und Google Ads trotzdem nicht](/de/blog/gclid-attribution-bug) - wie Payment-Referrer den `gclid` überschreiben können
---
## Self-Referrals - wenn deine eigene Domain als Quelle auftaucht
- URL: https://ga4-auditor.dev/de/blog/self-referrals-cross-domain-tracking
- lang: de
- updated: 2026-05-19
- description: Self-Referrals in GA4 verfälschen Channel-Attribution lautlos. So erkennt der Auditor sie und so behebst du die Ursache.
In den Akquisitions-Reports einer GA4-Property taucht plötzlich
`shop.example.com` als Referrer auf - obwohl `example.com` selbst die
Seite betreibt. Das ist ein **Self-Referral**, einer der häufigsten und
am leichtesten zu übersehenden Tracking-Bugs. Der Auditor erkennt ihn
direkt aus dem BigQuery-Export.
Die Wurzel liegt fast immer in der Einrichtung: Wer GA4
[von Beginn an richtig einrichtet](/de/blog/ga4-einrichten), trägt eigene
Sub- und Hauptdomains gleich korrekt ein - und vermeidet Self-Referrals.
## Was im Code passiert
Der Check in [`app/queries/checks/self_referrals.sql`](app/queries/checks/self_referrals.sql)
vergleicht die `referrer_domain` jeder Session mit der konfigurierten
`site_domain` und klassifiziert in vier Kategorien:
```sql
CASE
WHEN referrer_domain IS NULL OR referrer_domain = '' THEN 'no_referrer'
WHEN LOWER(referrer_domain) = LOWER(site_domain) THEN 'self_referral_exact'
WHEN REGEXP_CONTAINS(LOWER(referrer_domain), CONCAT(r'\.?', REGEXP_REPLACE(LOWER(site_domain), r'^www\.', ''), '$'))
OR REGEXP_CONTAINS(LOWER(site_domain), CONCAT(r'\.?', REGEXP_REPLACE(LOWER(referrer_domain), r'^www\.', ''), '$'))
THEN 'self_referral_subdomain'
ELSE 'external_referral'
END AS referral_type
```
Die Regex-Variante fängt sowohl `www.example.com → example.com` als
auch `example.com → shop.example.com` ab - also exakte Treffer **und**
Subdomain-Beziehungen.
## Schwellenwerte
| Status | Bedingung |
|---|---|
| Grün | 0 Self-Referrals |
| Gelb | ≥1 Self-Referral |
| Rot | >5 % aller Sessions |
Schon ein einziger Self-Referral ist meist ein Hinweis auf ein systemisches
Problem im Domain-Setup - daher die strenge Gelb-Ampel ab dem ersten Treffer.
## Typische Ursachen
- **Subdomain-Wechsel ohne Filter** - Wechsel von `www.example.com` zu
`example.com` oder von `example.com` zu `shop.example.com` ohne
Self-Referral-Domain-Eintrag in den GA4-Datenstrom-Einstellungen.
- **Interner Checkout-Redirect** - Der Bezahlvorgang läuft kurz über eine
Subdomain und kommt zurück, ohne dass der Referrer-Header genullt wird.
- **Cross-Subdomain ohne `_ga`-Cookie-Sync** - Wenn das `_ga`-Cookie
nicht über beide Subdomains gesetzt wird, startet eine neue Session
mit dem internen Referrer.
- **Session-übergreifende Navigation ohne Session-Restart** - Mobile-App
öffnet einen Web-Link, kommt zurück mit eigener Domain als Referrer.
## So zeigt's der Auditor
Die Sektion `create_self_referrals_section` in
[`app/components/dashboard/sections/acquisition.py`](app/components/dashboard/sections/acquisition.py)
liefert:
- Eine Status-Karte mit Prozentsatz und Schwellen-Ampel.
- Ein Zeitreihen-Chart der Self-Referral-Sessions pro Tag.
- Eine Tabelle mit Referrer-Domain × Site-Domain-Paaren.
Damit lässt sich das Problem sowohl quantitativ (wie viel?) als auch
qualitativ (welche konkrete Subdomain?) untersuchen.
## So behebst du es
1. In der GA4-Property unter *Admin → Data Streams → Web-Stream →
Configure tag settings → Define internal domains* alle eigenen
Sub- und Hauptdomains eintragen.
2. Zusätzlich unter *List unwanted referrals* dieselben Domains als
ausgeschlossene Referrer eintragen.
3. Beim Cross-Subdomain-Setup das GA4-Config-Tag im GTM auf
`cookie_domain = 'auto'` setzen, damit `_ga` über alle Subdomains
verfügbar bleibt.
4. Im Auditor unter [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
den Status nach 24-48 h erneut prüfen.
## Verwandte Themen
- Hilfeseite [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
- Blog [Bank- und Payment-Provider als Referrer](/de/blog/payment-referrer-exclusions) - verwandtes Problem mit externen Domains
- Blog [E-Commerce-Attribution: Live API vs. BigQuery](/de/blog/attribution-live-api-vs-bigquery)
---
## User-ID-Coverage - was 20 % Login-Quote über deine Cross-Device-Realität sagen
- URL: https://ga4-auditor.dev/de/blog/user-id-coverage-strategie
- lang: de
- updated: 2026-05-19
- description: User-ID-Coverage ist die unsichtbare Größe hinter Cross-Device-Tracking. So misst der Auditor sie und so verbesserst du sie ohne Login-Zwang.
Wer in GA4 Cross-Device-Tracking ernst nimmt, kommt an einer Zahl nicht
vorbei: der **User-ID-Coverage**. Sie misst, welcher Anteil deiner
Sessions überhaupt einer identifizierbaren Person zugeordnet ist. Bei
SaaS-Produkten mit Login-Zwang liegt sie oft bei 80-95 %, bei
E-Commerce-Shops mit Gast-Checkout bei 5-15 %. Der Unterschied
entscheidet, was du in den Reports sehen kannst - und was nicht.
## Was im Code passiert
Der Check in [`app/queries/checks/user_id_coverage.sql`](app/queries/checks/user_id_coverage.sql)
berechnet drei Coverage-Quoten parallel: Events, Sessions und User mit
gesetzter `user_id`:
```sql
overall_coverage AS (
SELECT
COUNT(*) AS total_events,
COUNTIF(user_id IS NOT NULL AND user_id != '') AS events_with_user_id,
COUNT(DISTINCT session_id) AS total_sessions,
COUNT(DISTINCT CASE WHEN user_id IS NOT NULL AND user_id != ''
THEN session_id END) AS sessions_with_user_id,
COUNT(DISTINCT user_pseudo_id) AS total_users,
COUNT(DISTINCT CASE WHEN user_id IS NOT NULL AND user_id != ''
THEN user_pseudo_id END) AS users_with_user_id
FROM user_id_analysis
)
```
Die drei Quoten unterscheiden sich oft deutlich - z. B. weil eine User-ID
zwar in den Events nach Login gesetzt wird, aber nicht in den vorherigen
Events derselben Session.
## Schwellenwerte
| Status | Bedingung |
|---|---|
| Grün | >50 % - gutes Cross-Device-Tracking möglich |
| Gelb | 10-50 % - nur Logged-in-User identifizierbar |
| Rot | <10 % - Cross-Device praktisch unmöglich |
## Typische Ursachen für niedrige Coverage
- **Kein Login auf der Site** - Nutzer browsen anonym, es gibt schlicht
keine `user_id`, die gesetzt werden könnte.
- **User-ID erst nach Purchase gesetzt** - Häufiges Muster bei Shops:
Der Pre-Purchase-Funnel hat keine ID, erst beim Account-Anlegen im
Checkout wird sie gesetzt - zu spät für sinnvolle Analyse.
- **GTM-Tag feuert nicht oder mit `FALSE`-Bedingung** - Klassischer
Implementierungs-Bug: Die Variable wird gesetzt, aber der Trigger
matcht nicht.
- **Consent-Manager blockiert User-Identifikation** - Manche
CMP-Konfigurationen schalten `user_id` zusammen mit anderen
Identifikatoren ab, auch wenn analytics-Consent vorhanden ist.
## So zeigt's der Auditor
Die Sektion `create_user_id_coverage_section` in
[`app/components/dashboard/sections/content.py`](app/components/dashboard/sections/content.py)
liefert:
- **Overall-Coverage-Karte** mit den drei Quoten (Events / Sessions / User).
- **Summary-Karten** für Anzahl Events, Sessions und User mit ID.
- **Daily-Trend-Tabelle**: wie entwickelt sich die Coverage über die Zeit
(steigt sie nach einem Login-Hinweis-Banner)?
- **Explanation-Accordion** mit Hintergrund zur Cross-Device-Logik.
## Strategien zur Verbesserung - auch ohne Login-Zwang
1. **Soft-Login fördern** - Newsletter, Wishlist, Kundenkonto im
Checkout-Flow als optional, aber attraktiv präsentieren.
2. **Login-Persistenz erhöhen** - Sessions länger gültig halten,
Remember-Me-Cookies setzen, damit die User-ID über Besuche stabil
bleibt.
3. **User-ID rückwirkend auf Session-Anfang setzen** - Sobald sich der
User einloggt, kann das GTM-Tag die User-ID auch für die laufende
Session beim nächsten Event mitsenden. Damit bleibt die ID nicht erst
ab Login-Klick, sondern für die ganze Session sichtbar.
4. **Consent-Setup audit** - Über [Consent Mode v2 verstehen](/de/hilfe/consent-mode)
prüfen, ob die User-Identifikation nicht versehentlich mit gesperrt
wird.
5. **Im Auditor unter [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
sicherstellen**, dass die `user_id` nicht versehentlich Klartext-Mails
oder Telefonnummern enthält - GA4 sperrt sonst die Property.
## Verwandte Themen
- Hilfeseite [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
- Hilfeseite [Consent Mode v2 verstehen](/de/hilfe/consent-mode)
- Blog [Consent Mode v2 in GA4 - was du wissen musst](/de/blog/ga4-consent-mode-v2)
---
## Consent Mode v2 in GA4 prüfen und verstehen
- URL: https://ga4-auditor.dev/de/blog/ga4-consent-mode-v2
- lang: de
- updated: 2026-06-01
- description: So prüfst du in Minuten, ob Consent Mode v2 korrekt läuft: ad_user_data, ad_personalization und Modelling - mit dem GA4 Auditor.
Mit Consent Mode v2 hat Google zwei neue Signale eingeführt: `ad_user_data`
und `ad_personalization`. Wer beides nicht oder falsch setzt, riskiert, dass
Audiences, Remarketing und Conversion-Modelling stillschweigend aussetzen -
ohne Fehlermeldung. Der GA4 Auditor prüft genau das automatisch. Diese Seite
zeigt dir, worauf es ankommt und wie du deinen Consent Mode v2 in Minuten
selbst prüfst.
Noch ganz am Anfang? Dann [richte GA4 zuerst richtig ein](/de/blog/ga4-einrichten) -
Consent Mode v2 setzt ein funktionierendes GA4-Setup voraus.
## Was Consent Mode v2 ist
Consent Mode v2 ist eine Schnittstelle, über die du Google den
Einwilligungsstatus deiner Besucher mitteilst. Vor v2 reichten `ad_storage`
und `analytics_storage`. Die beiden neuen Signale steuern jetzt explizit, ob
ein User in Personalisierung und Modelling einbezogen werden darf. Lehnt ein
Nutzer ab, sendet Consent Mode anonymisierte Pings, aus denen Google
entgangene Conversions modelliert.
## So prüfst du Consent Mode v2
Drei Wege, vom schnellsten zum gründlichsten:
1. **GA4 Auditor (OnPage-Check)** - der Headless-Browser scannt deine Seite
in der Phase vor und nach der Consent-Entscheidung, erkennt 14 CMPs und
liest den Default- und Updated-Consent-State direkt aus dem `dataLayer`.
2. **GTM-Vorschaumodus** - prüfe, ob deine Tags bei noch nicht akzeptiertem
Banner auf `denied` stehen und nach „Akzeptieren" auf `granted` wechseln.
3. **GA4-Diagnose** - unter *Verwaltung > Diagnose* bestätigt ein grüner
Status den aktiven Einwilligungsmodus.
## Die sechs Consent-Signale
| Signal | Steuert | Relevant für |
|---|---|---|
| `ad_storage` | Werbe-Cookies | Google Ads |
| `analytics_storage` | Analyse-Cookies | GA4 |
| `functionality_storage` | funktionale Daten (z. B. Sprache) | Website |
| `personalization_storage` | personalisierte Inhalte | Website |
| `ad_user_data` *(neu)* | Weitergabe von Nutzerdaten an Google | Ads, Enhanced Conversions |
| `ad_personalization` *(neu)* | personalisierte Werbung / Remarketing | Ads |
## So setzt du es korrekt
1. Setze die Default-Werte VOR jedem `gtag('config', ...)`.
2. Update sie sofort nach der CMP-Entscheidung - ohne Page-Reload.
3. Validiere im Tracking-Debugger des Auditors, ob beide neuen Signale
tatsächlich gesendet werden.
## Typische Fehler
- Default-Consent wird zu spät gesetzt, Tags feuern bereits auf `granted`.
- `ad_user_data` und `ad_personalization` fehlen ganz - das v1-Setup wurde
nie auf v2 erweitert.
- Die CMP aktualisiert den State erst nach einem Reload statt sofort.
## Verwandte Themen
- [Consent Mode v2 verstehen (Hilfe)](/de/hilfe/consent-mode) - Schritt für
Schritt in der App.
- [Datensicherheit im GA4 Auditor](/de/blog/datensicherheit-im-ga4-auditor) -
warum wir read-only und EU-gehostet arbeiten.
- [GA4-Audit-Checkliste](/de/blog/features-testkatalog) - alle Checks im
Überblick, inklusive Consent-Prüfung.
---
## Checking and understanding Consent Mode v2 in GA4
- URL: https://ga4-auditor.dev/en/blog/ga4-consent-mode-v2
- lang: en
- updated: 2026-06-01
- description: How to check in minutes whether Consent Mode v2 runs correctly: ad_user_data, ad_personalization and modelling - with the GA4 Auditor.
With Consent Mode v2, Google introduced two new signals: `ad_user_data`
and `ad_personalization`. Anyone who sets neither or sets them wrong risks
audiences, remarketing and conversion modelling silently failing -
without any error message. The GA4 Auditor checks exactly that
automatically. This page shows you what matters and how to check your
Consent Mode v2 yourself in minutes.
## What Consent Mode v2 is
Consent Mode v2 is an interface through which you tell Google the consent
status of your visitors. Before v2, `ad_storage` and `analytics_storage`
were enough. The two new signals now explicitly control whether a user may
be included in personalisation and modelling. If a user declines, Consent
Mode sends anonymised pings from which Google models missed conversions.
## How to check Consent Mode v2
Three routes, from the fastest to the most thorough:
1. **GA4 Auditor (on-page check)** - the headless browser scans your page
in the phase before and after the consent decision, detects 14 CMPs and
reads the default and updated consent state directly from the `dataLayer`.
2. **GTM preview mode** - check whether your tags are set to `denied` while
the banner has not yet been accepted and switch to `granted` after
"Accept".
3. **GA4 diagnostics** - under *Admin > Diagnostics*, a green status
confirms the active consent mode.
## The six consent signals
| Signal | Controls | Relevant for |
|---|---|---|
| `ad_storage` | advertising cookies | Google Ads |
| `analytics_storage` | analytics cookies | GA4 |
| `functionality_storage` | functional data (e.g. language) | website |
| `personalization_storage` | personalised content | website |
| `ad_user_data` *(new)* | sharing user data with Google | Ads, Enhanced Conversions |
| `ad_personalization` *(new)* | personalised advertising / remarketing | Ads |
## How to set it correctly
1. Set the default values BEFORE every `gtag('config', ...)`.
2. Update them immediately after the CMP decision - without a page reload.
3. Validate in the auditor's tracking debugger whether both new signals are
actually sent.
## Common mistakes
- The default consent is set too late, tags already fire on `granted`.
- `ad_user_data` and `ad_personalization` are missing entirely - the v1
setup was never extended to v2.
- The CMP only updates the state after a reload instead of immediately.
## Related topics
- [Understanding Consent Mode v2 (help)](/en/help/consent-mode) - step by
step in the app.
- [Data security in the GA4 Auditor](/en/blog/datensicherheit-im-ga4-auditor) -
why we work read-only and EU-hosted.
- [GA4 audit checklist](/en/blog/features-testkatalog) - all checks at a
glance, including the consent check.
---
## BigQuery-Export für GA4 - der Auditor-Standpunkt
- URL: https://ga4-auditor.dev/de/blog/bigquery-export-fuer-ga4
- lang: de
- updated: 2026-05-08
- description: Warum der BigQuery-Export für jedes ernsthafte GA4-Setup gehört und welche Audits damit erst möglich werden.
Ohne den BigQuery-Export läufst du in GA4 in eine Sackgasse: keine Roh-Daten,
keine eigene SQL-Modellierung, keine retroaktiven Audits. Der Auditor nutzt
den Export, um Sessions, Conversions und E-Commerce-Daten gegen das Live-UI
zu validieren.
## Was im Export drin ist
Der GA4-BigQuery-Export liefert für jeden Tag eine `events_YYYYMMDD`-Tabelle
mit allen Event-Records inklusive `user_properties`, `event_params` und der
zugehörigen `device`/`geo`-Struktur. Daraus rekonstruierst du Sessions,
Conversion-Pfade und Audience-Mitgliedschaften - auch rückwirkend.
## Datenqualitäts-Checks
1. **Event-Counts** vs. GA4-UI: Standard-Drift < 1 %. Mehr ist ein Hinweis
auf Sampling, Filter oder unkontrollierte Consent-Effekte.
2. **Conversions**: jede Conversion muss eine `transaction_id` haben.
3. **E-Commerce**: `currency` und `value` dürfen nie fehlen.
## Wann sich der Export lohnt
Schon ab dem ersten Property mit Kommerz-Tracking. Die Kosten sind in den
ersten Monaten vernachlässigbar (Free-Tier), der Erkenntnisgewinn ist groß.
---
## BigQuery export for GA4 - the auditor view
- URL: https://ga4-auditor.dev/en/blog/bigquery-export-fuer-ga4
- lang: en
- updated: 2026-05-08
- description: Why the BigQuery export belongs in every serious GA4 setup and which audits only become possible with it.
Without the BigQuery export you hit a wall in GA4: no raw data, no custom
SQL modelling, no retroactive audits. The auditor uses the export to
reconcile sessions, conversions and e-commerce data against the live UI.
## What is in the export
The GA4 BigQuery export delivers a daily `events_YYYYMMDD` table with all
event records including `user_properties`, `event_params` and the
associated `device`/`geo` struct.
## Data-quality checks
1. **Event counts** vs. GA4 UI: standard drift < 1 %.
2. **Conversions**: every conversion must have a `transaction_id`.
3. **E-commerce**: `currency` and `value` must never be missing.
---
## Datensicherheit im GA4 Auditor - wie wir Konten und Daten schützen
- URL: https://ga4-auditor.dev/de/blog/datensicherheit-im-ga4-auditor
- lang: de
- updated: 2026-05-19
- description: OAuth 2.0, Read-only-Scopes, kurze Token-Lebensdauer und EU-Hosting - wie der GA4 Auditor Google-Zugriffe technisch absichert.
Wenn ein Drittanbieter-Tool auf deine Google-Analytics-Daten zugreift, ist die
Frage nach Datensicherheit berechtigt - und sie muss eine technische Antwort
bekommen, nicht nur eine Marketing-Floskel. Dieser Beitrag beschreibt, wie der
GA4 Auditor diese Antwort konkret umsetzt: welche Berechtigungen er anfordert,
wie lange Tokens existieren und welche Daten überhaupt gespeichert werden.
## OAuth 2.0 statt Passwort-Weitergabe
Der Auditor nutzt **Google OAuth 2.0 (OpenID Connect)**. Konkret heißt das:
- Kein Passwort verlässt den Google-Anmeldebildschirm.
- Die Authentifizierung passiert komplett bei Google; der Auditor sieht nur das
Ergebnis (einen kurzlebigen Access-Token).
- Du kannst die Verbindung jederzeit unter
[myaccount.google.com/permissions](https://myaccount.google.com/permissions)
widerrufen - danach funktioniert kein weiterer API-Call mehr.
## Minimale Berechtigungen - Least Privilege als Code
Die OAuth-Scopes sind in
[`app/config.py`](app/config.py) zentral und sichtbar definiert
(`OAUTH_SCOPES_LIST`):
| Scope | Zweck |
|---|---|
| `openid` | Identitäts-Token (Google-Authentifizierung) |
| `email` | Konto-E-Mail zur eindeutigen Zuordnung |
| `analytics.readonly` | Lesezugriff auf GA4 Admin- und Data-API |
| `bigquery.readonly` | Lesezugriff auf BigQuery-Datasets (optional, nur wenn Export verknüpft) |
Beide Google-API-Scopes sind explizit `.readonly`. Das ist keine
Vertrauensfrage, sondern technisch garantiert: Mit diesen Scopes kann der
Auditor **nichts** in deinem GA4-Setup ändern, nichts löschen, keine Tags
ausspielen, keine Audiences anlegen. Read-only ist read-only.
## Tokens leben kurz und nur im Speicher
Access-Tokens haben in Google OAuth eine Standard-Lebensdauer von etwa einer
Stunde. Refresh-Tokens (über die ein Access-Token erneuert werden könnte) hält
der Auditor **nur während der aktiven Session** - sie werden weder dauerhaft
verschlüsselt abgelegt noch zwischen Sessions wiederverwendet.
Konkrete Folgen:
- Nach `GA4_SESSION_TIMEOUT_MINUTES` (Default: 30 Minuten Inaktivität) ist die
Session weg.
- Ein Server-Neustart invalidiert sämtliche Tokens.
- Ein hypothetischer Datenbank-Snapshot durch einen Angreifer würde **keine**
brauchbaren Zugriffs-Tokens enthalten - die liegen ausschließlich im
Application-Speicher der aktiven Session.
## Datensparsamkeit als Default
Die Datenschutzerklärung (siehe [`/de/datenschutzerklaerung`](/de/datenschutzerklaerung), §3) führt es im Detail aus - kurz zusammengefasst:
- **GA4-Rohdaten werden nicht persistiert.** Reports und Live-Checks werden zur
Laufzeit aus den Google-APIs gezogen und im UI dargestellt. Was beim Schließen
des Tabs in der Session noch lag, ist beim nächsten Login weg.
- **GA4-Property-IDs werden als organisationsgebundene HMAC-Hashes
abgespeichert.** Wer die Datenbank in die Hand bekommt, sieht keine
Klartext-IDs.
- **Server-Logs** werden in der Regel nach 14 Tagen rotiert (siehe
Datenschutzerklärung §9), Backups nach maximal 35 Tagen.
## Verschlüsselung, Hosting, Cookies
- TLS für alle Verbindungen (HTTPS-only in Produktion).
- Session-Cookies mit `HttpOnly`, `SameSite=Lax` und `Secure`-Flag.
- Hosting auf Google Cloud Platform (EU-Region) mit
Auftragsverarbeitungsverträgen.
- Kein Tracking ohne Einwilligung - Matomo (self-hosted) läuft nur nach aktivem
Opt-in.
## Was du tun kannst, wenn du den Zugriff zurücknehmen willst
1. Auf [myaccount.google.com/permissions](https://myaccount.google.com/permissions) den Eintrag „GA4 Auditor" anklicken und Zugriff entziehen.
2. Optional: Account-Löschung per E-Mail an `info@webmasterei-prange.de` -
wird in der Regel innerhalb von 30 Tagen abgearbeitet.
## Was du in der App selbst tun kannst
- **Tracking-Debugger** in der App nutzen, um zu sehen, welche Daten wirklich an
Google fließen - siehe Hilfeseite [Tracking-Debugger Schritt für Schritt](/de/hilfe/tracking-debug).
- **Consent Mode v2** sauber konfigurieren, damit die App nicht versehentlich
mehr „sieht" als gewollt - siehe Hilfeseite [Consent Mode v2 verstehen](/de/hilfe/consent-mode).
## Fazit
Datensicherheit ist im GA4 Auditor kein eigenes Feature, sondern Architektur:
OAuth statt Passwort, read-only statt admin, In-Memory-Tokens statt
Persistenz, HMAC-Hashes statt Klartext-IDs, EU-Hosting statt US-Default.
Wer es genauer wissen will, findet die vollständige rechtliche Ausformulierung
in der [Datenschutzerklärung](/de/datenschutzerklaerung).
---
## E-Commerce-Attribution: Live API vs. BigQuery - warum die Zahlen abweichen
- URL: https://ga4-auditor.dev/de/blog/attribution-live-api-vs-bigquery
- lang: de
- updated: 2026-05-19
- description: Live-API und BigQuery-Export liefern für dieselben Bestellungen unterschiedliche Kanal-Zuordnungen. Hier sind die Ursachen - und welcher Report wann der richtige ist.
Im GA4 Auditor gibt es zwei Wege, die Quellen einer Bestellung zu analysieren:
über die **Live-API** (`sessionDefaultChannelGroup`) oder über den
**BigQuery-Export** (`session_traffic_source_last_click.cross_channel_campaign.default_channel_group`).
Für dieselbe Bestellung sieht man oft unterschiedliche Kanäle - das ist kein
Bug, sondern systemisch. Dieser Artikel erklärt warum.
## Zwei Reports, zwei Datenstände
| Report | Datenquelle | Wann sinnvoll? |
|---|---|---|
| Live-Channel-Distribution | GA4 Data API (aggregiert) | Tages-Monitoring, Google-Ads-Sicht, schneller Health-Check |
| Order-Attribution / Google-Ads-Attribution | BigQuery (event-level) | Tracking-Debugging, Audit historischer Daten, Root-Cause |
Die Live-API liefert **vor-aggregierte Reporting-Daten** mit Googles
Standard-Channel-Grouping. Der BigQuery-Export liefert dieselben Felder, aber
**aus den Rohdaten** und **deterministisch** für einen abgeschlossenen Tag.
## Das 72-Stunden-Fenster
GA4 hält die Attribution nach einem Event noch **bis zu 72 Stunden offen**.
Googles ML modelliert in dieser Zeit Conversions für Cookie-blockierte Nutzer
und Cross-Device-Journeys nach. Das hat zwei Effekte, die der Auditor sichtbar
macht:
- **Live-API** zeigt aktuelle, modellierte Attribution - die sich aber bis zu
3 Tage später noch ändert.
- **BigQuery-Daily-Export** spiegelt den **finalisierten** Stand wider
(24-48h nach Tagesende stabil).
Wer also montags die Live-API-Zahlen einer Kampagne vom Sonntag mit dem
BigQuery-Export von Sonntag vergleicht, sieht zwangsläufig Unterschiede.
## Wo „Direct" nicht gleich „Direct" ist
Die Live-API fasst auffälliges Verhalten oft pauschal unter `(Direct)` /
`(unassigned)` zusammen. Der Auditor zerlegt das im BigQuery-Report in
deutlich feinere Klassen - der entsprechende SQL-Block aus
[`app/queries/checks/google_ads_attribution.sql`](app/queries/checks/google_ads_attribution.sql)
zeigt das Prinzip:
```sql
CASE
-- gclid vorhanden UND korrekt als Paid Search/Cross-network klassifiziert
WHEN gclid IS NOT NULL AND gclid != ''
AND (
LOWER(session_default_channel) IN ('paid search', 'cross-network')
OR (LOWER(session_source) = 'google'
AND LOWER(session_medium) IN ('cpc', 'ppc', 'paidsearch'))
)
THEN 'attributed_paid_search'
-- gclid vorhanden, ABER als Organic/Direct klassifiziert (Bug-Fall)
WHEN gclid IS NOT NULL AND gclid != ''
THEN 'gclid_misclassified'
-- Direct ohne gclid: möglicherweise Tracking-Lücke
WHEN LOWER(session_default_channel) = 'direct'
THEN 'direct_no_gclid'
ELSE 'other'
END AS attribution_status
```
Das Feld `attribution_status` rollt der Auditor in der Dashboard-Section
**Google Ads Attribution** auf, sodass der bekannte GA4-Bug
„`gclid` da, aber als Organic gezählt" überhaupt sichtbar wird - in der
Live-API würde diese Session schlicht als `Organic Search` durchlaufen.
## Daily vs. Intraday im BigQuery-Export
Der BigQuery-Export schreibt sowohl `events_intraday_YYYYMMDD` (laufend) als
auch `events_YYYYMMDD` (final, ein bis zwei Tage später). Der Auditor
bevorzugt automatisch die finalisierte Tabelle, sobald sie verfügbar ist -
das wirkt nach außen wie „die Zahlen ändern sich noch", ist aber gewollt:
Intraday-Daten sind Schätzwerte, Daily-Export ist Wahrheit.
## Welcher Report wann?
- **Live-API-Channel-Distribution** für: Tages-Monitoring, Google-Ads-Sicht
mit Conversion-Modeling, schnelle Plausibilitätsprüfung.
- **BigQuery-Order-Attribution** für: Tracking-Bug-Diagnose, historische
Vergleiche, Audit-Berichte, alles Detailgenaue.
Im Dashboard sind beide Sichten parallel verfügbar - `create_acquisition_section`
für die Live-Sicht, `create_order_attribution_section` und
`create_google_ads_attribution_section` für die BigQuery-Sicht. Die
Hilfeseite [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
fasst die wichtigsten Diagnose-Pfade zusammen.
## Fazit
Abweichungen zwischen Live-API und BigQuery sind **keine Tracking-Fehler**,
sondern Folge unterschiedlicher Datenstände und Klassifikations-Granularität.
Wer Attribution ernsthaft auditieren will, braucht **beide** Sichten: Die
Live-API zeigt, **dass** etwas nicht stimmt - BigQuery zeigt, **was genau**.
---
## Video-Anleitungen zum GA4 Auditor
- URL: https://ga4-auditor.dev/de/blog/videobeitraege-uebersicht
- lang: de
- updated: 2026-05-19
- description: Drei kurze Video-Touren durch den Auditor: Übersichtsseite, Server-Side-Tracking-Check und Session-Debugging mit BigQuery.
Wer den GA4 Auditor lieber im Bewegtbild kennenlernen will, findet hier drei
kurze Touren durch die wichtigsten Bereiche. Jedes Video begleitet einen
Workflow, den Techniker und Analyst:innen sonst in der App
zusammensuchen - und zeigt, wie die Auditor-Sicht den Schritt verkürzt.
## Video 1 - Übersicht: Die Auditor-Startseite
Das erste Video führt durch die Übersichtsseite des Auditors und zeigt, wie
sich Live-Check, Ampel-Checks, SST-Analyse und OnPage-Checks zueinander
verhalten. Wer den Auditor zum ersten Mal öffnet, bekommt hier ein klares
Bild davon, in welchem Bereich welcher Test sitzt.
::: youtube qHmNig8N1AY
:::
**Passt zu:** [Live Check - schnelle GA4-API-Diagnose](/de/hilfe/live-check)
und zur Startseite [`/de/`](/de/).
## Video 2 - Server-Side-Tracking im Auditor prüfen
Das zweite Video beantwortet die zwei zentralen Fragen rund um Server-Side
Tracking: **Ist SST überhaupt schon eingebunden?** Und: **Lohnt sich die
Umstellung für dieses Setup?** Der Auditor berechnet dafür einen
SST-Score (gewichtet aus Cookie-Lifetime, Attribution-Gap, Funnel-Dauer,
Cross-Domain und SST-Detection).
::: youtube HxUX909hZxU
:::
**Passt zu:** [SST-Analyse - der Server-Side-Score](/de/hilfe/sst-analyse).
## Video 3 - Session-Debugging mit dem BigQuery-Export
Das dritte Video zeigt, wie der Auditor mit BigQuery-Daten in die Session-Tiefe
geht: Welche Sessions haben kein `session_start`-Event? Wo bricht der Funnel?
Wann ist es Bot-Traffic, wann ein echter Tracking-Bug? Das Beispiel nutzt den
Datensatz einer realen Property und zeigt, wie kürzere Kontroll-Zyklen
durch den Auditor möglich werden.
::: youtube oheI3mJxFMs
:::
**Passt zu:** [Session-Qualität & Bot-Filter](/de/hilfe/session-qualitaet) und
[Ampel-Checks - Datenqualität aus BigQuery](/de/hilfe/ampel-checks-bigquery).
## Wie geht es weiter?
Wer nach dem Einstieg tiefer in den Auditor will, findet weitere Lese-Pfade
im [Hilfe-Center](/de/hilfe/) und im Blog-Beitrag
[Features & Testkatalog](/de/blog/features-testkatalog), der die vollständige
Test-Übersicht aller vier Audit-Methoden auf einer Seite zeigt.
---
## GA4-Audit-Checkliste: alle Checks des GA4 Auditors
- URL: https://ga4-auditor.dev/de/blog/features-testkatalog
- lang: de
- updated: 2026-06-01
- description: Was prüft ein GA4-Audit? Die vollständige Checkliste: Live-Check, Ampel-Checks aus BigQuery, SST-Analyse und OnPage-Audit - manuell oder automatisiert.
Ein GA4-Audit prüft, ob dein Google-Analytics-4-Setup vollständig, sauber und
datenschutzkonform misst. Der GA4 Auditor kombiniert dafür vier Methoden in
einem Tool. Diese Seite ist die vollständige Checkliste: **alle** Checks, die
der Auditor ausführt - als Referenz für Techniker und als Einstieg in die
passenden Hilfeseiten.
Du hast GA4 noch gar nicht oder nur halb installiert? Dann hilft zuerst die
[Schritt-für-Schritt-Anleitung zur GA4-Einrichtung](/de/blog/ga4-einrichten) -
dieses Audit prüft anschließend, ob das Setup wirklich sauber misst.
## Was ein GA4-Audit prüft
Ein belastbares Audit deckt vier Ebenen ab: die **Konfiguration** (über die
Admin-API), die **Datenqualität auf Event-Level** (aus dem BigQuery-Export),
das **Server-Side-Tagging-Potenzial** und die **On-Page-Implementierung** vor
und nach dem Consent. Die folgenden Tabellen listen jeden einzelnen Check.
## Datenquellen und Grenzen
| Quelle | Wofür | Grenzen |
|---|---|---|
| GA4 Admin API | Streams, Enhanced Measurement, Key Events, BigQuery-Linking | Reine Konfiguration, keine Daten |
| GA4 Data API | aggregierte Reporting- und Realtime-Metriken | Sampling möglich, kein Event-Detail |
| BigQuery Export | Event-Level-Rohdaten | Setup nötig, etwas Lag |
| Playwright (OnPage) | Headless-Browser, Phase vor/nach Consent | Eine URL pro Lauf |
## Statuslogik
Drei Klassen pro Check:
- **Pass** - keine Auffälligkeit, Schwellenwerte eingehalten
- **Warning** - erkennbares Risiko oder unvollständiges Setup
- **Fail** - hohe Wahrscheinlichkeit eines echten Tracking-Problems
## GA4 Live Check (Admin- & Data-API)
| Check | Datenquelle | Signal | Typische Ursachen |
|---|---|---|---|
| Streams vorhanden | Admin API | Mindestens ein Stream existiert | Property unvollständig |
| Enhanced Measurement aktiv | Admin API | Auto-Events aktiviert | Bewusst deaktiviert |
| Key Events vorhanden | Admin API | Mindestens ein Key Event definiert | Ziele nicht gepflegt |
| Google Ads Linking | Admin API | Mindestens eine Ads-Verknüpfung | Fehlende Berechtigungen |
| BigQuery Export verknüpft | Admin API | BigQuery-Linking vorhanden | Dataset-Location-Fehler |
| Annotations vorhanden | Admin API | Data Annotations existieren | Governance fehlt |
| Custom Definitions vorhanden | Admin API | Dimensionen/Metrics existieren | Parameter nicht registriert |
| Privacy Signals | Admin API | Data Retention, Google Signals | Retention zu kurz |
| Basis-Events vorhanden | Data API | `session_start` und `page_view` | Tag feuert nicht |
| Direct-Anteil plausibel | Data API | Anteil Direct erhöht | UTMs fehlen |
| Unassigned-Anteil plausibel | Data API | Anteil Unassigned erhöht | Channel Rules fehlen |
| PageTitle „(not set)"-Anteil | Data API | Anteil nicht gesetzter Titel | SPA setzt zu spät |
| PageTitle mit 404-Mustern | Data API | Anteil mit 404-Mustern | Kaputte Links |
| Traffic Source „(not set)" | Data API | `sessionSource` not set | UTMs fehlen |
| E-Commerce-Plausibilität | Data API | `add_to_cart` und `purchase` passen zusammen | Checkout-Events fehlen |
| Site Search Nutzung | Data API | Search Terms vorhanden | Enhanced Measurement aus |
| Audiences vorhanden | Admin API | Audiences mit Bedingungen | Kein Remarketing-Setup |
Mehr Detail: [Live Check - schnelle GA4-API-Diagnose](/de/hilfe/live-check).
## Ampel-Checks (BigQuery)
| Check | Signal | Typische Ursachen |
|---|---|---|
| Event Errors | Fehlende Items, IDs, Values, PII | Schema-Fehler |
| Duplicate Events | Doppelte Events gleicher Timestamp | Trigger doppelt |
| Event Values | Events ohne Value | Value nicht gesetzt |
| Page Quality | Seiten mit „(not set)" oder 404 | SPA-Timing |
| URL Parameters | PII-verdächtige Parameter | PII in URL |
| PII-Hinweise | E-Mail, Telefon, Name in URLs | Formulare, Redirects |
| Content Grouping | Content Groups nicht befüllt | Taxonomie fehlt |
| Site Search | Such-Events vorhanden | Search nicht getrackt |
| Session Consistency | Sessions ohne start/page_view | Bot-Traffic |
| Session Gap | Zeitabstände zwischen Sessions | Session-Timeout |
| User-ID Coverage | Anteil `user_id`-Events | Login fehlt |
| Acquisition Channels | Keine Source/Medium, ungültige UTMs | UTMs fehlen |
| Self-Referrals | Eigene Domain als Referrer | Cross-Domain kaputt |
| Channel Distribution | Unassigned/Direct hoch | UTMs fehlen |
| Ecommerce Funnel | Funnel-Sprünge | Events fehlen |
| Ecommerce Transactions | Revenue null | Value/Currency nicht gesetzt |
| Duplicate Transactions | Doppelte Purchases | Reload Thank-You-Page |
| Payment Referrals | Payment-Domains als Referrer | Checkout-Domainwechsel |
Mehr Detail: [Ampel-Checks - Datenqualität aus BigQuery](/de/hilfe/ampel-checks-bigquery)
und themenspezifisch:
[E-Commerce-Checks](/de/hilfe/ecommerce-checks),
[Attribution & Akquisition](/de/hilfe/attribution-akquisition),
[Session-Qualität](/de/hilfe/session-qualitaet),
[Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet).
## SST-Analyse (gewichteter Score 0-100)
| Check | Gewicht | Signal |
|---|---|---|
| Cookie Lifetime Impact | 35 % | Safari vs. Chrome Returning Rate |
| Attribution Gap | 35 % | Unattribuierte Sessions/Key Events |
| Funnel Duration | 20 % | Tage bis Conversion |
| Cross-Domain | 10 % | Mehrere Domains erkannt |
| SST Detection | - | `user_pseudo_id`-Muster |
Mehr Detail: [SST-Analyse - der Server-Side-Score](/de/hilfe/sst-analyse).
## OnPage-Checks (Playwright vor/nach Consent)
| Check | Signal |
|---|---|
| Server-Side Tagging | Custom GA4-Endpoints, FPID-Cookie |
| GTM-Implementierung | Container-IDs, Duplikate |
| CMP-Erkennung | 14 CMPs erkannt (Cookiebot, OneTrust, Usercentrics …) |
| Consent Mode v2 | Default/Updated Consent State |
| Privacy / DSGVO | Tracking vor Consent-Akzeptanz |
| Third-Party-Tools | 9 Tools erkannt (Meta, TikTok, LinkedIn, Clarity …) |
| DataLayer | Events, E-Commerce-Validierung |
Mehr Detail: [OnPage-Checks - Browser-basiertes Audit](/de/hilfe/onpage-checks).
## Empfohlener Workflow
1. **Live-Check-Übersicht** - schnell sehen, ob Setup und Datenbasis grundsätzlich stimmen.
2. **Ampel-Tab** - bei Warnings/Fails die BigQuery-Rohdaten heranziehen.
3. **SST-Bereich** - bei Attribution- und Browser-Gaps Impact bewerten.
4. **OnPage-Analyse** - für spezifische URLs und Consent-Verifikation.
## Manuell oder automatisiert auditieren?
Manuell ist gründlich, aber langsam und schwer reproduzierbar - und genau
deshalb bricht Tracking meist unbemerkt zwischen zwei Audits. Der
[GA4 Auditor](/de/) automatisiert die wiederkehrende Prüfung über die
offiziellen Google-APIs und den BigQuery-Export und liefert in Minuten eine
Ampel-Bewertung. Strategie und Interpretation bleiben menschlich - das Tool
liefert die belastbare Faktenbasis.
## Verwandte Beiträge
- [GA4 Auditor: Property in Minuten prüfen](/de/) - das Tool zur Checkliste.
- [Consent Mode v2 in GA4 prüfen](/de/blog/ga4-consent-mode-v2)
- [Datensicherheit im GA4 Auditor](/de/blog/datensicherheit-im-ga4-auditor)
- [E-Commerce-Attribution: Live API vs. BigQuery](/de/blog/attribution-live-api-vs-bigquery)
- [Video-Anleitungen zum GA4 Auditor](/de/blog/videobeitraege-uebersicht)
---
## GA4 Audit Checklist 2026: 24 Checks + Free Template
- URL: https://ga4-auditor.dev/en/blog/features-testkatalog
- lang: en
- updated: 2026-06-26
- description: The complete GA4 audit checklist: 24 checks across configuration, BigQuery data quality, server-side tagging and on-page consent. Copy it as a template or run it automatically.
A GA4 audit checks whether your Google Analytics 4 setup measures
completely, cleanly and in a privacy-compliant way. The GA4 Auditor
combines four audit methods - live check, BigQuery data quality,
server-side tagging and on-page - in a single tool, with 24 essential
checks across the board and 14 consent platforms (CMPs) detected
automatically, in line with Google's official
[Consent Mode v2 guidance](https://developers.google.com/tag-platform/security/concepts/consent-mode).
This page is the complete checklist: **all** the checks the auditor runs -
as a reference for technicians and as an entry point into the matching help
pages.
## What a GA4 audit checks
A robust audit covers four layers: the **configuration** (via the Admin
API), the **data quality at event level** (from the BigQuery export), the
**server-side tagging potential** and the **on-page implementation** before
and after consent. The following tables list every single check.
## The GA4 audit checklist (copy & check off)
Work through these 24 essential checks in order. Each maps to a section
below and to a help page with the fix.
**1. Configuration (Admin API)**
- [ ] At least one data stream exists
- [ ] Enhanced Measurement is active
- [ ] Key events are defined and current
- [ ] Google Ads linking present (if you run Ads)
- [ ] BigQuery export linked, dataset location correct
- [ ] Custom definitions registered for your event parameters
- [ ] Data retention set to the maximum your plan allows
- [ ] Audiences defined for remarketing
- [ ] Annotations and data governance maintained
**2. Data quality (BigQuery export)**
- [ ] No duplicate events on identical timestamps
- [ ] No PII in URLs or event parameters
- [ ] Channel distribution: Unassigned/Direct not inflated
- [ ] E-commerce funnel intact (add_to_cart to purchase)
- [ ] No duplicate transactions (thank-you-page reloads)
- [ ] User-ID coverage matches your login rate
- [ ] No self-referrals (your own domain as a referrer)
- [ ] Acquisition: valid UTMs, no (not set) sources
**3. Server-side tagging**
- [ ] Cookie lifetime impact assessed (Safari vs. Chrome)
- [ ] Attribution gap measured
- [ ] Cross-domain setup detected and correct
**4. On-page (before and after consent)**
- [ ] No tracking fires before consent acceptance
- [ ] Consent Mode v2 default and update states correct
- [ ] GTM container IDs present, no duplicates
- [ ] CMP detected and configured
## Is there a GA4 audit template?
Yes. This checklist works as a reusable GA4 audit template: copy the 24
checks above, run each against your property, and mark Pass, Warning or
Fail. The GA4 Auditor fills the same template automatically via the
official Google APIs and the BigQuery export, so you get the filled-in
version in minutes instead of working through it by hand.
## Data sources and limits
| Source | What for | Limits |
|---|---|---|
| GA4 Admin API | streams, Enhanced Measurement, key events, BigQuery linking | configuration only, no data |
| GA4 Data API | aggregated reporting and realtime metrics | sampling possible, no event detail |
| BigQuery export | event-level raw data | setup required, some lag |
| Playwright (on-page) | headless browser, phase before/after consent | one URL per run |
## Status logic
Three classes per check:
- **Pass** - no issue, thresholds met
- **Warning** - recognisable risk or incomplete setup
- **Fail** - high likelihood of a real tracking problem
## GA4 live check (Admin & Data API)
| Check | Data source | Signal | Typical causes |
|---|---|---|---|
| Streams present | Admin API | at least one stream exists | property incomplete |
| Enhanced Measurement active | Admin API | auto events enabled | deliberately disabled |
| Key events present | Admin API | at least one key event defined | goals not maintained |
| Google Ads linking | Admin API | at least one Ads link | missing permissions |
| BigQuery export linked | Admin API | BigQuery linking present | dataset location error |
| Annotations present | Admin API | data annotations exist | governance missing |
| Custom definitions present | Admin API | dimensions/metrics exist | parameters not registered |
| Privacy signals | Admin API | data retention, Google Signals | retention too short |
| Base events present | Data API | `session_start` and `page_view` | tag does not fire |
| Direct share plausible | Data API | Direct share elevated | UTMs missing |
| Unassigned share plausible | Data API | Unassigned share elevated | channel rules missing |
| PageTitle "(not set)" share | Data API | share of unset titles | SPA sets too late |
| PageTitle with 404 patterns | Data API | share with 404 patterns | broken links |
| Traffic source "(not set)" | Data API | `sessionSource` not set | UTMs missing |
| E-commerce plausibility | Data API | `add_to_cart` and `purchase` match | checkout events missing |
| Site search usage | Data API | search terms present | Enhanced Measurement off |
| Audiences present | Admin API | audiences with conditions | no remarketing setup |
More detail: [Live check - fast GA4 API diagnostics](/en/help/live-check).
## Traffic-light checks (BigQuery)
| Check | Signal | Typical causes |
|---|---|---|
| Event Errors | missing items, IDs, values, PII | schema error |
| Duplicate Events | duplicate events with same timestamp | trigger duplicated |
| Event Values | events without value | value not set |
| Page Quality | pages with "(not set)" or 404 | SPA timing |
| URL Parameters | PII-suspicious parameters | PII in URL |
| PII hints | email, phone, name in URLs | forms, redirects |
| Content Grouping | content groups not filled | taxonomy missing |
| Site Search | search events present | search not tracked |
| Session Consistency | sessions without start/page_view | bot traffic |
| Session Gap | time gaps between sessions | session timeout |
| User-ID Coverage | share of `user_id` events | login missing |
| Acquisition Channels | no source/medium, invalid UTMs | UTMs missing |
| Self-Referrals | own domain as referrer | cross-domain broken |
| Channel Distribution | Unassigned/Direct high | UTMs missing |
| Ecommerce Funnel | funnel jumps | events missing |
| Ecommerce Transactions | revenue null | value/currency not set |
| Duplicate Transactions | duplicate purchases | reload of thank-you page |
| Payment Referrals | payment domains as referrer | checkout domain switch |
More detail: [Traffic-light checks - data quality from BigQuery](/en/help/ampel-checks-bigquery)
and topic-specific:
[E-commerce checks](/en/help/ecommerce-checks),
[Attribution & acquisition](/en/help/attribution-akquisition),
[Session quality](/en/help/session-qualitaet),
[Event quality & PII hints](/en/help/event-qualitaet).
## SST analysis (weighted score 0-100)
| Check | Weight | Signal |
|---|---|---|
| Cookie Lifetime Impact | 35 % | Safari vs. Chrome returning rate |
| Attribution Gap | 35 % | unattributed sessions/key events |
| Funnel Duration | 20 % | days to conversion |
| Cross-Domain | 10 % | multiple domains detected |
| SST Detection | - | `user_pseudo_id` pattern |
More detail: [SST analysis - the server-side score](/en/help/sst-analyse).
## On-page checks (Playwright before/after consent)
| Check | Signal |
|---|---|
| Server-Side Tagging | custom GA4 endpoints, FPID cookie |
| GTM implementation | container IDs, duplicates |
| CMP detection | 14 CMPs detected (Cookiebot, OneTrust, Usercentrics …) |
| Consent Mode v2 | default/updated consent state |
| Privacy / GDPR | tracking before consent acceptance |
| Third-party tools | 9 tools detected (Meta, TikTok, LinkedIn, Clarity …) |
| DataLayer | events, e-commerce validation |
More detail: [On-page checks - browser-based audit](/en/help/onpage-checks).
## Recommended workflow
1. **Live check overview** - quickly see whether the setup and data basis are fundamentally sound.
2. **Traffic-light tab** - for warnings/fails, pull in the BigQuery raw data.
3. **SST area** - assess the impact for attribution and browser gaps.
4. **On-page analysis** - for specific URLs and consent verification.
## Audit manually or automated?
Manual is thorough, but slow and hard to reproduce - and that is exactly
why tracking usually breaks unnoticed between two audits. The
[GA4 Auditor](/en/) automates the recurring check via the official Google
APIs and the BigQuery export and delivers a traffic-light rating in
minutes. Strategy and interpretation stay human - the tool delivers the
robust factual basis.
## Related posts
- [GA4 Auditor: check your property in minutes](/en/) - the tool behind the checklist.
- [Checking Consent Mode v2 in GA4](/en/blog/ga4-consent-mode-v2)
- [Data security in the GA4 Auditor](/en/blog/datensicherheit-im-ga4-auditor)
- [E-commerce attribution: live API vs. BigQuery](/en/blog/attribution-live-api-vs-bigquery)
- [Video guides for the GA4 Auditor](/en/blog/videobeitraege-uebersicht)
---
## Ampel-Checks - Datenqualität aus BigQuery
- URL: https://ga4-auditor.dev/de/hilfe/ampel-checks-bigquery
- lang: de
- updated: 2026-05-19
- description: Wie die Ampel-Checks die GA4-Rohdaten aus BigQuery bewerten, welche Schwellen hinterlegt sind und wie du Warnungen interpretierst.
Die Ampel-Checks im GA4 Auditor lesen die GA4-BigQuery-Exporttabellen
(`events_YYYYMMDD`, `events_intraday_YYYYMMDD`) und bewerten Datenqualität
auf Event-Level. Sie sind die Tiefenstufe nach dem
[Live Check](/de/hilfe/live-check): Was die GA4-API nur summarisch sieht,
zerlegen die Ampel-Checks bis auf einzelne Events herunter.
## Was prüft die App?
Die Ampel-Checks gruppieren die BigQuery-SQL-Queries unter
[`app/queries/checks/`](app/queries/checks/) in thematische Sektionen:
- **Events** - Event-Errors, Duplikate, Values
- **Sessions** - Konsistenz, Gap-Analyse, fehlende `session_start`
- **Akquisition** - Channels, Self-Referrals, Payment-Referrer
- **E-Commerce** - Funnel, Transactions, Attribution, Duplikate
- **Inhalte** - Page-Quality, Content-Groups, Site-Search, User-ID
Jede Sektion liefert einen Ampel-Status (Pass / Warning / Fail), eine
Kurz-Erklärung in einer Hint-Box (`render_hint_box`) und optional eine
ausklappbare Lösungsanleitung (`render_solution_accordion`).
## Wann wird ein Check ausgelöst?
Beispiele für Schwellenwerte aus dem Code:
| Check | Schwelle |
|---|---|
| E-Commerce-Funnel-Fehler | >0 Fehler = Rot, 1-3 Issues = Gelb, 0 = Grün |
| Session-Konsistenz | <5 % ohne `session_start` = Grün, 5-15 % Gelb, >15 % Rot |
| Event-Duplikate | >5 % = Warnung |
| gclid ohne Attribution | >10 % der Google-Ads-Sessions = Warnung |
Die SQL-Logik dazu liegt z. B. in
[`ecommerce_funnel.sql`](app/queries/checks/ecommerce_funnel.sql),
[`session_consistency.sql`](app/queries/checks/session_consistency.sql),
[`event_quality.sql`](app/queries/checks/event_quality.sql) und
[`acquisition_channels.sql`](app/queries/checks/acquisition_channels.sql).
## Hint-Box vs. Lösungs-Accordion
Im Dashboard nutzt jede Section zwei standardisierte UI-Bausteine:
- **`render_hint_box`** zeigt einen Kurzhinweis: Worum geht's, warum ist
das ein Problem? Maximal 2-3 Sätze.
- **`render_solution_accordion`** klappt eine Schritt-für-Schritt-Anleitung
auf: Welche Konfiguration anpassen, welche Stelle im Code, welche
Folge-Audit-Frage stellen?
So bleibt der Dashboard-Status scannbar, ohne dass technische Details
verloren gehen.
## Typische Ursachen
- **Funnel-Sprünge** → fehlende Checkout-Events, Items ohne IDs oder Prices
in den `purchase`-Events, Custom-Code-Bug im GTM.
- **`session_start` fehlt** → GTM-Tag feuert erst nach Session-Timeout,
Server-Side-Tagging mit zu hoher Latenz.
- **gclid nicht zugeordnet** → manuelle UTM-Parameter überschreiben den
Auto-Tagging-Klick, Cross-Domain-Sprung verliert den Parameter - siehe
Blog [Wenn der `gclid` da ist - und Google Ads trotzdem nicht](/de/blog/gclid-attribution-bug).
## So gehst du vor
1. Im Dashboard auf den Ampel-Tab wechseln und nach roten/gelben Karten suchen.
2. Pro Section die Hint-Box lesen - sie nennt das Symptom konkret.
3. Lösungs-Accordion ausklappen, Schritt-für-Schritt abarbeiten.
4. Bei E-Commerce-Themen direkt in [E-Commerce-Checks im Detail](/de/hilfe/ecommerce-checks)
springen - dort ist die Funnel-Logik mit Schwellen erklärt.
5. Bei Datenqualitäts-Themen (PII, Duplikate, Items fehlen) in
[Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet) weiterlesen.
## Verwandte Themen
- [E-Commerce-Checks im Detail](/de/hilfe/ecommerce-checks)
- [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
- [Session-Qualität & Bot-Filter](/de/hilfe/session-qualitaet)
- [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
- [BigQuery-Export für GA4 - der Auditor-Standpunkt](/de/blog/bigquery-export-fuer-ga4)
---
## Attribution & Akquisitions-Qualität
- URL: https://ga4-auditor.dev/de/hilfe/attribution-akquisition
- lang: de
- updated: 2026-05-19
- description: Wie der Auditor Channel-Attribution und UTM-Qualität in GA4 bewertet - Direct/Unassigned-Anteile, gclid-Bugs, Self-Referrals und Payment-Referrer.
Akquisitions-Daten in GA4 sind nur so gut wie die Kanal-Zuordnung. Wenn
ein hoher Anteil deiner Sessions als `Direct` oder `(unassigned)` landet,
weiß GA4 nicht, woher der Traffic kommt - und genau das deckt der Auditor
auf.
## Was prüft die App?
Die Akquisitions-Checks bewerten vier Ebenen:
1. **Channel-Verteilung** - wie groß ist der Anteil von `Direct` und
`(unassigned)`?
2. **Google-Ads-Klick-Qualität** - wird `gclid` korrekt als Paid Search
klassifiziert?
3. **Self-Referrals** - taucht deine eigene Domain als Referrer auf?
4. **Payment-Provider** - werden Bank- und Payment-Domains als Quelle
gemessen statt korrekt ausgeschlossen?
## Wann wird ein Check ausgelöst?
| Check | Schwelle |
|---|---|
| Direct-Anteil | <20 % = Grün, 20-35 % = Gelb, >35 % = Rot |
| Unassigned-Anteil | <5 % = Grün, 5-10 % = Gelb, >10 % = Rot |
| gclid-Mismatch | gclid da, aber Channel ≠ Google Ads = Warnung |
| Payment-Self-Referrals | >2 % der Sessions = Warnung |
| UTM-Fehler | `utm_source=(direct)` oder `utm_medium=(none)` = Rot |
Die Schwellen kommen aus `app/services/ga4_api_check_service.py:_run_data_checks()`
sowie aus den SQL-Queries
[`acquisition_channels.sql`](app/queries/checks/acquisition_channels.sql),
[`channel_distribution.sql`](app/queries/checks/channel_distribution.sql),
[`self_referrals.sql`](app/queries/checks/self_referrals.sql) und
[`payment_referrals.sql`](app/queries/checks/payment_referrals.sql).
## Typische Ursachen
- **Fehlende UTM-Parameter** - Kampagnen ohne `utm_source` oder
`utm_medium`, E-Mail-Links nicht getaggt, Social Ads als organisch
zurückgemessen.
- **gclid-Drop** - Cross-Domain-Redirect ohne gclid-Pass, Payment-Redirect
bricht den Parameter, Referral-Exclusion-Liste zu kurz. Tieferer Hintergrund
im Blog [Wenn der `gclid` da ist - und Google Ads trotzdem nicht](/de/blog/gclid-attribution-bug).
- **Self-Referrals** - eigene Subdomain (`shop.example.com`) ist nicht als
Self-Referral-Domain in GA4 eingetragen. Details im Blog
[Self-Referrals - wenn deine eigene Domain als Quelle auftaucht](/de/blog/self-referrals-cross-domain-tracking).
- **Payment-Referrer** - PayPal, Klarna, Stripe, Adyen, SOFORT, Giropay
und Co. landen als Quelle. Lösung: Referral-Exclusion-Liste pflegen.
Im Blog [Bank- und Payment-Provider als Referrer](/de/blog/payment-referrer-exclusions)
steht die vollständige Liste der erkannten Provider.
## So gehst du vor
1. **Channel-Verteilung im Dashboard** prüfen - Direct/Unassigned-Anteil
gegen die Schwellen vergleichen.
2. Bei gclid-Warnungen die **Google-Ads-Attribution-Sektion** öffnen
(`create_google_ads_attribution_section`) - sie zeigt konkrete Sessions
mit gclid, die nicht als Google Ads gezählt wurden.
3. **Self-Referrals-Sektion** (`create_self_referrals_section`) öffnen,
wenn die eigene Domain als Referrer erscheint.
4. **Payment-Provider** in der GA4-Property unter *Property-Settings →
Data Streams → Configure tag settings → Define internal traffic /
List unwanted referrals* eintragen.
5. Bei UTM-Lücken die Kampagnen-Tagging-Disziplin überarbeiten - ohne
sauberes Tagging bleibt jede Attribution Schätzung.
## Verwandte Themen
- [Ampel-Checks aus BigQuery](/de/hilfe/ampel-checks-bigquery)
- [E-Commerce-Checks im Detail](/de/hilfe/ecommerce-checks)
- [Server-Side-Tracking-Analyse](/de/hilfe/sst-analyse)
- [E-Commerce-Attribution: Live API vs. BigQuery](/de/blog/attribution-live-api-vs-bigquery)
- [Self-Referrals - Cross-Domain-Tracking](/de/blog/self-referrals-cross-domain-tracking)
- [Bank- und Payment-Provider als Referrer](/de/blog/payment-referrer-exclusions)
- [Wenn der `gclid` da ist - und Google Ads trotzdem nicht](/de/blog/gclid-attribution-bug)
---
## Consent Mode v2 verstehen
- URL: https://ga4-auditor.dev/de/hilfe/consent-mode
- lang: de
- updated: 2026-05-12
- description: Was Consent Mode v2 für dein GA4-Tracking ändert.
Consent Mode v2 erweitert das bisherige Modell um zwei neue Signale:
``ad_user_data`` und ``ad_personalization``.
## Warum Consent Mode
Mit Consent Mode kannst du Hits an Google senden, selbst wenn der User
**nicht** zugestimmt hat - die Daten werden dann anonymisiert/modelliert.
## Auswirkungen auf das Tracking
- Page Views und Conversions werden im UI weiterhin gezählt
- Modellierte Daten werden mit einem Hinweis markiert
- Audiences brauchen ``ad_user_data=granted`` für die Personalisierung
---
## Understanding Consent Mode v2
- URL: https://ga4-auditor.dev/en/help/consent-mode
- lang: en
- updated: 2026-05-12
- description: What Consent Mode v2 changes for your GA4 tracking.
Consent Mode v2 adds two new signals: ``ad_user_data`` and
``ad_personalization``.
## Why Consent Mode
With Consent Mode you can still send hits to Google when a user has **not**
consented - Google will then anonymise/model the data.
## Tracking implications
- Page views and conversions are still counted in the UI
- Modelled data is flagged with a note
- Audiences require ``ad_user_data=granted`` for personalization
---
## E-Commerce-Checks im Detail
- URL: https://ga4-auditor.dev/de/hilfe/ecommerce-checks
- lang: de
- updated: 2026-05-19
- description: Wie der Auditor E-Commerce-Daten in GA4 bewertet: Pflicht-Events, Funnel-Completion, Duplikate, Attribution - mit konkreten Schwellenwerten.
E-Commerce ist der Bereich, in dem schon kleine Tracking-Lücken zu großen
Umsatz-Lücken im Reporting führen. Der Auditor prüft das auf zwei Ebenen:
Live (über die GA4 Data API) und in der Tiefe (über BigQuery).
## Was prüft die App?
Vier zentrale Themen liegen hinter den E-Commerce-Checks:
1. **Pflicht-Events vorhanden** - `view_item`, `add_to_cart`,
`begin_checkout` und `purchase` müssen alle gemessen werden.
2. **Funnel-Completion** - wie viele Sessions, die einen `begin_checkout`
feuern, kommen tatsächlich bis `purchase`?
3. **Duplikate** - werden Käufe versehentlich doppelt erfasst?
4. **Transaktions-Attribution** - werden Käufe sauberen Kanälen zugeordnet,
oder landen sie überproportional auf `Direct` und `Unassigned`?
## Wann wird ein Check ausgelöst?
Aus dem Code:
| Check | Schwelle |
|---|---|
| Pflicht-Events | alle vier vorhanden = Grün; eines fehlt = Rot |
| Funnel-Completion (`purchase / begin_checkout`) | >50 % = Grün, 20-50 % = Gelb, <20 % = Rot |
| Duplicate Transactions | >1 % doppelte `purchase` = Warnung |
| Direct/Unassigned bei Käufen | <15 % = Grün, 15-30 % = Gelb, >30 % = Rot |
Die Logik liegt in `app/services/ga4_api_check_service.py:_run_data_checks()`
(Pflicht-Events + Attribution) und in den SQL-Queries
[`ecommerce_funnel.sql`](app/queries/checks/ecommerce_funnel.sql),
[`ecommerce_transactions.sql`](app/queries/checks/ecommerce_transactions.sql)
und [`duplicate_events.sql`](app/queries/checks/duplicate_events.sql).
## Typische Ursachen
- **Fehlende `purchase`-Events** → Checkout läuft auf einer Subdomain
ohne Tracking, Payment-Redirect-URL löscht Cookies vor dem Trigger,
Headless-/No-JS-Checkout.
- **Doppelte Transaktionen** → Reload der Danke-Seite, Popup-Workflow
feuert Trigger mehrfach, fehlerhafte Dedup-Logik im GTM, parallele
Universal-Analytics-Implementierung läuft mit. Tieferer Hintergrund im
Blog [Doppelte Käufe in GA4](/de/blog/duplicate-transactions-deduplication).
- **Unvollständige Item-Daten** → `price` und `item_id` werden als
`(not set)` übergeben, weil dynamische Felder nicht im DataLayer landen.
- **Hoher Direct-Anteil bei Käufen** → Payment-Provider als Referrer
(siehe Blog [Bank- und Payment-Provider als Referrer](/de/blog/payment-referrer-exclusions))
oder Cross-Domain-Tracking ohne `_ga`-Cookie-Pass.
## So gehst du vor
1. **Pflicht-Events zuerst** - wenn `purchase` fehlt, lohnt jede weitere
Auswertung erst, sobald das Tracking läuft.
2. **Funnel-Sektion `create_ecommerce_funnel_section`** öffnen - sie zeigt
die Drop-offs zwischen `view_item` → `add_to_cart` → `begin_checkout` →
`purchase` als Sankey-/Barchart.
3. **Duplikate-Sektion `create_duplicate_transactions_section`** prüfen -
sie listet konkrete Transaction-IDs, die mehrfach gefeuert wurden,
inkl. Umsatz-Impact.
4. **Attribution kreuzprüfen** mit
[Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition).
5. Bei Item-Datenproblemen in [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
weiterlesen - dort liegt die PII- und `(not set)`-Diagnose.
## Verwandte Themen
- [Ampel-Checks aus BigQuery](/de/hilfe/ampel-checks-bigquery)
- [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
- [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
- [Doppelte Käufe in GA4](/de/blog/duplicate-transactions-deduplication)
- [E-Commerce-Attribution: Live API vs. BigQuery](/de/blog/attribution-live-api-vs-bigquery)
---
## Event-Qualität & PII-Hinweise
- URL: https://ga4-auditor.dev/de/hilfe/event-qualitaet
- lang: de
- updated: 2026-05-19
- description: Wie der Auditor Event-Schema-Fehler, PII-Risiken, (not set)-Anteile und Duplikate in GA4 erkennt - mit Schwellen aus dem Code.
GA4-Events sind nur so wertvoll wie ihre Schema-Konsistenz und PII-Hygiene.
Diese Hilfeseite erklärt, welche Auffälligkeiten der Auditor in der
Event-Qualitäts-Sektion meldet und wie sie zu interpretieren sind.
## Was prüft die App?
Die Event-Qualitäts-Checks scannen Roh-Events aus dem BigQuery-Export auf:
- **PII-Pattern** in `user_properties`, `page_location` und Event-Parametern
- **`(not set)`-Anteile** in Pflichtfeldern (Items, Werte, Page-Title)
- **Fehlende Items** in `purchase`-Events
- **`debug_mode=1`-Events** in Production
- **Duplikate** innerhalb derselben Sekunde / desselben 5-Minuten-Fensters
## Wann wird ein Check ausgelöst?
| Check | Schwelle |
|---|---|
| PII (E-Mail/Telefon in Parametern) | >0 % = kritisch |
| `(not set)`-Anteil | >1 % = Warnung, >5 % = Rot |
| `purchase` ohne `items` | jede Stelle = Rot |
| `debug_mode=1` in Production | >0 % = Info/Warnung |
| Event-Duplikate im 5-min-Fenster | >2 % = Rot |
Die Checks liegen in
[`event_quality.sql`](app/queries/checks/event_quality.sql),
[`duplicate_events.sql`](app/queries/checks/duplicate_events.sql),
[`event_values.sql`](app/queries/checks/event_values.sql) sowie in
`app/services/ga4_api_check_service.py` für die `(not set)`-Schwellen.
## Typische Ursachen
- **PII in Parametern** → E-Mail-Adresse versehentlich als `utm_content`
oder im Page-Path, Telefonnummer als `item_id`, Customer-ID als `user_id`
ohne vorherige Pseudonymisierung. **Pflicht**: GA4 schließt Konten, die
PII speichern.
- **`(not set)` durch fehlende Mappings** → Event-Parameter wird im GTM
nicht gesetzt, dynamische Variable liefert `undefined`, Server-Response
wird nicht korrekt geparst.
- **Duplikate** → HTTP-Retry ohne Idempotenz-Check, GTM-Trigger feuert
doppelt, Plugin-Konflikt (WooCommerce + GA4-Plugin parallel).
- **`debug_mode=1` in Production** → Tracker wurde nach lokalem Test nicht
zurückgesetzt; verfälscht Conversion-Reports.
## So gehst du vor
1. **Event-Errors-Sektion** (`create_event_errors_section`) im Dashboard
öffnen - sie clustert die Befunde nach Kategorie (PII, Items fehlen,
Duplikate, `(not set)`).
2. **PII-Warnungen sofort beheben** - kein Audit lohnt sich, solange
Klartext-Mails in Events landen. GA4 droht mit Konto-Sperrung.
3. **`(not set)`-Pattern** über den Blog
[„(not set)" in GA4 - wo das Auditing wirklich anfängt](/de/blog/not-set-quellen-analyse)
in die typischen Ursachen einordnen.
4. **Duplikate** zerlegen mit
[Doppelte Käufe in GA4](/de/blog/duplicate-transactions-deduplication) -
dort steht die SQL-Logik der Sekunden-Bucket-Erkennung.
5. **`debug_mode`** in der GA4-Konfiguration des GTM-Tags überprüfen.
## Verwandte Themen
- [Ampel-Checks aus BigQuery](/de/hilfe/ampel-checks-bigquery)
- [E-Commerce-Checks im Detail](/de/hilfe/ecommerce-checks)
- [Session-Qualität & Bot-Filter](/de/hilfe/session-qualitaet)
- [Doppelte Käufe in GA4](/de/blog/duplicate-transactions-deduplication)
- [„(not set)" in GA4 - wo das Auditing wirklich anfängt](/de/blog/not-set-quellen-analyse)
---
## Live Check - schnelle GA4-API-Diagnose
- URL: https://ga4-auditor.dev/de/hilfe/live-check
- lang: de
- updated: 2026-05-19
- description: Was der Live Check über die GA4 Admin- und Data-API prüft, welche Schwellenwerte gelten und wie du Probleme einordnest.
Der Live Check ist der schnellste Weg, um den Gesundheitszustand einer
GA4-Property einzuschätzen. Er fragt die offiziellen Google-APIs ab,
ohne dass ein BigQuery-Export nötig ist - und liefert in Sekunden ein Bild
über Setup-Konfiguration und tagesaktuelle Datenqualität.
## Was prüft die App?
Der Live Check kombiniert zwei Datenquellen:
- **GA4 Admin API** für die Konfigurations-Sicht: Streams, Enhanced
Measurement, Key Events, Google-Ads-Verknüpfung, BigQuery-Linking,
Custom Definitions, Privacy Signals.
- **GA4 Data API** für Plausibilitäts-Sicht: Realtime-Nutzer,
`session_start` und `page_view`, Channel-Verteilung, `(not set)`-Anteile,
E-Commerce-Plausibilität, Site-Search.
Die Checks landen in der Ampel-Reihe oben im Dashboard und nutzen den
Standard-Status (Pass / Warning / Fail), wie er auch im
[Features & Testkatalog](/de/blog/features-testkatalog) beschrieben ist.
## Wann wird ein Check ausgelöst?
Konkrete Schwellenwerte aus dem Code:
| Check | Schwelle |
|---|---|
| Realtime-Nutzer | 0 aktive Nutzer = kritisch |
| Data Streams | mindestens 1 Web-Stream Pflicht |
| Enhanced Measurement | deaktiviert = Info |
| Key Events | optimal 3-10; ≥ 25 = Info („zu viele") |
| Data Retention | < 14 Monate = Warnung |
| BigQuery Export | `reachable=false` = kritisch |
Die Logik liegt in `app/services/ga4_live_check_rules.py:build_live_check_findings()`
und wird im Dashboard von `app/services/ga4_api_check_service.py:get_overview()`
aufgerufen.
## Typische Ursachen
- **0 Realtime-Nutzer** → Tracking-Code fehlt oder wird blockiert,
Consent Mode falsch konfiguriert, Production-URL stimmt nicht mit dem
GA4-Stream überein.
- **Keine Web-Streams** → Property ist unvollständig angelegt, es existieren
nur App-Streams.
- **BigQuery unerreichbar** → GCP-Projekt-Zugriff fehlt, Dataset-Permissions
sind nicht korrekt gesetzt, Region zwischen GA4 und BigQuery passt nicht
zusammen.
## So gehst du vor
1. Im Dashboard die obere Ampel-Reihe durchsehen - jede Karte ist klickbar
und öffnet Hint- und Lösungstexte direkt unter dem Status.
2. Bei Realtime-`0`-Befunden zuerst den
[Tracking-Debugger](/de/hilfe/tracking-debug) öffnen - der zeigt
eingehende Events pro Stream und Sekunde.
3. Bei `(not set)`-Auffälligkeiten parallel den BigQuery-Tab nutzen -
die [Ampel-Checks aus BigQuery](/de/hilfe/ampel-checks-bigquery) zeigen
die gleiche Frage mit deutlich mehr Detail.
4. Falls eine Konfigurationswarnung (z. B. fehlende Custom Dimensions)
auftaucht: über die GA4-Admin-UI ändern und nach 24 h erneut prüfen -
die Data-API spiegelt Änderungen mit Verzögerung.
## Wann reicht der Live Check, wann braucht es BigQuery?
- **Live Check reicht** für Tages-Monitoring, Setup-Audits und das
schnelle Erkennen von Tracking-Ausfällen.
- **BigQuery (Ampel-Tab)** ergänzt, sobald es um Event-Detail,
Funnel-Konsistenz, Duplikate, PII-Hinweise oder
Attribution-Tiefenanalyse geht - siehe
[Ampel-Checks aus BigQuery](/de/hilfe/ampel-checks-bigquery).
## Verwandte Themen
- [Ampel-Checks aus BigQuery](/de/hilfe/ampel-checks-bigquery)
- [Tracking-Debugger Schritt für Schritt](/de/hilfe/tracking-debug)
- [Consent Mode v2 verstehen](/de/hilfe/consent-mode)
- [Features & Testkatalog](/de/blog/features-testkatalog)
---
## Tracking-OnPage-Check für GA4: Tags, Consent und dataLayer prüfen
- URL: https://ga4-auditor.dev/de/hilfe/onpage-checks
- lang: de
- updated: 2026-06-26
- description: Prüft direkt im Browser, ob GA4-Tag, Consent-Signale und dataLayer auf einer Seite sauber laden. Teil des GA4-Audits - kein SEO-OnPage-Tool.
Die GA4-Tracking-OnPage-Checks öffnen eine echte URL in einem Headless-Browser
(Chromium via Playwright) - einmal vor Consent-Akzeptanz, einmal danach.
Sie liefern damit eine Sicht, die APIs allein nicht haben: Was passiert
*auf der Seite selbst* in den ersten Sekunden?
## Was prüft die App?
Die OnPage-Sektion deckt sieben Bereiche ab:
1. **Server-Side-Tagging-Detection** - antwortet die Site mit Custom
GA4-Endpoints oder einem FPID-Cookie?
2. **GTM-Implementierung** - sind Container geladen, gibt es Duplikate?
3. **CMP-Erkennung** - 14 Consent-Management-Plattformen werden erkannt
(Cookiebot, OneTrust, Usercentrics, Borlabs, CCM19, Sourcepoint u. a.).
4. **Consent Mode v2** - Default- und Updated-State werden mitgelesen.
5. **Privacy/DSGVO** - feuert Tracking *vor* der Consent-Akzeptanz?
6. **Drittanbieter-Tools** - 9 Tracker werden erkannt (Meta, TikTok,
LinkedIn, Clarity u. a.).
7. **DataLayer** - sind Events und E-Commerce-Daten Spec-konform?
## Wann wird ein Check ausgelöst?
| Check | Schwelle |
|---|---|
| Measurement-ID erkannt | Ja = Grün, Nein = Rot |
| `page_view + session_start` in 2 min | >5 = Grün, <2 = Rot |
| Cross-Domain-Cookie (`_ga`) | über Domains konsistent = Grün |
| Consent-Status `analytics` | granted = Grün, denied = Warnung |
| Tracker-Feuern vor Consent | jedes Event = DSGVO-Warnung |
Die Logik liegt in [`app/pages/onpage.py`](app/pages/onpage.py),
[`app/services/browser_check_service.py`](app/services/browser_check_service.py)
und [`app/services/onpage_check_evaluator.py`](app/services/onpage_check_evaluator.py).
## Typische Ursachen
- **GTM nicht geladen** → JavaScript-Fehler im Container, Content-Security-Policy
blockt das Script, URL-Mismatch zwischen GA4-Stream und tatsächlicher
Domain.
- **Measurement-ID falsch** → Copy-Paste-Bug, alte/Test-ID im Production-Code
hängen geblieben.
- **Tracking vor Consent** → GTM-Trigger feuert auf „Page Load" statt auf
„Consent granted", CMP-Script lädt nach GTM oder gar nicht.
- **Cross-Domain-Cookie fehlt** → `_ga`-Cookie wird nicht über das
Sub-/Hauptdomain-Setup hinweg gesetzt, weil `auto`-Konfiguration
überschrieben wurde.
## So gehst du vor
1. Im Auditor unter **OnPage** eine URL eingeben - bei Cloud-Run-Setup
ist das Feature ggf. erst nach Aktivierung sichtbar
(`onpage.disabled.title`).
2. Den Lauf abwarten (~10-30 s pro URL, da zwei Phasen).
3. Die zwei Spalten „Vor Consent" und „Nach Consent" vergleichen - alles,
was *vor* Consent feuert, ist ein potenzielles DSGVO-Risiko.
4. CMP-Erkennung prüfen: Wenn keine CMP gefunden wird, obwohl eine läuft,
das Element im DOM identifizieren und ggf. Issue im Auditor melden.
5. Bei Consent-Mode-Themen parallel
[Consent Mode v2 verstehen](/de/hilfe/consent-mode) öffnen.
## Verwandte Themen
- [Consent Mode v2 verstehen](/de/hilfe/consent-mode)
- [Tracking-Debugger Schritt für Schritt](/de/hilfe/tracking-debug)
- [Server-Side-Tracking-Analyse](/de/hilfe/sst-analyse)
- [Datensicherheit im GA4 Auditor](/de/blog/datensicherheit-im-ga4-auditor)
---
## Session-Qualität & Bot-Filter
- URL: https://ga4-auditor.dev/de/hilfe/session-qualitaet
- lang: de
- updated: 2026-05-19
- description: Wie der Auditor Sessions ohne session_start, Bot-Traffic-Indikatoren und Session-Neustarts erkennt - mit Schwellenwerten.
Sessions sind in GA4 die Klammer um den Nutzer-Besuch. Wenn Sessions ohne
`session_start` ankommen, Sessions zu schnell hintereinander starten oder
hunderte Events pro Minute feuern, stimmt etwas im Tracking nicht - oder es
ist Bot-Traffic.
## Was prüft die App?
Drei Themen:
1. **Session-Start-Coverage** - wie viele Sessions haben kein `session_start`-Event?
2. **Session-Gap-Analyse** - wie viel Zeit liegt zwischen aufeinanderfolgenden
Sessions des gleichen Nutzers?
3. **Event-Frequenz** - feuert eine Session ungewöhnlich viele Events?
(Bot-Indikator)
## Wann wird ein Check ausgelöst?
| Check | Schwelle |
|---|---|
| `session_start`-Coverage | <5 % ohne = Grün, 5-15 % = Gelb, >15 % = Rot |
| Session-Gap | <30 min normal, 30 min-4 h = Warnung, >4 h = Rot |
| Event-Frequenz | >100 Events/min = Bot-Indikator |
| Single-Event-Sessions | >30 % = Rot |
| Sessions ohne `page_view` | jede = Warnung |
Die Schwellen kommen aus `app/services/ga4_api_check_service.py:_run_data_checks()`
und den SQL-Queries
[`session_consistency.sql`](app/queries/checks/session_consistency.sql),
[`session_gap_analysis.sql`](app/queries/checks/session_gap_analysis.sql) und
[`orders_without_session_start.sql`](app/queries/checks/orders_without_session_start.sql).
## Typische Ursachen
- **`session_start` zu spät** → GTM-Container-Ladezeit über 2 Sekunden,
Server-Side-Tagging mit hoher Latenz, Tracking-Code im Async-Script ohne
Initialisierungs-Guard.
- **Session-Neustarts** → `session_timeout` zu kurz konfiguriert (10 statt
30 min), Navigation Mobile↔Web verliert Cookies, VPN-/Proxy-Rotation
setzt das Cookie zurück.
- **Event-Spikes** → fehlerhafte For-Loop im Custom-Code, Scroll-Tracking
zu aggressiv (z. B. Event pro Pixel), Webhook-Loop, das eine externe
Anwendung zurück in die Property pumpt.
- **Sessions ohne `page_view`** → Tracker feuert Custom-Events bevor der
erste Page-View ausgelöst wurde, oder Single-Page-App setzt den ersten
Page-View nicht.
## So gehst du vor
1. **Session-Konsistenz-Sektion** (`create_session_consistency_section`)
im Dashboard öffnen - sie listet konkrete Session-IDs ohne
`session_start` oder ohne `page_view`.
2. Bei Bot-Verdacht **Event-Frequenz-Histogramm** prüfen - Sessions mit
>100 Events/min sind verdächtig.
3. **Bots aktiv ausfiltern**: In der GA4-Admin-UI unter *Data Streams →
Configure tag settings → List unwanted referrals* werden zwar nur
Referrer ausgeschlossen - Bot-Traffic muss zusätzlich über IP-Filter
oder über serverseitige Validierung blockiert werden.
4. Bei `session_start`-Lücken den GTM-Trigger prüfen: Feuert der
GA4-Configuration-Tag wirklich auf jeder Seite vor allen Custom-Events?
## Verwandte Themen
- [Ampel-Checks aus BigQuery](/de/hilfe/ampel-checks-bigquery)
- [Event-Qualität & PII-Hinweise](/de/hilfe/event-qualitaet)
- [Server-Side-Tracking-Analyse](/de/hilfe/sst-analyse)
- [Tracking-Debugger Schritt für Schritt](/de/hilfe/tracking-debug)
---
## Server-Side-Tracking-Analyse - der SST-Score
- URL: https://ga4-auditor.dev/de/hilfe/sst-analyse
- lang: de
- updated: 2026-05-19
- description: Wie der Auditor einen Score (0-100) für den Nutzen von Server-Side-Tracking berechnet - Cookie-Lifetime, Attribution-Gap, Funnel-Dauer und Cross-Domain.
Server-Side-Tracking (SST) ist eine technische Antwort auf Browser-Limits:
Cookies sind kürzer, Werbeblocker greifen tiefer, Cross-Device-Tracking
zerfällt. Die SST-Analyse im Auditor zeigt, ob die Umstellung sich für
deine Property überhaupt lohnt - und wenn ja, wie groß der erwartete
Hebel ist.
## Was prüft die App?
Die SST-Analyse berechnet einen **gewichteten Score zwischen 0 und 100**
aus fünf Einzelchecks und zeigt die Implikationen pro Bereich:
- **Cookie-Lifetime-Impact** - wie unterscheiden sich Returning-Rates
zwischen Safari (kurze Cookies) und Chrome?
- **Attribution-Gap** - wie viele Sessions und Key Events landen ohne
saubere Quelle?
- **Funnel-Duration** - wie viele Tage liegen typischerweise zwischen
Erstkontakt und Conversion?
- **Cross-Domain** - wie viele unterschiedliche Domains sind beteiligt?
- **SST-Detection** - gibt es bereits Hinweise im `user_pseudo_id`-Muster,
dass eine SST-Implementierung läuft?
## Wann wird ein Check ausgelöst?
| Komponente | Gewicht | Schwelle |
|---|---|---|
| Cookie-Lifetime-Impact | 35 % | Safari-vs.-Chrome-Returning-Rate-Delta |
| Attribution-Gap | 35 % | Unattribuierte Sessions/Key Events |
| Funnel-Duration | 20 % | Tage bis Conversion |
| Cross-Domain | 10 % | Anzahl Domains |
| SST-Detection | - | `user_pseudo_id`-Muster |
Score-Ampel: **>70 = Grün**, **40-70 = Gelb**, **<40 = Rot**. Zusätzlich
flaggt der Check eine SST-Event-Coverage unter 50 % der Web-Events als
Warnung und einen Cookieless-Anteil >20 % als Risiko.
Die Logik liegt in [`app/pages/serverside_tracking.py`](app/pages/serverside_tracking.py),
[`app/services/sst_check_service.py`](app/services/sst_check_service.py) und im
OnPage-Detektor [`app/services/sst/_check_sst_detection_onpage.py`](app/services/sst/_check_sst_detection_onpage.py).
## Typische Ursachen für niedrige Scores
- **Unvollständige SST-Implementierung** - Web feuert mehr Events als die
Server-Endpoint-Variante, Coverage <50 % der Web-Events.
- **Attribution-Mismatch** - SST sendet andere Quelle/Medium-Kombination
als die Web-Events (z. B. Header-basierte UTM-Rekonstruktion vs.
Frontend-Parameter).
- **Cookie-Lifetime-Problem** - SST setzt nur kurze Erstanbieter-Cookies
(z. B. 24 h), Web nutzt 2-Jahres-Cookies. Session-Zerfall ist die Folge.
## So gehst du vor
1. **SST-Tab im Dashboard** öffnen - der Gesamt-Score steht oben, darunter
die fünf Teilscores mit Erklärung.
2. Bei niedrigem Cookie-Lifetime-Score: Safari- und Chrome-Returning-Rates
nebeneinander betrachten. Großes Delta = SST hilft.
3. Bei hohem Attribution-Gap: parallel
[Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
prüfen - manchmal ist die Lösung kein SST, sondern eine bessere
Referral-Exclusion.
4. Vor jeder SST-Investition den **OnPage-Check** laufen lassen
([OnPage-Checks - Browser-basiertes Audit](/de/hilfe/onpage-checks)),
um zu sehen, ob die Site überhaupt mit Custom-Endpoints und FPID-Cookie
antwortet.
## Verwandte Themen
- [Live Check - schnelle GA4-API-Diagnose](/de/hilfe/live-check)
- [Attribution & Akquisitions-Qualität](/de/hilfe/attribution-akquisition)
- [OnPage-Checks - Browser-basiertes Audit](/de/hilfe/onpage-checks)
- [Video-Anleitungen zum GA4 Auditor](/de/blog/videobeitraege-uebersicht) (Video 2 zeigt den SST-Check)
---
## Tracking-Debugger Schritt für Schritt
- URL: https://ga4-auditor.dev/de/hilfe/tracking-debug
- lang: de
- updated: 2026-05-12
- description: So findest und behebst du Tracking-Fehler mit dem GA4 Auditor.
Der Tracking-Debugger im GA4 Auditor zeigt dir genau, welche **Events**
deine Property heute aktiv empfängt. Diese Seite erklärt die wichtigsten
Schritte.
## Erste Schritte
Öffne den Tracking-Debugger im Dashboard unter dem Punkt "Live Check". Dort
siehst du eine Liste aller eingehenden Events pro Stream.
## Consent Mode
Wenn dein Tracking nach **Consent Mode v2** arbeitet, achte besonders auf die
`gtag('consent')`-Calls vor jedem Event. Fehlt der Consent-Aufruf, werden
deine Events zwar an Google geschickt, aber nicht gezählt.
## DataLayer-Grundlagen
Im **DataLayer** sammelst du serverseitig oder im Frontend strukturierte
Events. GA4 Auditor liest den DataLayer und prüft, ob die Events
spec-konform sind.
## Bekannte Probleme
- `gtag('event', 'page_view')` ohne Page-Title
- Fehlende `transaction_id` bei `purchase`-Events
- Falsches Currency-Format
---
## Tracking debugger walkthrough
- URL: https://ga4-auditor.dev/en/help/tracking-debug
- lang: en
- updated: 2026-05-12
- description: How to find and fix tracking errors with GA4 Auditor.
The tracking debugger in GA4 Auditor shows you exactly which **events** are
arriving in your property right now.
## Getting started
Open the tracking debugger in the dashboard under "Live Check". You will see
a live list of incoming events per stream.
## Consent Mode
If your tracking runs in **Consent Mode v2**, watch for `gtag('consent')`
calls before each event. Without consent, events are still sent to Google but
won't be counted.
## DataLayer basics
The **DataLayer** collects structured events. GA4 Auditor reads the
DataLayer and validates the events against the GA4 spec.
---