{"id":9301,"date":"2026-08-09T15:37:06","date_gmt":"2026-08-09T13:37:06","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/werkzeuge\/ga4-anomaly-detector\/"},"modified":"2026-08-28T16:15:11","modified_gmt":"2026-08-28T14:15:11","slug":"ga4-anomaly-detector","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/","title":{"rendered":"GA4-Anomalieerkennung"},"content":{"rendered":"<p><script src=\"https:\/\/accounts.google.com\/gsi\/client\" async defer><\/script><\/p>\n<div class=\"ga4-anomaly-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<div class=\"lw-aussenhinweis\" style=\"background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-left: 3px solid #fbbf24; border-radius: 6px; padding: 14px 16px; margin-bottom: 20px;\">\n<div style=\"color: #fbbf24; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 6px;\">Ben\u00f6tigt eine Google-Anmeldung<\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin: 0 0 8px; font-size: 0.9rem; line-height: 1.55;\">Anders als die \u00fcbrigen Werkzeuge hier arbeitet dieses nicht f\u00fcr sich allein. Es liest aus der Google Analytics Data API v1 und verlangt daf\u00fcr eine Anmeldung bei Google. Das angeforderte Recht lautet analytics.readonly und ist ausschlie\u00dflich lesend \u2014 \u00e4ndern l\u00e4sst sich dar\u00fcber nichts.<\/p>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin: 0; font-size: 0.9rem; line-height: 1.55;\">Was geholt wird, bleibt in dieser Registerkarte: Die Auswertung l\u00e4uft im Browser, an lukaswojcik.com geht nichts. Die unten vorbelegte OAuth-Client-ID l\u00e4sst sich durch eine eigene ersetzen.<\/p>\n<\/div>\n<p style=\"color: var(--text-secondary); margin-bottom: 20px; line-height: 1.6;\">\n        Verbindet sich \u00fcber OAuth 2.0 direkt mit der <strong>Google Analytics Data API v1<\/strong>, um die Standardmetriken einer Property auf statistische Auff\u00e4lligkeiten, pl\u00f6tzliche Zugriffsspitzen oder Messausf\u00e4lle zu untersuchen.<br \/>\n        S\u00e4mtliche Berechnungen der Z-Werte laufen lokal im Browser &mdash; es werden keinerlei Analysedaten gespeichert oder an unsere Server \u00fcbertragen.\n    <\/p>\n<p>    <!-- SCHRITT 1: OAUTH UND ANMELDUNG --><\/p>\n<div style=\"background: var(--bg-body, #101416); padding: 20px; border-radius: 8px; border: 1px solid var(--border); margin-bottom: 20px;\">\n<h3 style=\"color: var(--accent); font-size: 1rem; margin-top: 0; margin-bottom: 12px;\">1. Anmeldung an der Google Analytics API<\/h3>\n<div style=\"display: flex; gap: 15px; flex-wrap: wrap; align-items: flex-end;\">\n<div style=\"flex: 1; min-width: 280px;\">\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Google Cloud OAuth-Client-ID:<\/label><br \/>\n                <input type=\"text\" id=\"ga4-client-id\" value=\"423029313598-2ko0jilc28eevp253rqncvodg2181e1l.apps.googleusercontent.com\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); border: 1px solid var(--border); color: var(--text-primary); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <button id=\"ga4-auth-btn\" class=\"button\" style=\"background: var(--accent); color: var(--on-accent); border: none; padding: 11px 22px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Mit Google autorisieren<\/button>\n            <\/div>\n<\/p><\/div>\n<div data-mp-mask id=\"ga4-auth-status\" style=\"margin-top: 10px; font-size: 0.85rem; color: var(--text-secondary);\">Status: <strong style=\"color: #ff6b6b;\">Nicht verbunden<\/strong><\/div>\n<\/p><\/div>\n<p>    <!-- SCHRITT 2: PROPERTY UND PRUEFLAUF EINSTELLEN --><\/p>\n<div id=\"ga4-config-panel\" style=\"background: var(--bg-body); padding: 20px; border-radius: 8px; border: 1px solid var(--border); margin-bottom: 20px; display: none;\">\n<h3 style=\"color: var(--accent); font-size: 1rem; margin-top: 0; margin-bottom: 12px;\">2. Property und Anomaliepr\u00fcfung einstellen<\/h3>\n<div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 15px;\">\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">GCP-Projekt (Referenz):<\/label><br \/>\n                <input type=\"text\" id=\"gcp-project-id\" value=\"lukaswojcik\" placeholder=\"lukaswojcik\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">GA4-Property-ID (numerisch):<\/label><br \/>\n                <input type=\"text\" id=\"ga4-property-id\" placeholder=\"z. B. 345678901\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px; font-family: monospace;\">\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Basiszeitraum:<\/label><br \/>\n                <select id=\"ga4-timeframe\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px;\"><option value=\"30daysAgo\" selected>Letzte 30 Tage (empfohlen)<\/option><option value=\"60daysAgo\">Letzte 60 Tage<\/option><option value=\"90daysAgo\">Letzte 90 Tage<\/option><\/select>\n            <\/div>\n<div>\n                <label style=\"color: var(--text-secondary); display: block; font-size: 0.85rem; margin-bottom: 6px;\">Empfindlichkeit (Schwelle des Z-Werts):<\/label><br \/>\n                <select id=\"ga4-sensitivity\" style=\"width: 100%; padding: 10px; background: var(--bg-panel); color: var(--text-primary); border: 1px solid var(--border); border-radius: 6px;\"><option value=\"1.8\">Hohe Empfindlichkeit (&plusmn;1,8&sigma;)<\/option><option value=\"2.0\" selected>Unternehmensstandard (&plusmn;2,0&sigma;)<\/option><option value=\"2.5\">Streng \/ Major Deviations Only (&plusmn;2.5&sigma;)<\/option><\/select>\n            <\/div>\n<\/p><\/div>\n<div style=\"display: flex; justify-content: flex-end;\">\n            <button id=\"run-anomaly-scan-btn\" class=\"button\" style=\"background: var(--accent); color: var(--on-accent); border: none; padding: 11px 26px; border-radius: 6px; font-weight: 700; cursor: pointer;\">GA4-Metriken auf Anomalien pr\u00fcfen<\/button>\n        <\/div>\n<\/p><\/div>\n<p>    <!-- STATUS- UND UEBERSICHTSLEISTE --><\/p>\n<div data-mp-mask id=\"anomaly-summary-bar\" style=\"margin-bottom: 20px;\"><\/div>\n<p>    <!-- BEHAELTER FUER DIE ERGEBNISSE --><\/p>\n<div data-mp-mask id=\"anomaly-results-container\"><\/div>\n<\/div>\n<p><script>\n(() => {\n    let accessToken = null;\n    let tokenClient = null;<\/p>\n<p>    const authBtn = document.getElementById(\"ga4-auth-btn\");\n    const authStatus = document.getElementById(\"ga4-auth-status\");\n    const configPanel = document.getElementById(\"ga4-config-panel\");\n    const runScanBtn = document.getElementById(\"run-anomaly-scan-btn\");\n    const summaryBar = document.getElementById(\"anomaly-summary-bar\");\n    const resultsContainer = document.getElementById(\"anomaly-results-container\");<\/p>\n<p>    const esc = (str) => String(str).replace(\/&\/g, \"&amp;\").replace(\/<\/g, \"&lt;\").replace(\/>\/g, \"&gt;\");<\/p>\n<p>    \/\/ AUSGEWERTETE METRIKEN (name = API-Feld, unveraendert; label = Anzeigetext)\n    const TRACKED_METRICS = [\n        { name: \"sessions\", label: \"Sitzungen\", isRate: false },\n        { name: \"totalUsers\", label: \"Nutzer insgesamt\", isRate: false },\n        { name: \"screenPageViews\", label: \"Seitenaufrufe\", isRate: false },\n        { name: \"conversions\", label: \"Conversions\", isRate: false },\n        { name: \"eventCount\", label: \"Anzahl Ereignisse\", isRate: false },\n        { name: \"totalRevenue\", label: \"Gesamtumsatz\", isRate: false },\n        { name: \"engagementRate\", label: \"Interaktionsrate\", isRate: true }\n    ];<\/p>\n<p>    \/\/ Beschriftungen getrennt von SPIKE\/DROP, damit der Vergleich\n    \/\/ a.type === \"SPIKE\" und die Einfaerbung von der Uebersetzung unberuehrt bleiben\n    const TYPE_LABELS = {\n        SPIKE: \"&uarr; AUSSCHLAG (+Anomalie)\",\n        DROP: \"&darr; EINBRUCH (-Anomalie)\"\n    };<\/p>\n<p>    \/\/ 1. OAUTH-2.0-INITIALISIERUNG\n    authBtn.addEventListener(\"click\", () => {\n        const clientId = document.getElementById(\"ga4-client-id\").value.trim();\n        if (!clientId) {\n            alert(\"Bitte eine g\u00fcltige Google Cloud Client-ID eingeben.\");\n            return;\n        }<\/p>\n<p>        if (!window.google || !google.accounts || !google.accounts.oauth2) {\n            alert(\"Das Skript von Google Identity Services wird noch geladen. Bitte in einem Moment erneut versuchen.\");\n            return;\n        }<\/p>\n<p>        tokenClient = google.accounts.oauth2.initTokenClient({\n            client_id: clientId,\n            scope: \"https:\/\/www.googleapis.com\/auth\/analytics.readonly\",\n            callback: (resp) => {\n                if (resp.error) {\n                    authStatus.innerHTML = \"Status: <strong style='color:#ff6b6b;'>Anmeldefehler: \" + esc(resp.error) + \"<\/strong>\";\n                    return;\n                }\n                accessToken = resp.access_token;\n                authStatus.innerHTML = \"Status: <strong style='color:#51cf66;'>Verbunden (Analytics, nur Lesezugriff)<\/strong>\";\n                configPanel.style.display = \"block\";\n            }\n        });\n        tokenClient.requestAccessToken();\n    });<\/p>\n<p>    \/\/ 2. STATISTISCHE ANOMALIEERKENNUNG (Z-WERT)\n    const calculateStats = (values) => {\n        const n = values.length;\n        if (n === 0) return { mean: 0, stdev: 0 };\n        const mean = values.reduce((acc, v) => acc + v, 0) \/ n;\n        const variance = values.reduce((acc, v) => acc + Math.pow(v - mean, 2), 0) \/ n;\n        return { mean: mean, stdev: Math.sqrt(variance) };\n    };<\/p>\n<p>    const formatDateStr = (dateStr) => {\n        if (dateStr.length === 8) {\n            return dateStr.substring(0, 4) + \"-\" + dateStr.substring(4, 6) + \"-\" + dateStr.substring(6, 8);\n        }\n        return dateStr;\n    };<\/p>\n<p>    const getBadgeHtml = (type) => {\n        if (type === \"SPIKE\") {\n            return \"<span style='background:#18382b; color:#51cf66; padding:4px 10px; border-radius:4px; font-size:0.75rem; font-weight:700; text-transform:uppercase;'>\" + TYPE_LABELS.SPIKE + \"<\/span>\";\n        }\n        return \"<span style='background:#471a1a; color:#ff6b6b; padding:4px 10px; border-radius:4px; font-size:0.75rem; font-weight:700; text-transform:uppercase;'>\" + TYPE_LABELS.DROP + \"<\/span>\";\n    };<\/p>\n<p>    \/\/ 3. BERICHT UEBER DIE GA4 DATA API ABRUFEN\n    runScanBtn.addEventListener(\"click\", async () => {\n        const propertyId = document.getElementById(\"ga4-property-id\").value.trim().replace(\/^properties\\\/\/i, \"\");\n        const timeframe = document.getElementById(\"ga4-timeframe\").value;\n        const zThreshold = parseFloat(document.getElementById(\"ga4-sensitivity\").value) || 2.0;<\/p>\n<p>        if (!propertyId || isNaN(propertyId)) {\n            alert(\"Bitte eine g\u00fcltige numerische GA4-Property-ID eingeben (z. B. 345678901).\");\n            return;\n        }<\/p>\n<p>        runScanBtn.disabled = true;\n        runScanBtn.textContent = \"GA4-Zeitreihen werden gepr\u00fcft ...\";\n        summaryBar.innerHTML = \"\";\n        resultsContainer.innerHTML = \"\";<\/p>\n<p>        try {\n            \/\/ Tageswerte aller Standardmetriken bis gestern abrufen (der angebrochene heutige Tag bleibt aussen vor)\n            const response = await fetch(\"https:\/\/analyticsdata.googleapis.com\/v1beta\/properties\/\" + propertyId + \":runReport\", {\n                method: \"POST\",\n                headers: {\n                    \"Authorization\": \"Bearer \" + accessToken,\n                    \"Content-Type\": \"application\/json\"\n                },\n                body: JSON.stringify({\n                    dateRanges: [{ startDate: timeframe, endDate: \"yesterday\" }],\n                    dimensions: [{ name: \"date\" }],\n                    metrics: TRACKED_METRICS.map(m => ({ name: m.name })),\n                    orderBys: [{ dimension: { dimensionName: \"date\" } }],\n                    limit: 1000\n                })\n            });<\/p>\n<p>            if (!response.ok) {\n                const errJson = await response.json().catch(() => ({}));\n                const errMsg = errJson.error ? errJson.error.message : response.statusText;\n                throw new Error(errMsg);\n            }<\/p>\n<p>            const data = await response.json();\n            const rows = data.rows || [];\n            const daysScanned = rows.length;<\/p>\n<p>            if (daysScanned < 5) {\n                throw new Error(\"Es wurden zu wenige historische Tage zur\u00fcckgegeben (\" + daysScanned + \" Tage), um belastbare Z-Werte zu berechnen.\");\n            }\n\n            const anomalies = [];\n\n            \/\/ Jede Metrik f\u00fcr sich auswerten\n            TRACKED_METRICS.forEach((metric, idx) => {\n                const dailySeries = rows.map(r => ({\n                    date: r.dimensionValues[0].value,\n                    val: parseFloat(r.metricValues[idx].value || 0)\n                }));<\/p>\n<p>                const values = dailySeries.map(item => item.val);\n                const stats = calculateStats(values);<\/p>\n<p>                \/\/ Unver\u00e4nderliche Metriken \u00fcberspringen (stdev = 0 oder nahe 0)\n                if (stats.stdev <= 0.0001) return;\n\n                dailySeries.forEach(item => {\n                    const zScore = (item.val - stats.mean) \/ stats.stdev;\n                    if (Math.abs(zScore) >= zThreshold) {\n                        const devPct = stats.mean > 0 ? ((item.val - stats.mean) \/ stats.mean) * 100 : 0;\n                        anomalies.push({\n                            metricName: metric.label,\n                            isRate: metric.isRate,\n                            date: formatDateStr(item.date),\n                            value: item.val,\n                            mean: stats.mean,\n                            stdev: stats.stdev,\n                            zScore: zScore,\n                            devPct: devPct,\n                            type: zScore > 0 ? \"SPIKE\" : \"DROP\"\n                        });\n                    }\n                });\n            });<\/p>\n<p>            \/\/ 4. \u00dcBERSICHT UND ERGEBNISSE AUSGEBEN\n            summaryBar.innerHTML = [\n                \"<\/p>\n<div style='background:var(--bg-body); padding:16px 20px; border-radius:8px; border:1px solid var(--border); display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:15px;'>\",\n                \"  <\/p>\n<div>\",\n                \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Gepr\u00fcfte GA4-Metriken<\/span>\",\n                \"    <strong style='color:var(--accent); font-size:1.4rem;'>\" + TRACKED_METRICS.length + \" Standardmetriken<\/strong>\",\n                \"  <\/div>\n<p>\",\n                \"  <\/p>\n<div>\",\n                \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Betrachteter Zeitraum<\/span>\",\n                \"    <strong style='color:var(--text-primary); font-size:1.4rem;'>\" + daysScanned + \" volle Tage<\/strong>\",\n                \"  <\/div>\n<p>\",\n                \"  <\/p>\n<div>\",\n                \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Gefundene Anomalien<\/span>\",\n                \"    <strong style='color:\" + (anomalies.length > 0 ? \"#ff922b\" : \"#51cf66\") + \"; font-size:1.4rem;'>\" + anomalies.length + \" Ereignisse<\/strong>\",\n                \"  <\/div>\n<p>\",\n                \"<\/p><\/div>\n<p>\"\n            ].join(\"\");<\/p>\n<p>            if (anomalies.length === 0) {\n                resultsContainer.innerHTML = \"<\/p>\n<div style='background:var(--bg-body); padding:30px; border-radius:8px; border:1px solid var(--border); text-align:center; color:#51cf66; font-weight:bold; font-size:1.1rem;'>\u2714 Alles unauff\u00e4llig: In \" + TRACKED_METRICS.length + \" Metriken der letzten \" + daysScanned + \" Tage wurden keine statistischen Auff\u00e4lligkeiten, Ausschl\u00e4ge oder Einbr\u00fcche gefunden!<\/div>\n<p>\";\n                return;\n            }<\/p>\n<p>            \/\/ Anomalien zuerst nach j\u00fcngstem Datum, dann nach Schwere des Z-Werts sortieren\n            anomalies.sort((a, b) => {\n                if (b.date !== a.date) return b.date.localeCompare(a.date);\n                return Math.abs(b.zScore) - Math.abs(a.zScore);\n            });<\/p>\n<p>            const cardsHtml = anomalies.map(a => {\n                const valFmt = a.isRate ? (a.value * 100).toFixed(2) + \"%\" : a.value.toLocaleString();\n                const meanFmt = a.isRate ? (a.mean * 100).toFixed(2) + \"%\" : Math.round(a.mean).toLocaleString();\n                const devSign = a.devPct >= 0 ? \"+\" : \"\";<\/p>\n<p>                return [\n                    \"<\/p>\n<div style='background:var(--bg-body); border:1px solid var(--border); border-radius:8px; padding:18px; margin-bottom:15px; display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:15px;'>\",\n                    \"  <\/p>\n<div style='min-width:220px;'>\",\n                    \"    <\/p>\n<div style='color:var(--text-secondary); font-size:0.8rem; text-transform:uppercase; font-weight:700; margin-bottom:4px;'>\" + esc(a.date) + \"<\/div>\n<p>\",\n                    \"    <strong style='color:var(--text-primary); font-size:1.15rem; display:block;'>\" + esc(a.metricName) + \"<\/strong>\",\n                    \"  <\/div>\n<p>\",\n                    \"  <\/p>\n<div style='text-align:right;'>\",\n                    \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Ist-Wert gegen\u00fcber erwartetem Mittel<\/span>\",\n                    \"    <strong style='color:var(--text-primary); font-size:1.1rem; font-family:monospace;'>\" + valFmt + \" <span style='color:var(--text-secondary); font-weight:normal; font-size:0.95rem;'> (Mittel: \" + meanFmt + \")<\/span><\/strong>\",\n                    \"  <\/div>\n<p>\",\n                    \"  <\/p>\n<div style='text-align:right;'>\",\n                    \"    <span style='color:var(--text-secondary); font-size:0.85rem; display:block;'>Abweichung (Z-Wert, &sigma;)<\/span>\",\n                    \"    <strong style='color:\" + (a.type === \"SPIKE\" ? \"#51cf66\" : \"#ff6b6b\") + \"; font-size:1.1rem; font-family:monospace;'>\" + devSign + a.devPct.toFixed(1) + \"% (\" + a.zScore.toFixed(2) + \"&sigma;)<\/strong>\",\n                    \"  <\/div>\n<p>\",\n                    \"  <\/p>\n<div>\" + getBadgeHtml(a.type) + \"<\/div>\n<p>\",\n                    \"<\/p><\/div>\n<p>\"\n                ].join(\"\");\n            }).join(\"\");<\/p>\n<p>            resultsContainer.innerHTML = [\n                \"<\/p>\n<h3 style='color:var(--text-primary); margin-bottom:15px; font-size:1.15rem;'>Erkannte Auff\u00e4lligkeiten in den Daten (\" + anomalies.length + \")<\/h3>\n<p>\",\n                cardsHtml\n            ].join(\"\");<\/p>\n<p>        } catch (e) {\n            resultsContainer.innerHTML = \"<\/p>\n<div style='background:var(--bg-body); padding:25px; border-radius:8px; border:1px solid #ff6b6b; color:#ff6b6b; font-weight:bold;'>Fehler der GA4-API: \" + esc(e.message) + \"<\/div>\n<p>\";\n        } finally {\n            runScanBtn.disabled = false;\n            runScanBtn.textContent = \"GA4-Metriken auf Anomalien pr\u00fcfen\";\n        }\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Verbindet sich per OAuth mit der Google Analytics Data API und findet \u00fcber den Z-Wert auff\u00e4llige Ausschl\u00e4ge und Einbr\u00fcche in den GA4-Standardmetriken.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":9283,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[92088,92091],"class_list":["post-9301","page","type-page","status-publish","hentry","tag-data-quality-de","tag-google-analytics-4-de"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GA4-Anomalieerkennung - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GA4-Anomalieerkennung - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Verbindet sich per OAuth mit der Google Analytics Data API und findet \u00fcber den Z-Wert auff\u00e4llige Ausschl\u00e4ge und Einbr\u00fcche in den GA4-Standardmetriken.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-28T14:15:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-anomaly-detector\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-anomaly-detector\\\/\",\"name\":\"GA4-Anomalieerkennung - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-09T13:37:06+00:00\",\"dateModified\":\"2026-08-28T14:15:11+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-anomaly-detector\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-anomaly-detector\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/ga4-anomaly-detector\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/toolbox-2\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"GA4-Anomalieerkennung\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"GA4-Anomalieerkennung - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/","og_locale":"en_US","og_type":"article","og_title":"GA4-Anomalieerkennung - Lukas Wojcik - Blog","og_description":"Verbindet sich per OAuth mit der Google Analytics Data API und findet \u00fcber den Z-Wert auff\u00e4llige Ausschl\u00e4ge und Einbr\u00fcche in den GA4-Standardmetriken.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-08-28T14:15:11+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/","url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/","name":"GA4-Anomalieerkennung - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-09T13:37:06+00:00","dateModified":"2026-08-28T14:15:11+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/ga4-anomaly-detector\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/toolbox-2\/"},{"@type":"ListItem","position":3,"name":"GA4-Anomalieerkennung"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9301","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=9301"}],"version-history":[{"count":6,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9301\/revisions"}],"predecessor-version":[{"id":13093,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9301\/revisions\/13093"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9283"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=9301"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=9301"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}