{"id":17207,"date":"2026-10-10T12:30:00","date_gmt":"2026-10-10T10:30:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=17207"},"modified":"2026-10-09T22:41:29","modified_gmt":"2026-10-09T20:41:29","slug":"ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/","title":{"rendered":"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet"},"content":{"rendered":"<p>Eine Measurement-Protocol-Anfrage ist ein einziger HTTPS-POST: eine Abfragezeichenfolge mit zwei Zugangsdaten und ein JSON-Rumpf mit den Ereignissen. So kommen Daten in eine GA4-Property, die nicht aus einem Browser stammen \u2014 Offline-Conversions aus einem CRM, eine per Webhook best\u00e4tigte Zahlung, ein App-Backend, das Nachreichen von Treffern, die ein Werbeblocker verschluckt hat.<\/p>\n<p>Es ist zugleich der einzige Einlieferungsweg im ganzen Aufbau, der nie sagt, ob er funktioniert hat.<\/p>\n<figure class=\"lw-diagram\">\n<img decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/mp-nutzlast-de.png\" width=\"1120\" height=\"580\" loading=\"lazy\" alt=\"Links der Aufbau einer Measurement-Protocol-Nutzlast mit den dokumentierten Grenzen, rechts eine Tabelle mit neun absichtlich fehlerhaften Anfragen und dem Statuscode, mit dem der Produktivendpunkt jeweils geantwortet hat\"><figcaption>Woraus eine Nutzlast besteht und was der Produktivendpunkt antwortet, wenn Teile davon falsch sind.<\/figcaption><\/figure>\n<h2>Was der Endpunkt antwortet<\/h2>\n<p>Neun Anfragen gingen am 9. September 2026 an <code>https:\/\/www.google-analytics.com\/mp\/collect<\/code>, alle mit einer erfundenen Mess-ID, damit nirgends etwas erfasst werden konnte. Sieben davon waren absichtlich kaputt.<\/p>\n<p>Acht der neun kamen als <strong>204 No Content<\/strong> zur\u00fcck, in rund 100 Millisekunden und mit leerem Rumpf. Nicht nur die g\u00fcltige: auch das Ereignis, dessen Name mit einem Unterstrich beginnt, das leere <code>events<\/code>-Array, die Nutzlast mit einem erfundenen Feld ganz oben, die Anfrage ohne <code>client_id<\/code> und ein Rumpf, der \u00fcberhaupt kein JSON war. Eine Anfrage <strong>ganz ohne Abfragezeichenfolge<\/strong> \u2014 ohne Mess-ID, ohne API-Geheimnis \u2014 kam ebenfalls mit 204 zur\u00fcck.<\/p>\n<p>Genau zwei Dinge erzeugten einen HTTP-Fehler, und keines davon ist ein Urteil \u00fcber die Nutzlast. Ein Rumpf von 140 kB wurde mit <strong>413<\/strong> und einer HTML-Fehlerseite des Vorbaus abgelehnt, weil er die dokumentierte Grenze von 130 kB \u00fcberschritt, bevor \u00fcberhaupt etwas gelesen wurde. Ein <code>GET<\/code> wurde mit <strong>405<\/strong> abgelehnt.<\/p>\n<p>Der europ\u00e4ische Endpunkt <code>region1.google-analytics.com<\/code> verh\u00e4lt sich gleich. \u00dcber je f\u00fcnf L\u00e4ufe lag die Umlaufzeit vom selben Server bei beiden Hosts im Mittel bei 90 Millisekunden.<\/p>\n<p>Der Antwortcode best\u00e4tigt also nur, dass die Anfrage angekommen ist. Ob das Ereignis verstanden und gespeichert wurde oder ein Parameter verloren ging, l\u00e4sst sich daraus nicht erkennen. Beim Senden bleiben diese Probleme unsichtbar; erst Stunden sp\u00e4ter fallen sie als fehlende Daten im Bericht auf.<\/p>\n<h2>Wohin die Nutzlast wirklich geh\u00f6rt<\/h2>\n<p>Zwei Teile, und die Verwechslung liegt nahe.<\/p>\n<p>Die <strong>Abfragezeichenfolge<\/strong> tr\u00e4gt die Zugangsdaten: <code>measurement_id<\/code> f\u00fcr einen Web-Datenstrom (oder <code>firebase_app_id<\/code> f\u00fcr einen App-Datenstrom) und <code>api_secret<\/code>, das je Datenstrom in der GA4-Verwaltung angelegt wird. Keines von beiden geh\u00f6rt ins JSON. Dort werden sie zu unbekannten Feldern, und ein unbekanntes Feld wird nicht \u00fcbergangen \u2014 es macht die gesamte Nutzlast unlesbar.<\/p>\n<p>Der <strong>Rumpf<\/strong> ist ein JSON-Objekt mit einem festen Satz erlaubter Schl\u00fcssel:<\/p>\n<pre><code>{\n  \"client_id\": \"1234567890.1700000000\",\n  \"user_id\": \"crm-88213\",\n  \"timestamp_micros\": 1788000000000000,\n  \"consent\": { \"ad_user_data\": \"GRANTED\", \"ad_personalization\": \"DENIED\" },\n  \"user_properties\": { \"kundenstufe\": { \"value\": \"gold\" } },\n  \"events\": [\n    {\n      \"name\": \"purchase\",\n      \"params\": {\n        \"transaction_id\": \"T-8891\",\n        \"currency\": \"EUR\",\n        \"value\": 20,\n        \"session_id\": \"1700000000\",\n        \"engagement_time_msec\": 100,\n        \"items\": [\n          { \"item_id\": \"A-1\", \"item_name\": \"Hemd\", \"price\": 10, \"quantity\": 2 }\n        ]\n      }\n    }\n  ]\n}<\/code><\/pre>\n<p>Daneben erlaubt die Referenz <code>user_data<\/code>, <code>user_location<\/code>, <code>ip_override<\/code>, <code>device<\/code>, <code>user_agent<\/code>, <code>non_personalized_ads<\/code> und <code>validation_behavior<\/code>. Das ist die vollst\u00e4ndige Liste. Alles andere \u2014 ein aus einem dataLayer-Objekt mitkopierter <code>event<\/code>-Schl\u00fcssel, eine <code>ecommerce<\/code>-H\u00fclle, eine Notiz f\u00fcr die Kollegin \u2014 kostet die ganze Anfrage.<\/p>\n<h2>Die Kennungsfelder<\/h2>\n<p><code>client_id<\/code> ist auf einem Web-Datenstrom Pflicht und das eine Feld, das entscheidet, ob ein Ereignis zu einem vorhandenen Nutzer st\u00f6\u00dft oder einen neuen erfindet. Die empfohlene Form sind zwei positive Zahlen, durch einen Punkt verbunden \u2014 genau das, was <code>gtag('get')<\/code> herausgibt und was die eingebaute Variable Analytics Client ID im Google Tag Manager liefert. Der volle Wert des <code>_ga<\/code>-Cookies, <code>GA1.1.1234567890.1700000000<\/code>, wird ebenfalls angenommen; die beiden Zahlen stecken darin.<\/p>\n<p>Ein auf dem Server erfundener Wert wird auch angenommen, und das ist der teure Fehler. Eine frische Kennung je Anfrage erzeugt jedes Mal einen frischen Nutzer und eine frische Sitzung \u2014 eine Property, die belebt aussieht und ausschlie\u00dflich aus Sitzungen mit je einem Ereignis besteht.<\/p>\n<p>App-Datenstr\u00f6me nutzen stattdessen <code>app_instance_id<\/code>: 32 hexadezimale Zeichen aus dem Firebase-SDK, keine client_id unter anderem Namen. Beides zu senden schadet nicht und n\u00fctzt nicht; das Feld der jeweils anderen Datenstromart wird \u00fcbergangen.<\/p>\n<p><code>user_id<\/code> ist freiwillig, bis zu 256 Zeichen lang und muss eine Zeichenkette sein. Es ist ein Verkn\u00fcpfungsschl\u00fcssel, keine Person: Eine Mailadresse oder eine Telefonnummer in diesem Feld ist ein personenbezogenes Datum, was die Nutzungsbedingungen von Google Analytics verbieten und was als Grund f\u00fcr die L\u00f6schung einer Property gen\u00fcgt. Dasselbe gilt f\u00fcr jeden Ereignisparameter und jede Nutzereigenschaft.<\/p>\n<h2>Die zwei Parameter, an denen h\u00e4ngt, ob die Berichte aufgehen<\/h2>\n<p>Ein Ereignis ohne <code>session_id<\/code> geh\u00f6rt zu keiner Sitzung. Gespeichert und z\u00e4hlbar ist es trotzdem, aber Sitzungen, engagierte Sitzungen und die sitzungsbezogenen Dimensionen gehen nicht auf, und in der Echtzeit fehlt das Ereignis unter Umst\u00e4nden ganz.<\/p>\n<p>Ein Ereignis ohne <code>engagement_time_msec<\/code> tr\u00e4gt nichts zur durchschnittlichen Interaktionsdauer bei, die f\u00fcr den so eingelieferten Verkehr dann bei null steht.<\/p>\n<p>Beides ist nicht Pflicht, beides erzeugt nirgends eine Warnung, und beides ist die \u00fcbliche Antwort auf \u201edie Ereignisse kommen an, aber der Bericht stimmt nicht&#8221;. <code>session_id<\/code> muss eine positive Ganzzahl sein \u2014 im Regelfall ein Zeitstempel \u2014 und darf als Zahl oder als Ziffernkette gesendet werden. Buchstaben darin werden abgelehnt.<\/p>\n<h2>Das Ereignis und sein Name<\/h2>\n<p>Ein Ereignis ist ein Objekt mit genau zwei erlaubten Schl\u00fcsseln, <code>name<\/code> und <code>params<\/code>. Ein Zeitstempel, der als dritter Schl\u00fcssel danebengesetzt wird, macht die Nutzlast kaputt; der Zeitstempel je Ereignis geh\u00f6rt als <code>timestamp_micros<\/code> in die <code>params<\/code>.<\/p>\n<p>Namen m\u00fcssen mit einem Buchstaben beginnen und d\u00fcrfen nur Buchstaben, Ziffern und Unterstriche enthalten. Bindestriche, Punkte und Leerzeichen werden rundweg abgelehnt. Namen unterscheiden <strong>Gro\u00df- und Kleinschreibung<\/strong>, und das ist der stille Fall: <code>Purchase<\/code> wird angenommen, wird gespeichert und ist ein anderes Ereignis als <code>purchase<\/code> \u2014 in den E-Commerce-Berichten taucht es nie auf, weil die am kleingeschriebenen Namen h\u00e4ngen.<\/p>\n<p>Einunddrei\u00dfig Namen beh\u00e4lt Google f\u00fcr sich, darunter <code>session_start<\/code>, <code>first_visit<\/code>, <code>user_engagement<\/code>, <code>app_remove<\/code> und <code>error<\/code>. Drei weitere \u2014 <code>screen_view<\/code>, <code>ad_impression<\/code> und <code>in_app_purchase<\/code> \u2014 gibt es, sind aber nur auf App-Datenstr\u00f6men erlaubt. Auf einem Web-Datenstrom werden sie schlicht nicht erfasst, und niemand sagt das irgendwo.<\/p>\n<h2>Parameter und die Grenzen, die f\u00fcr sie gelten<\/h2>\n<p>Alle Grenzen des Protokolls an einer Stelle:<\/p>\n<table>\n<tr>\n<th>Was<\/th>\n<th>Grenze<\/th>\n<\/tr>\n<tr>\n<td>JSON-Rumpf<\/td>\n<td>unter 130 kB<\/td>\n<\/tr>\n<tr>\n<td>Ereignisse je Anfrage<\/td>\n<td>25<\/td>\n<\/tr>\n<tr>\n<td>Ereignisname<\/td>\n<td>40 Zeichen<\/td>\n<\/tr>\n<tr>\n<td>Parameter je Ereignis<\/td>\n<td>25<\/td>\n<\/tr>\n<tr>\n<td>Parametername<\/td>\n<td>40 Zeichen<\/td>\n<\/tr>\n<tr>\n<td>Parameterwert<\/td>\n<td>100 Zeichen, 500 bei einer Analytics-360-Property<\/td>\n<\/tr>\n<tr>\n<td>Nutzereigenschaften je Anfrage<\/td>\n<td>25<\/td>\n<\/tr>\n<tr>\n<td>Name einer Nutzereigenschaft<\/td>\n<td>24 Zeichen<\/td>\n<\/tr>\n<tr>\n<td>Wert einer Nutzereigenschaft<\/td>\n<td>36 Zeichen<\/td>\n<\/tr>\n<tr>\n<td><code>user_id<\/code><\/td>\n<td>256 Zeichen<\/td>\n<\/tr>\n<tr>\n<td>Items je Ereignis<\/td>\n<td>200<\/td>\n<\/tr>\n<tr>\n<td>Eigene Parameter je Item<\/td>\n<td>10<\/td>\n<\/tr>\n<tr>\n<td>R\u00fcckdatierung<\/td>\n<td>72 Stunden<\/td>\n<\/tr>\n<\/table>\n<p>Parameternamen d\u00fcrfen nicht mit <code>_<\/code>, <code>firebase_<\/code>, <code>ga_<\/code>, <code>google_<\/code> oder <code>gtag.<\/code> beginnen, und <code>firebase_conversion<\/code> ist rundweg reserviert. F\u00fcr Namen von Nutzereigenschaften gelten dieselben Pr\u00e4fixregeln und zus\u00e4tzlich f\u00fcnf reservierte Namen, von denen <code>user_id<\/code> derjenige ist, zu dem versehentlich gegriffen wird \u2014 die Nutzerkennung geh\u00f6rt ganz nach oben, nicht in <code>user_properties<\/code>.<\/p>\n<p>Nur <code>items<\/code> darf ein Array sein. Jeder andere Parameter nimmt einen Einzelwert; ein verschachteltes Objekt f\u00e4llt weg, und im Bericht erscheint der Parameter als fehlend statt als falsch.<\/p>\n<h2>Wo die beiden H\u00f6chstwerte aneinandergeraten<\/h2>\n<p>F\u00fcnfundzwanzig Ereignisse je Anfrage und zweihundert Items je Ereignis sind beide dokumentiert, und beide zusammen gehen nicht. Gemessen an erzeugten Nutzlasten mit realistischen Item-Feldern \u2014 Kennung, Name, Marke, Kategorie, Variante, Preis, Menge:<\/p>\n<ul>\n<li>Ein <code>purchase<\/code> mit einem Item, samt consent und Nutzereigenschaften, ist <strong>558 Byte<\/strong> gro\u00df.<\/li>\n<li>F\u00fcnfundzwanzig solcher Ereignisse ergeben rund <strong>14 kB<\/strong> und damit 10,7 % der Grenze.<\/li>\n<li>F\u00fcnfundzwanzig Ereignisse mit je <strong>29 Items<\/strong> \u00fcberschreiten 130 kB. Bei 28 Items sind es noch 126 kB.<\/li>\n<li>F\u00fcnfundzwanzig Ereignisse mit den erlaubten 200 Items w\u00e4ren 879 kB \u2014 das <strong>6,8-Fache<\/strong> der Grenze.<\/li>\n<\/ul>\n<p>Ein einzelnes Ereignis mit 200 Items ist 35 kB gro\u00df und passt bequem. F\u00fcr gew\u00f6hnlichen Verkehr bindet also die Ereigniszahl, und sobald die Warenk\u00f6rbe lang werden, \u00fcbernimmt die Gr\u00f6\u00dfengrenze. Der \u00dcbergang liegt bei rund 29 Items je Ereignis, und es ist die einzige Grenze, die mit einem HTTP-Fehler statt mit Schweigen antwortet.<\/p>\n<h2>Zeit und die drei Arten, sie falsch zu setzen<\/h2>\n<p><code>timestamp_micros<\/code> ist ein Unix-Zeitstempel in <strong>Mikrosekunden<\/strong>. Fehlt er, wird das Ereignis beim Eintreffen gestempelt, was f\u00fcr alles Gegenw\u00e4rtige richtig und f\u00fcr alles Nachgereichte falsch ist.<\/p>\n<p>Die Einheit ist die Falle. <code>time()<\/code> in PHP und <code>time.time()<\/code> in Python liefern Sekunden, <code>Date.now()<\/code> in JavaScript liefert Millisekunden. Beides wird als Zahl angenommen, und beides legt das Ereignis irgendwo ins Jahr 1970. Der Pr\u00fcfserver von Google meldet das zwar \u2014 als \u201etimestamp too far in the past&#8221;, eine Meldung, die zur Suche nach einem R\u00fcckdatierungsproblem f\u00fchrt, w\u00e4hrend der wirkliche Fehler ein Faktor von tausend oder einer Million ist.<\/p>\n<p>Das Fenster betr\u00e4gt 72 Stunden. \u00c4lteres wird verworfen, und Ereignisse mit <code>validation_behavior<\/code> auf <code>ENFORCE_RECOMMENDATIONS<\/code> werden abgelehnt statt stillschweigend fallengelassen. Ein Zeitstempel in der Zukunft hei\u00dft meist, dass eine Uhr nachgeht oder eine Zeitzone doppelt aufgeschlagen wurde.<\/p>\n<h2>consent und die Schl\u00fcssel, die nicht hierhergeh\u00f6ren<\/h2>\n<p>Das <code>consent<\/code>-Objekt nimmt genau zwei Schl\u00fcssel, <code>ad_user_data<\/code> und <code>ad_personalization<\/code>, jeweils <code>GRANTED<\/code> oder <code>DENIED<\/code>. Nicht <code>analytics_storage<\/code>, nicht <code>ad_storage<\/code> \u2014 das ist der Consent Mode im Browser, ein anderer Mechanismus mit einem anderen Wortschatz.<\/p>\n<p>Einen davon hier einzusetzen ist kein Teilausfall. Ein unbekannter Schl\u00fcssel in <code>consent<\/code>, oder ein anderer Wert als die beiden erlaubten, macht die Nutzlast unlesbar und die ganze Anfrage sinnlos. Ganz weggelassen greift GA4 auf den Einwilligungsstand aus den Browserinteraktionen desselben Clients zur\u00fcck, was f\u00fcr eine serverseitige Anbindung meist genau das Gew\u00fcnschte ist.<\/p>\n<p><code>non_personalized_ads<\/code> wirkt weiterhin und gilt als veraltet; <code>ad_personalization<\/code> innerhalb von <code>consent<\/code> l\u00f6st es ab.<\/p>\n<h2>validation_behavior und warum der Betrieb es nicht setzen sollte<\/h2>\n<p><code>validation_behavior<\/code> kennt zwei Werte. <code>RELAXED<\/code> ist die Vorgabe: Fehlerhafte Anfragen werden abgelehnt, aber Parameter \u00fcber den Grenzen werden \u00fcbergangen statt gemeldet, und Daten vom falschen Typ k\u00f6nnen trotzdem durchgehen. <code>ENFORCE_RECOMMENDATIONS<\/code> lehnt genau das ab.<\/p>\n<p>Die strenge Pr\u00fcfung geh\u00f6rt in den Test, weil eine Ablehnung dort hilft, Fehler zu finden. Im Betrieb sollte das Feld dagegen fehlen: Eine Ablehnung bedeutet hier verlorene Daten. Mit lockerer Pr\u00fcfung kommt ein Ereignis mit einem zu langen Parameter ohne diesen Parameter an. Mit strenger Pr\u00fcfung wird das gesamte Ereignis abgelehnt.<\/p>\n<h2>Wie sich ein Fehler \u00fcberhaupt finden l\u00e4sst<\/h2>\n<p>Weil der Produktivendpunkt nichts sagt, m\u00fcssen Fehler vor dem Senden gefunden werden. Der Pr\u00fcfserver von Google nimmt dieselbe Anfrage unter <code>\/debug\/mp\/collect<\/code> entgegen und antwortet mit einem <code>validationMessages<\/code>-Array; dorthin gesendete Ereignisse werden nie erfasst.<\/p>\n<p>Bevor Du Dich auf den Pr\u00fcfserver verl\u00e4sst, solltest Du zwei Einschr\u00e4nkungen kennen. Er meldet <strong>nur den ersten Fund<\/strong>: Bei drei Problemen in einem Ereignis kommt zun\u00e4chst eine Meldung zur\u00fcck. Die n\u00e4chste erscheint erst, wenn der erste Fehler behoben ist. Au\u00dferdem pr\u00fcft er weder <code>measurement_id<\/code> noch <code>api_secret<\/code>. Eine Anfrage mit erfundenen Zugangsdaten erh\u00e4lt deshalb dasselbe Ergebnis wie eine mit echten. Das ist dokumentiert und erlaubt die Nutzlastpr\u00fcfung, ohne ein echtes Geheimnis nach au\u00dfen zu senden.<\/p>\n<p>Ebenso geh\u00f6rt gekannt, was er gar nicht pr\u00fcft. Gegen ihn gemessen, mit gesetztem <code>ENFORCE_RECOMMENDATIONS<\/code>, ging all das kommentarlos durch: drei\u00dfig Ereignisse in einer Anfrage, ein leeres <code>events<\/code>-Array, eine Nutzlast ganz ohne <code>events<\/code>-Schl\u00fcssel, zwei Ereignisse mit demselben Namen, <code>screen_view<\/code> auf einem Web-Datenstrom und ein <code>purchase<\/code> ohne <code>value<\/code> und ohne <code>currency<\/code>. Ohne <code>validation_behavior<\/code> \u2014 also so, wie der Betrieb denselben Text behandelt \u2014 kam auch ein Parameterwert von 120 Zeichen sauber zur\u00fcck.<\/p>\n<h2>Was das Protokoll jetzt ist<\/h2>\n<p>Google hat das Measurement Protocol im Juni 2026 in einen abgeschlossenen Zustand versetzt: keine Abk\u00fcndigung, keine neuen Funktionen. Die Dokumentation empfiehlt f\u00fcr neue Server-zu-Server-Anbindungen jetzt die Data Manager API, mit OAuth statt eines API-Geheimnisses, mehreren Zielen je Anfrage und verschl\u00fcsselten Kennungen.<\/p>\n<p>F\u00fcr eine bestehende Anbindung ist das kein Notfall. Das Measurement Protocol l\u00e4uft weiter, seine Grenzen gelten weiter, und sein Endpunkt antwortet weiter auf alles mit 204 \u2014 was die Pr\u00fcfung vor dem Senden zu derselben Aufgabe macht, die sie immer war.<\/p>\n<div class=\"lw-faq\">\n<h2>Fragen und Antworten<\/h2>\n<h3>Wie l\u00e4sst sich im Betrieb erkennen, ob Measurement-Protocol-Ereignisse wirklich ankommen?<\/h3>\n<p>Nicht am Antwortcode, der ist fast immer 204. Tragf\u00e4hig ist eine Kombination aus Pr\u00fcfung vor dem Senden und Abgleich danach:<\/p>\n<ol>\n<li>Jede neue oder ge\u00e4nderte Nutzlast geht zuerst an <code>\/debug\/mp\/collect<\/code>. Weil der Pr\u00fcfserver nur den ersten Fund meldet, ist der Durchlauf so lange zu wiederholen, bis keine Meldung mehr kommt.<\/li>\n<li>Was der Pr\u00fcfserver nicht pr\u00fcft, pr\u00fcft der eigene Code: h\u00f6chstens 25 Ereignisse je Anfrage, ein nicht leeres events-Array, empfohlene Ereignisnamen wie purchase in Kleinschreibung, keine reinen App-Ereignisse auf einem Web-Datenstrom, value und currency bei einem purchase.<\/li>\n<li>Der Absender protokolliert, was er gesendet hat, etwa je Tag die Zahl der purchase-Ereignisse und ihre transaction_id. Liegt der Bericht einige Stunden sp\u00e4ter vor, zeigt der Vergleich, ob Ereignisse fehlen.<\/li>\n<\/ol>\n<p>Nur der dritte Schritt findet auch Verluste im laufenden Betrieb, etwa nach einem ausgetauschten API-Geheimnis oder bei einem Zeitstempel in der falschen Einheit.<\/p>\n<h3>Was passiert, wenn das API-Geheimnis in der GA4-Verwaltung gel\u00f6scht oder ersetzt wird?<\/h3>\n<p>Beim Senden nichts Sichtbares: Der Endpunkt antwortete in der Messung selbst auf eine Anfrage ganz ohne Zugangsdaten mit 204, und der Pr\u00fcfserver kontrolliert measurement_id und api_secret nicht. Ein Absender mit einem veralteten Geheimnis verliert seine Ereignisse also unbemerkt. Beim Austausch sind deshalb erst alle Absender umzustellen, bevor das alte Geheimnis gel\u00f6scht wird.<\/p>\n<h3>Wie passen serverseitige Ereignisse zur Einwilligung, die im Browser \u00fcber den Consent Mode erfasst wird?<\/h3>\n<p>Nur \u00fcber den eigenen Code. Das consent-Objekt des Measurement Protocol kennt allein ad_user_data und ad_personalization; einen Schl\u00fcssel f\u00fcr analytics_storage gibt es nicht, und ihn trotzdem zu senden macht die Nutzlast unlesbar. Eine Ablehnung der Analyse l\u00e4sst sich dem Endpunkt \u00fcber das consent-Objekt also nicht mitteilen. Die Entscheidung, ob f\u00fcr diesen Client \u00fcberhaupt ein Ereignis gesendet wird, muss vorher im eigenen System fallen.<\/p>\n<p>Hinzu kommt die Kennung. Ist analytics_storage abgelehnt, setzt das Google-Tag im Browser kein _ga-Cookie, und ein Server, der die client_id daraus liest, findet keine. Eine auf dem Server erfundene Ersatzkennung w\u00e4re genau der teure Fehler: ein neuer Nutzer mit einer Sitzung aus einem einzigen Ereignis.<\/p>\n<h3>Landet ein Zeitstempel in Millisekunden im Jahr 1970 oder gar nicht in den Berichten?<\/h3>\n<p>Gar nicht, weil er das Fenster von 72 Stunden verfehlt. F\u00fcr den Zeitpunkt aus der Beispielnutzlast liefert <code>Date.now()<\/code> den Wert 1.788.000.000.000. Als Mikrosekunden gelesen, sind das 1.788.000 Sekunden, rund 20,7 Tage nach dem Beginn der Unix-Zeit, also der 21. Januar 1970. Ein Wert in Sekunden landet knapp eine halbe Stunde nach Mitternacht am 1. Januar 1970. Beides ist \u00e4lter als 72 Stunden und wird verworfen, w\u00e4hrend der Produktivendpunkt weiter mit 204 antwortet.<\/p>\n<\/div>\n<div class=\"lw-quellen\">\n<h2>Quellen<\/h2>\n<ul>\n<li><a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/protocol\/ga4\" target=\"_blank\" rel=\"noopener noreferrer\">GA4 Measurement Protocol<\/a><\/li>\n<li><a href=\"https:\/\/support.google.com\/analytics\/answer\/9267744\" target=\"_blank\" rel=\"noopener noreferrer\">GA4 collection and configuration limits<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/ga4\" target=\"_blank\" rel=\"noopener noreferrer\">Google Analytics 4 developer guide<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Neun Anfragen, sieben davon absichtlich kaputt, gingen an den produktiven Measurement-Protocol-Endpunkt. Acht kamen in rund 100 Millisekunden als 204 No Content zurueck &#8211; darunter die, die gar kein JSON war, und die ohne jede Zugangsdaten. Hier steht der vollstaendige Aufbau einer Nutzlast: jedes erlaubte Feld, jede dokumentierte Grenze und die Stelle, an der zwei dieser Grenzen nicht zusammengehen.<\/p>\n","protected":false},"author":1,"featured_media":19745,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[92088,92091,92148],"class_list":["post-17207","post","type-post","status-publish","format-standard","hentry","category-digital-analytics-de","tag-data-quality-de","tag-google-analytics-4-de","tag-server-side-gtm-de"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet | Lukas Wojcik<\/title>\n<meta name=\"description\" content=\"Jedes Feld und jede Grenze einer GA4-Measurement-Protocol-Nutzlast, gemessen: was der Endpunkt stillschweigend annimmt, wo 25 Ereignisse und 200 Items aneinandergeraten und was der Pruefserver nicht prueft.\" \/>\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\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Jedes Feld und jede Grenze einer GA4-Measurement-Protocol-Nutzlast, gemessen: was der Endpunkt stillschweigend annimmt, wo 25 Ereignisse und 200 Items aneinandergeraten und was der Pruefserver nicht prueft.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-10T10:30:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png\" \/>\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\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet\",\"datePublished\":\"2026-10-10T10:30:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/\"},\"wordCount\":2211,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png\",\"keywords\":[\"Data Quality\",\"Google Analytics 4\",\"Server-Side GTM\"],\"articleSection\":[\"Digital Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/\",\"name\":\"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png\",\"datePublished\":\"2026-10-10T10:30:00+00:00\",\"description\":\"Jedes Feld und jede Grenze einer GA4-Measurement-Protocol-Nutzlast, gemessen: was der Endpunkt stillschweigend annimmt, wo 25 Ereignisse und 200 Items aneinandergeraten und was der Pruefserver nicht prueft.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png\",\"width\":1200,\"height\":630,\"caption\":\"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/digital-analytics-de\\\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet\"}]},{\"@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-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet | Lukas Wojcik","description":"Jedes Feld und jede Grenze einer GA4-Measurement-Protocol-Nutzlast, gemessen: was der Endpunkt stillschweigend annimmt, wo 25 Ereignisse und 200 Items aneinandergeraten und was der Pruefserver nicht prueft.","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\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/","og_locale":"en_US","og_type":"article","og_title":"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet | Lukas Wojcik","og_description":"Jedes Feld und jede Grenze einer GA4-Measurement-Protocol-Nutzlast, gemessen: was der Endpunkt stillschweigend annimmt, wo 25 Ereignisse und 200 Items aneinandergeraten und was der Pruefserver nicht prueft.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-10-10T10:30:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet","datePublished":"2026-10-10T10:30:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/"},"wordCount":2211,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png","keywords":["Data Quality","Google Analytics 4","Server-Side GTM"],"articleSection":["Digital Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/","url":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/","name":"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png","datePublished":"2026-10-10T10:30:00+00:00","description":"Jedes Feld und jede Grenze einer GA4-Measurement-Protocol-Nutzlast, gemessen: was der Endpunkt stillschweigend annimmt, wo 25 Ereignisse und 200 Items aneinandergeraten und was der Pruefserver nicht prueft.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-17207-ga4-measurement-protocol-nutzlasten--dn.png","width":1200,"height":630,"caption":"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/digital-analytics-de\/ga4-measurement-protocol-nutzlasten-jedes-feld-jede-grenze-und-warum\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"GA4-Measurement-Protocol-Nutzlasten: Jedes Feld, jede Grenze und warum der Endpunkt auf kaputtes JSON mit 204 antwortet"}]},{"@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\/posts\/17207","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"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=17207"}],"version-history":[{"count":3,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/17207\/revisions"}],"predecessor-version":[{"id":21800,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/17207\/revisions\/21800"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/19745"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=17207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=17207"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=17207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}