Tutorial: GA4 Analytics Advisor per API abfragen und die Antwort mit runReport prüfen

Inhalt
Ein hilfreicher Analyseassistent braucht überprüfbare Antworten. Dieses Tutorial fragt Analytics Advisor nach Sitzungen je Kanal, ergänzt einen Vergleichszeitraum und kontrolliert die Zahlen durch eine ausdrücklich definierte Data-API-Abfrage. Das Ergebnis ist eine kleine Untersuchung mit gespeicherten Eingaben und Ausgaben statt einer ungeprüft übernommenen Erklärung.
Dokumentation geprüft: 25. September 2026. Der Chat-Endpunkt gehört zur frühen Vorschau v1alpha. Verfügbarkeit und Zugriff müssen für die vorgesehene Property geprüft werden. Am 27. September 2026 wurden die drei dokumentierten API-Abfragen über die Kommandozeile gegen eine autorisierte GA4-Property ausgeführt. Die strukturierte Tabelle für den 1.–7. September stimmte in allen vier Kanalgruppen-Zeilen exakt mit runReport überein; Property-Werte werden hier nicht wiedergegeben. [1]
1. Eine begrenzte Berichtsfrage festlegen
Das Beispiel vergleicht den 1.–7. September 2026 mit dem 25.–31. August 2026. Beide Zeiträume umfassen sieben Tage mit gleicher Wochentagsverteilung. Die Kennzahl heißt sessions, die Gruppierung sessionDefaultChannelGroup. Diese Bezeichnungen stammen aus dem API-Schema. [4] Feste Datumsangaben vermeiden die wechselnde Bedeutung von „letzte Woche“.
Ein Kanal ist eine Zuordnungsgruppe, keine Person und kein Kampagnenbudget. Die erste Frage verlangt bewusst eine Anzahl statt einer Ursache. Ein niedrigerer Wert kann eine Untersuchung begründen, beweist aber noch nicht, welche Marketingmaßnahme ihn verursacht hat.
2. Zugriff einrichten und die erste Antwort speichern
Das Beispiel läuft in Bash mit installiertem gcloud, curl und jq. Im Cloud-Projekt muss die Analytics Data API aktiviert sein. Das angemeldete Konto benötigt Zugriff auf die Property und die Berechtigung zur Nutzung des Kontingentprojekts. Cloud-Projektkennung und numerische Analytics-Property-ID sind unterschiedliche Kennungen.
Chat benötigt analytics.chatbot.read, die spätere Berichtsprüfung analytics.readonly. Das Beispiel fordert beide an. Zugangsdaten verbleiben im lokalen gcloud-Anmeldeverfahren und gehören weder in Artikelcode noch in öffentliche Webseiten. [1][3]
Aktuelle Cloud-CLI-Versionen können diese Analytics-Berechtigungen für den eingebauten OAuth-Client blockieren. Im vorgesehenen Cloud-Projekt ist daher ein OAuth-Client vom Typ Desktop-App anzulegen, als JSON herunterzuladen und über --client-id-file anzugeben. Google dokumentiert diesen Parameter für Berechtigungen außerhalb des standardmäßigen Cloud-Umfangs. [6]
# Bash; gcloud, curl and jq required
set -euo pipefail
export PROJECT_ID='REPLACE_WITH_CLOUD_PROJECT'
export PROPERTY_ID='REPLACE_WITH_NUMERIC_PROPERTY_ID'
export OAUTH_CLIENT_FILE='REPLACE_WITH_DOWNLOADED_DESKTOP_CLIENT_JSON'
gcloud auth application-default login --client-id-file="$OAUTH_CLIENT_FILE" --scopes="https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/analytics.chatbot.read,https://www.googleapis.com/auth/analytics.readonly"
gcloud auth application-default set-quota-project "$PROJECT_ID"
cat > question.json <<'JSON'
{
"userQuery": "For 2026-09-01 through 2026-09-07, report sessions by sessionDefaultChannelGroup. Use these exact dates and API field names. State any limitation and do not infer causes.",
"returnPropertyQuota": true
}
JSON
curl --fail-with-body --silent --show-error \
"https://analyticsdata.googleapis.com/v1alpha/properties/${PROPERTY_ID}:chat" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-H "Content-Type: application/json" \
--data-binary @question.json -o answer.json
jq '{sessionId, blocks, propertyQuota}' answer.json
Eine erfolgreiche Antwort kann Text- und Tabellenblöcke enthalten. Die vollständige Speicherung erhält deren Zusammenhang. Eine fehlende Tabelle ist keine Tabelle voller Nullwerte. Währungszeichen, Prozentzeichen und formatierte Zellen sollten nicht stillschweigend in bloße Zahlen umgewandelt werden. Antwortstruktur und Sitzungsfelder sind separat dokumentiert. [2]
3. In der zurückgegebenen Sitzung nachfragen
Der nächste Befehl liest die zurückgegebene Sitzungskennung; fehlt sie, stoppt das Skript. Danach folgt die Frage zum früheren Zeitraum. Für weitere Schritte liefert jeweils die jüngste Antwort die nächste Sitzungskennung. Verschiedene Properties, Kunden und Berechtigungskontexte benötigen getrennte Sitzungsspeicher.
SESSION_ID=$(jq -er '.sessionId | strings | select(length > 0)' answer.json)
jq -n --arg sid "$SESSION_ID" '{
sessionId: $sid,
userQuery: "Compare those sessions by sessionDefaultChannelGroup with 2026-08-25 through 2026-08-31. Show both totals and absolute differences. Separate observations from hypotheses.",
returnPropertyQuota: true
}' > followup.json
curl --fail-with-body --silent --show-error \
"https://analyticsdata.googleapis.com/v1alpha/properties/${PROPERTY_ID}:chat" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-H "Content-Type: application/json" \
--data-binary @followup.json -o followup-answer.json
jq '{sessionId, blocks, propertyQuota}' followup-answer.json
Der Sitzungskontext verbindet Fragen, ersetzt aber keine eindeutigen Zeiträume und Definitionen. „Organic Search ist zurückgegangen“ beschreibt ein Ergebnis. „Die neue Landingpage hat den Rückgang verursacht“ braucht zusätzliche Belege. Die gespeicherten Fragen machen diesen Unterschied nachvollziehbar.
4. Die Anzahl mit runReport reproduzieren
Die zweite API-Abfrage fordert beide Zeiträume, dieselbe Dimension und dieselbe Kennzahl direkt an. Sie erzeugt einen eigenständigen Bericht. Der Assistent bestätigt damit nicht nur seine eigene Antwort. Die Berichts-API dokumentiert Zeiträume, Spaltenköpfe, Zeilenzahlen und Metadaten. [3]
cat > report-request.json <<'JSON'
{
"dateRanges": [
{"startDate":"2026-09-01","endDate":"2026-09-07","name":"current"},
{"startDate":"2026-08-25","endDate":"2026-08-31","name":"previous"}
],
"dimensions": [{"name":"sessionDefaultChannelGroup"}],
"metrics": [{"name":"sessions"}],
"limit": "1000",
"returnPropertyQuota": true
}
JSON
curl --fail-with-body --silent --show-error \
"https://analyticsdata.googleapis.com/v1beta/properties/${PROPERTY_ID}:runReport" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: ${PROJECT_ID}" \
-H "Content-Type: application/json" \
--data-binary @report-request.json -o report-response.json
jq '{dimensionHeaders,metricHeaders,rows,rowCount,metadata,propertyQuota}' report-response.json
Die Reihenfolge der Spaltenköpfe bestimmt die Interpretation der Zeilenwerte. Bei mehreren Zeiträumen unterscheidet die zusätzliche Zeitraumdimension die Perioden. Ein Vergleich allein nach Zeilenposition ist ungeeignet: Kanäle können anders sortiert sein oder fehlen. Je Kanal lautet die Rechnung aktuell minus vorher. Eine prozentuale Änderung benötigt einen vorherigen Wert ungleich null; eine fehlende Zeile ist etwas anderes als eine gemessene Null.
5. Einschränkungen vor der Auswertung prüfen
Der GA4-API-Antwortprüfer verarbeitet die gespeicherte report-response.json für die Prüfung von Metadaten und Kontingenten. Chat-Antworten unterstützt er nicht. Die Assistentenausgabe wird separat mit dem Bericht verglichen. Hinweise auf Schwellen, Stichproben oder unvollständige Seitennavigation müssen in der Untersuchung sichtbar bleiben.
returnPropertyQuota fordert den Chat-Kontingentstand an und reserviert keine Kapazität. Fehlt das Kontingentobjekt, ist der Stand unbekannt und nicht unbegrenzt. Anmelde-, Berechtigungs- und Kontingentfehler gehören vor erneuten Versuchen ins Protokoll. Automatische Wiederholungen können zusätzliche Kontingente verbrauchen und andere Antworten liefern. [1]
6. Ein prüfbares Ergebnis festhalten
Die Arbeitsunterlagen bestehen aus zwei Fragen, zwei Chat-Antworten, Berichtsanfrage und Berichtsantwort sowie dem Abrufzeitpunkt. Der Zugriff richtet sich nach der Vertraulichkeit der Property-Daten. Googles Datenschutzhinweis nennt die mögliche Bearbeitung von Gesprächen durch menschliche Prüfer zur Produktverbesserung. Kundennamen und vertrauliche Kampagnenpläne gehören deshalb nicht in eine ansonsten rein zahlenbezogene Frage. [5]
Am Ende steht eine dokumentierte Zahl mit einer Erklärung möglicher Abweichungen. Das Ergebnis kann auch „nicht reproduzierbar“ lauten. Beides ist hilfreicher als eine unbelegte Empfehlung zur Änderung des Werbebudgets.