{"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-09T15:37:06","modified_gmt":"2026-08-09T13:37:06","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<p style=\"color: var(--text-secondary); margin-bottom: 20px; line-height: 1.6;\">\n        Verbinden Sie 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 in Ihrem 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: #0b1114; border: none; padding: 11px 22px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Mit Google autorisieren<\/button>\n            <\/div>\n<\/p><\/div>\n<div 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 \/ nur starke Abweichungen (&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: #0b1114; 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 id=\"anomaly-summary-bar\" style=\"margin-bottom: 20px;\"><\/div>\n<p>    <!-- BEHAELTER FUER DIE ERGEBNISSE --><\/p>\n<div 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>    \/\/ Anzeigetexte getrennt vom Schluessel 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 geben Sie eine g\u00fcltige Google Cloud Client-ID ein.\");\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 versuchen Sie es in einem Moment erneut.\");\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 geben Sie eine g\u00fcltige numerische GA4-Property-ID ein (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":""},"class_list":["post-9301","page","type-page","status-publish","hentry"],"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=\"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\",\"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\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/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","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","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":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_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":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9301\/revisions"}],"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"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}