Google Search Console Date Picker Fehler: Daten per API abrufen

Google Search Console Date Picker Fehler: Daten per API abrufen

Zuletzt überprüft: 16. Oktober 2026
22 Min. Lesezeit
Leitfaden
Technisches SEO

#Warum zeigt der Date Picker der Google Search Console das Jahr 1969 an

Der Ausfall der Datumsauswahl im Leistungsbericht der Google Search Console zeigt, wie riskant die ausschließliche Abhängigkeit von einer Weboberfläche ist. Am 13. Oktober 2026 berichtete Barry Schwartz bei Search Engine Roundtable, dass der Bericht bei einem benutzerdefinierten Zeitraum das Formular mit der Meldung Date can't be after 1969-12-31 ablehnt, also: Das Datum darf nicht nach dem 31. Dezember 1969 liegen. Die Auswahl wurde repariert, fiel am 14. Oktober erneut aus und funktionierte einige Stunden später wieder. Während des Ausfalls können Teams historische Daten im Browser nicht filtern.

Google hat keine Ursache genannt, aber das Datum selbst ist aufschlussreich. Nach POSIX zählt die Unix-Zeit die Sekunden seit Mitternacht des 1. Januar 1970 UTC. Erhält ein Datumsfeld in JavaScript einen Nullwert, einen leeren String oder ein noch nicht geladenes Objekt, landet es leicht beim Wert 0. In Zeitzonen mit negativem Versatz gegenüber UTC fällt dieser Nullpunkt auf den 31. Dezember 1969, in den US-Zeitzonen zwischen 16:00 und 19:00 Uhr. Die wahrscheinlichste Erklärung ist daher ein Zeitstempel mit dem Wert null, der als obere Grenze des Zeitraums im Validator ankam.

Unter dieser Annahme vergleicht der Validator das gewählte Datum mit einer Grenze im Jahr 1969. Jedes reale Datum liegt später, also wertet die Regel den Zeitraum als ungültig und blockiert das Diagramm.

Für große Portale, Onlineshops und Agenturen mit Dutzenden betreuten Websites bedeutet ein solcher Ausfall, dass die laufende Diagnose stillsteht. Die Arbeit eines SEO-Teams darf nicht von der Stabilität einer einzelnen Single-Page-Application (SPA) abhängen. Die Lösung für durchgehende Analysen ist eine direkte Anbindung an die offizielle Google Search Console API.

              Architektur fuer den Datenzugriff auf die Search Console
              
    [GSC Web-Oberflaeche]              [Search Analytics API v1]
              │                                    │
    Frontend-Fehler & Blockaden           Direkter REST-Endpunkt
    1.000 Zeilen Limit                    25.000 Zeilen pro Abfrage
    Unix-Epoch-Validierungsfehler         50.000 Zeilen pro Tag
              │                                    │
              ▼                                    ▼
       [Webbrowser]                      [Lokale DB / BigQuery]

#Welche Grenzen hat die Oberfläche der Google Search Console im Vergleich zur API

Die grafische Oberfläche der Google Search Console ist für einen schnellen Blick auf Basiskennzahlen gebaut, nicht für Data Engineering. Selbst wenn die Datumsauswahl fehlerfrei läuft, setzt das Webpanel Grenzen, die das Bild der Sichtbarkeit verzerren.

Die erste Grenze ist das feste Anzeigelimit. Die Tabelle in der Search Console zeigt höchstens 1.000 Zeilen. Bei Websites mit Hunderten Unterseiten und Zehntausenden Long-Tail-Suchanfragen sieht man nur einen Teil der Begriffe, die tatsächlich Traffic bringen.

Das zweite Problem ist die Aufbewahrung. Die Search Console löscht Daten, die älter als 16 Monate sind. Ohne automatisierte Archivierung ist ein mehrjähriger Vergleich (Year-over-Year) nicht möglich. Der dritte Faktor ist die Anonymisierung seltener Suchanfragen (anonymized queries): Google filtert sie aus Datenschutzgründen im Panel, in der API und im BigQuery-Export heraus. Die API kennt dafür das Tabellenlimit von 1.000 Zeilen nicht, und Abfragen, die für jeden Tag einzeln laufen, liefern bis zu 50.000 Zeilen pro Tag und Suchtyp (Google-Dokumentation).

KriteriumWeboberfläche der GSCSearch Analytics API
Zeilenlimit pro Anfrage1.000 Zeilen25.000 Zeilen
Maximale Zeilenzahl1.000 (feste Tabellengrenze)50.000 pro Tag und Suchtyp (Paginierung über startRow)
Aufbewahrung der Daten16 Monate16 Monate, länger nach Speicherung in eigener Datenbank
Anfälligkeit für Frontend-FehlerHoch (UI-Fehler, JavaScript-Blockaden)Keine UI-Schicht (JSON-Antwort eines REST-Endpunkts)
Automatisierung des ReportingsManuelles Klicken nötigVollständig automatisierbar (Cron, Worker, CI)
Mehrdimensionale AufschlüsselungEingeschränkte FilterkombinationenVolle Kombination: page + query + device + country

Die Nutzung der API macht das Reporting unabhängig von Frontend-Fehlern bei Google und gibt Entwicklern die Kontrolle über das Datenarchiv.

#Wie richtet man einen Service Account für die Google Search Console API ein

Um ohne wiederholtes Browser-Login per OAuth2 für Endnutzer auf die Search Analytics API zuzugreifen, richtet man in der Google Cloud Platform einen Service Account ein. Das Dienstkonto arbeitet als eigenständige technische Identität mit eigenem kryptografischem Schlüsselpaar.

Der erste Schritt ist ein Projekt in der Google Cloud Console (console.cloud.google.com). Danach öffnet man den Bereich APIs & Services, sucht die Google Search Console API und aktiviert sie.

Im zweiten Schritt legt man im Bereich IAM & Admin, Unterbereich Service Accounts, ein Dienstkonto mit einem eindeutigen Namen an, zum Beispiel gsc-analytics-exporter. Anschließend wechselt man zum Reiter Keys und erstellt über Add Key und Create new key einen neuen privaten Schlüssel im JSON-Format. Die Datei wird lokal heruntergeladen. Sie enthält die Schlüssel-ID, die E-Mail-Adresse des Dienstkontos und den privaten RSA-Schlüssel im PEM-Format.

{
  "type": "service_account",
  "project_id": "enterprise-seo-pipeline",
  "private_key_id": "7f8a9b1c2d3e4f5a",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9...\n-----END PRIVATE KEY-----\n",
  "client_email": "gsc-analytics-exporter@enterprise-seo-pipeline.iam.gserviceaccount.com",
  "client_id": "104958673829104958673",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token"
}

Im dritten Schritt autorisiert man das Dienstkonto in der Google Search Console. Man kopiert die Adresse aus client_email, öffnet die Search Console für die bestätigte Property, wählt Einstellungen (Settings) und dann Nutzer und Berechtigungen (Users and permissions) und fügt die E-Mail-Adresse mit der Rolle Eingeschränkt (Restricted) oder Vollständig (Full) hinzu. Ab diesem Moment darf das Dienstkonto die Endpunkte der Search Console für diese Property abfragen.

Die JSON-Datei mit dem privaten Schlüssel darf nie in einem öffentlichen Repository landen. Sie gehört in die .gitignore oder wird auf dem Produktionsserver als verschlüsselte Umgebungsvariable übergeben.

#Wie prüft man, auf welche Search Console Properties ein Service Account Zugriff hat

Der häufigste Grund für einen 403-Fehler nach der Einrichtung eines Dienstkontos ist eine Abweichung zwischen der Property-Adresse im Skript und der, die die Search Console kennt. Statt zu raten, lohnt sich eine Abfrage der API. Die Methode sites.list liefert die Liste der Properties, auf die das Konto Zugriff hat. Jeder Eintrag enthält zwei Felder: siteUrl in genau der Schreibweise, die die übrigen Methoden erwarten, und permissionLevel (Dokumentation der Ressource sites).

Das Feld permissionLevel nimmt einen von vier Werten an: siteOwner (Inhaber), siteFullUser (vollständige Berechtigung), siteRestrictedUser (eingeschränkte Berechtigung) und siteUnverifiedUser (Nutzer ohne bestätigte Property). Fehlt die Property in der Liste, wurde die E-Mail-Adresse des Dienstkontos in den Einstellungen der Search Console nicht hinzugefügt oder bei einer anderen Property eingetragen, zum Beispiel beim Präfix https://www. statt bei der Domain-Property.

const { data } = await searchconsole.sites.list();
for (const site of data.siteEntry || []) {
  console.log(site.siteUrl, site.permissionLevel);
}
// sc-domain:wppoland.com siteFullUser

Dieselbe Ressource hat die Methoden add, delete und get. Für den reinen Datenabruf reichen der Scope webmasters.readonly und ein list-Aufruf beim Start des Skripts: Weicht die zurückgegebene siteUrl von der konfigurierten ab, kann das Skript mit einer klaren Meldung abbrechen, bevor es Hunderte fehlerhafte Anfragen sendet.

#Wie ruft man Daten für sc-domain und URL-Präfixe in Node.js ab

Bei der Arbeit mit der Search Console API stoßen Entwickler oft auf einen 403- oder 404-Fehler, der auf ein falsches Format der Property-Kennung (siteUrl) zurückgeht. Google unterscheidet zwei Arten von Properties:

  1. Domain-Property: fasst alle Protokolle und Subdomains zusammen. In der API braucht ihre Kennung das Präfix sc-domain:, zum Beispiel sc-domain:wppoland.com.
  2. URL-Präfix-Property: bezieht sich auf ein bestimmtes Protokoll und einen Pfad. In der API ist ihre Kennung die vollständige URL mit abschließendem Schrägstrich, zum Beispiel https://wppoland.com/de/.

Bei mehrsprachigen Websites fragt man entweder die URL-Präfix-Properties der einzelnen Sprachversionen ab oder die Domain-Property und filtert die URL-Pfade anschließend im Code.

Das folgende Node.js-Skript zeigt eine vollständige Implementierung des Datenabrufs mit Paginierung und Speicherung in einer JSON-Datei. Es nutzt die offizielle Bibliothek googleapis.

import fs from "node:fs";
import path from "node:path";
import { google } from "googleapis";

async function exportSearchConsoleMetrics() {
  const credentialsPath = path.resolve("./scripts/gsc-service-account.json");
  const creds = JSON.parse(fs.readFileSync(credentialsPath, "utf8"));

  if (creds.private_key) {
    creds.private_key = creds.private_key.replace(/\\n/g, "\n");
  }

  const auth = new google.auth.GoogleAuth({
    credentials: creds,
    scopes: ["https://www.googleapis.com/auth/webmasters.readonly"],
  });

  const client = await auth.getClient();
  const searchconsole = google.searchconsole({ version: "v1", auth: client });

  const siteUrl = "sc-domain:wppoland.com";

  // Drei Tage Puffer einplanen, da Google-Performancedaten nachtraeglich konsolidiert werden
  const endDate = new Date(Date.now() - 3 * 864e5).toISOString().slice(0, 10);
  const startDate = new Date(Date.now() - 33 * 864e5).toISOString().slice(0, 10);

  console.log(`Starte Datenabruf fuer ${siteUrl} von ${startDate} bis ${endDate}`);

  const allRecords = [];
  let startRow = 0;
  const rowLimit = 25000;

  while (true) {
    const response = await searchconsole.searchanalytics.query({
      siteUrl,
      requestBody: {
        startDate,
        endDate,
        dimensions: ["page", "query", "device", "country"],
        rowLimit,
        startRow,
      },
    });

    const rows = response.data.rows || [];
    allRecords.push(...rows);
    console.log(`Stapel geladen: ${rows.length} Zeilen (Gesamt: ${allRecords.length})`);

    if (rows.length < rowLimit) {
      break;
    }

    startRow += rowLimit;
  }

  const targetFile = "./reports/gsc-performance-data.json";
  fs.mkdirSync(path.dirname(targetFile), { recursive: true });
  fs.writeFileSync(targetFile, JSON.stringify(allRecords, null, 2), "utf8");

  console.log(`Export abgeschlossen. ${allRecords.length} Datensaetze gespeichert in ${targetFile}`);
}

exportSearchConsoleMetrics().catch((err) => {
  console.error("Fehler beim Abruf der Search Console API:", err.message);
  process.exit(1);
});

Der Code durchläuft die Ergebnisseiten über den Parameter startRow. Enthält die Antwort weniger Zeilen als das Limit von 25.000, endet die Schleife. So lässt sich die Historie der Suchanfragen bis zum Tageslimit der API vollständig abrufen.

#Wie ruft man Daten aus der Google Search Console mit Python ab

Für Data Engineers und Teams, die mit Pandas und Jupyter arbeiten, ist ein Python-Skript das bequemste Werkzeug, um Daten aus der Search Console zu extrahieren und zu bereinigen. Das folgende Beispiel ruft Daten mit Aufschlüsselung nach Tagen ab und speichert sie im spaltenorientierten Format Parquet, das weniger Platz als CSV belegt und die Spaltentypen erhält.

Für das Skript werden die Bibliotheken google-api-python-client, google-auth sowie pandas und pyarrow benötigt:

pip install google-api-python-client google-auth pandas pyarrow

Implementierung des Skripts:

import datetime
import pandas as pd
from google.oauth2 import service_account
from googleapiclient.discovery import build

def fetch_search_console_dataframe(site_url: str, days: int = 30) -> pd.DataFrame:
    key_path = "scripts/gsc-service-account.json"
    credentials = service_account.Credentials.from_service_account_file(
        key_path,
        scopes=["https://www.googleapis.com/auth/webmasters.readonly"]
    )
    
    service = build("searchconsole", "v1", credentials=credentials)
    
    end_date = (datetime.date.today() - datetime.timedelta(days=3)).strftime("%Y-%m-%d")
    start_date = (datetime.date.today() - datetime.timedelta(days=days + 3)).strftime("%Y-%m-%d")
    
    collected_items = []
    start_row = 0
    row_limit = 25000
    
    while True:
        body = {
            "startDate": start_date,
            "endDate": end_date,
            "dimensions": ["date", "page", "query", "country", "device"],
            "rowLimit": row_limit,
            "startRow": start_row
        }
        
        response = service.searchanalytics().query(
            siteUrl=site_url,
            body=body
        ).execute()
        
        rows = response.get("rows", [])
        if not rows:
            break
            
        for item in rows:
            collected_items.append({
                "date": item["keys"][0],
                "page": item["keys"][1],
                "query": item["keys"][2],
                "country": item["keys"][3],
                "device": item["keys"][4],
                "clicks": item["clicks"],
                "impressions": item["impressions"],
                "ctr": item["ctr"],
                "position": round(item["position"], 2)
            })
            
        print(f"Stapel verarbeitet: {len(rows)} Zeilen (startRow={start_row})")
        if len(rows) < row_limit:
            break
            
        start_row += row_limit
        
    df = pd.DataFrame(collected_items)
    return df

if __name__ == "__main__":
    property_id = "sc-domain:wppoland.com"
    df_data = fetch_search_console_dataframe(property_id, days=60)
    
    if not df_data.empty:
        df_data["date"] = pd.to_datetime(df_data["date"])
        df_data.to_parquet("reports/gsc_performance.parquet", index=False)
        print(f"{len(df_data)} Datensaetze erfolgreich als Parquet gesichert.")
    else:
        print("Keine Daten empfangen.")

Das spaltenorientierte Parquet-Format erlaubt schnelle Aggregationen und Gruppierungen von Suchanfragen nach Produktkategorien oder WordPress-Templates, ohne den Arbeitsspeicher des Servers zu belasten.

#Wie ruft man aktuelle und stündliche Daten über die Search Console API ab

Die Skripte oben lassen die letzten drei Tage aus, weil Google angibt, dass Daten in der Regel nach 2 bis 3 Tagen verfügbar sind (Leitfaden zum Abruf aller Daten). Derselbe Leitfaden empfiehlt einen einfachen Test: Eine Abfrage mit der Dimension date über die letzten 10 Tage zeigt, welcher Tag der letzte verfügbare ist.

Ob die API vorläufige Daten liefert, steuert der Parameter dataState (Dokumentation der Methode query):

Wert von dataStateWas die API liefert
final (oder kein Parameter)Nur finalisierte Daten
allAuch frische Daten, die sich noch ändern können
hourly_allStündlich aufgeschlüsselte, unvollständige Daten, zu verwenden mit der Dimension hour

Bei dataState: "all" und Gruppierung nach Datum enthält die Antwort in den Metadaten das Feld first_incomplete_date. Alle Werte nach diesem Datum können sich noch deutlich ändern. Ein Archivierungsskript sollte sie daher getrennt speichern oder beim nächsten Lauf überschreiben. Zeitangaben in den Metadaten stehen in der Zeitzone America/Los_Angeles, was beim Zusammenführen mit Serverlogs in mitteleuropäischer Zeit wichtig ist.

Die Dimension hour hat Google am 9. April 2025 eingeführt. Das Panel zeigt Stundendaten nur für die letzten 24 Stunden, die API liefert sie für bis zu 10 Tage (Ankündigung im Google Search Central Blog). So lässt sich der letzte Tag mit demselben Wochentag der Vorwoche vergleichen, etwa nach der Veröffentlichung eines Beitrags oder nach dem Deployment eines neuen Themes.

{
  "startDate": "2026-10-15",
  "endDate": "2026-10-15",
  "dataState": "hourly_all",
  "dimensions": ["hour"]
}

Die Schlüssel in der Antwort haben die Form 2026-10-15T00:00:00-07:00, also die Stunde in der Zeitzone von Los Angeles mit Versatz. Vor dem Speichern in der Datenbank lohnt sich die Umrechnung in UTC.

#Wie filtert man Seiten und Suchanfragen in der Search Analytics API

Eine Abfrage ohne Filter liefert den gesamten Traffic der Property. Auf einer mehrsprachigen Website braucht man meist einen Ausschnitt, etwa nur Adressen unter /de/. Dafür gibt es das Array dimensionFilterGroups. Gefiltert werden kann nach den Dimensionen country, device, page, query und searchAppearance. Verfügbare Operatoren sind (Dokumentation der Methode query):

  • equals (Standard) und notEquals: exakte Übereinstimmung, bei page und query mit Unterscheidung von Groß- und Kleinschreibung,
  • contains und notContains: Teilübereinstimmung ohne Unterscheidung von Groß- und Kleinschreibung,
  • includingRegex und excludingRegex: regulärer Ausdruck in RE2-Syntax.
{
  "startDate": "2026-09-01",
  "endDate": "2026-09-30",
  "dimensions": ["page", "query"],
  "type": "web",
  "dimensionFilterGroups": [{
    "filters": [
      { "dimension": "page", "operator": "includingRegex", "expression": "^https://wppoland\\.com/de/" },
      { "dimension": "query", "operator": "notContains", "expression": "wppoland" }
    ]
  }],
  "rowLimit": 25000
}

Der zweite Filter schneidet Markensuchen ab, ein typischer Schritt vor der Long-Tail-Analyse. Der Parameter type ersetzt das veraltete searchType und nimmt die Werte web (Standard, der Tab Alle ohne Discover und Google News), image, video, news (Tab News), discover und googleNews an. Jeder Typ braucht eine eigene Abfrage.

Der Parameter aggregationType legt fest, ob Kennzahlen nach Property (byProperty) oder nach URL (byPage) berechnet werden; der Standardwert auto überlässt Google die Wahl. Der Wert byProperty funktioniert nicht für die Typen discover und googleNews.

#Warum stimmt die Summe aus der API nicht mit dem Diagramm in der Search Console überein

Nach dem ersten Export bemerkt fast jedes Team, dass die Summe der Klicks aus den Zeilen niedriger ist als die Zahl im Diagramm des Panels. Das ist kein Fehler im Skript. Google nennt drei Ursachen (Leitfaden zum Abruf aller Daten):

  1. Die API liefert höchstens 50.000 Zeilen pro Tag und Suchtyp, sortiert nach Klicks. Bei großen Websites fehlt der Long Tail unterhalb dieser Schwelle in der Antwort.
  2. Bei Gruppierung nach den Dimensionen page oder query kann das System einen Teil der Daten weglassen, damit die Berechnung machbar bleibt.
  3. Impressionen, Klicks, Position und CTR werden bei Aggregation nach Seite anders berechnet als bei Aggregation nach Property.

Dazu kommen anonymisierte Suchanfragen, die in keiner Quelle enthalten sind. Praktische Folge: Gesamtwerte des Traffics holt man aus einer Abfrage ohne die Dimensionen page und query (nur date), die Aufschlüsselung nach Suchbegriffen behandelt man als nach Klicks geordnete Stichprobe. Google empfiehlt außerdem, die Daten Tag für Tag abzurufen und in Schritten von 25.000 Zeilen zu paginieren, bis eine leere Seite zurückkommt, und zwar getrennt für jeden Suchtyp.

#Wie speichert man Daten aus der Google Search Console in Google BigQuery

Die ausfallsicherste Lösung für große Websites ist der automatische Export der Search-Console-Daten in das Data Warehouse Google BigQuery. Google hat den Bulk Data Export am 21. Februar 2023 eingeführt: Der Mechanismus überträgt täglich einen Abzug der Leistungsdaten in das angegebene BigQuery-Projekt (Ankündigung im Google Search Central Blog).

Vorteile dieses Ansatzes:

  1. Keine 16-Monats-Grenze: In BigQuery gespeicherte Daten bleiben so lange erhalten, wie man sie braucht.
  2. Der Export unterliegt nicht dem täglichen Zeilenlimit der API. Google filtert nur anonymisierte Suchanfragen aus Datenschutzgründen heraus.
  3. Die Daten aus der Search Console lassen sich mit Tabellen der WordPress-Datenbank verknüpfen (WooCommerce-Bestellungen, Warenkörbe, Conversions).

Der Export wird in zwei Schritten eingerichtet. In der Google Cloud Console aktiviert man die BigQuery API im Projekt und erteilt dem Dienstkonto der Search Console Berechtigungen. In den Einstellungen der Search Console gibt man die Projekt-ID und den Speicherort des Datasets an. Den Export kann nur der Inhaber der Property einrichten. Die Search Console simuliert zuerst einen Export; gelingt die Simulation, erhalten alle Inhaber eine E-Mail, und die regelmäßigen Exporte starten innerhalb von 48 Stunden. Bei einem Fehler erscheint sofort eine Warnung.

Der Export legt drei Tabellen an:

  • searchdata_site_impression: nach Property aggregierte Daten, mit Suchanfrage, Land, Suchtyp und Gerät.
  • searchdata_url_impression: nach URL aggregierte Daten, mit Details zu Suchanfragen und Rich Results.
  • ExportLog: Protokoll darüber, welche Daten an einem Tag gespeichert wurden. Fehlgeschlagene Exporte werden hier nicht erfasst.

Beispielabfrage in BigQuery, die Unterseiten mit vielen Impressionen und niedriger CTR findet (Kandidaten für die Optimierung von Title-Tags und Überschriften):

SELECT
  url,
  query,
  SUM(impressions) AS total_impressions,
  SUM(clicks) AS total_clicks,
  ROUND(SAFE_DIVIDE(SUM(clicks), SUM(impressions)) * 100, 2) AS calculated_ctr,
  ROUND(SUM(sum_position) / SUM(impressions) + 1, 1) AS avg_position
FROM
  `enterprise-project.searchconsole.searchdata_url_impression`
WHERE
  data_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
  AND country = 'deu'
GROUP BY
  url,
  query
HAVING
  total_impressions > 500
  AND calculated_ctr < 2.0
  AND avg_position BETWEEN 3.0 AND 10.0
ORDER BY
  total_impressions DESC
LIMIT 100;

Die Tabelle searchdata_url_impression enthält unter anderem die Spalten data_date, url, query, country, search_type, impressions, clicks und sum_position sowie Flags für Rich-Result-Typen (das Beispiel von Google filtert search_type = 'WEB'). Die Spalte sum_position zählt die Position ab null, deshalb berechnet man die durchschnittliche Position als SUM(sum_position) / SUM(impressions) + 1, wie im Beispiel von Google. Die Abfrage findet Suchbegriffe auf der ersten Ergebnisseite, die unter 2 Prozent Klicks bringen. Das sind Kandidaten für einen Test mit neuem Title, neuer H1 und neuer Beschreibung; die Wirkung der Änderung muss man in den folgenden Wochen messen, statt sie vorauszusetzen.

                  Search Console zu BigQuery Pipeline
                  
   [Google Search Console] ──(Bulk Export)──> [Google BigQuery]
                                                    │
                                                    ├──> [Looker Studio Dashboard]
                                                    ├──> [Ranking-Verlust-Monitoring]
                                                    └──> [WooCommerce-Umsatz-Korrektur]

#Wann wählt man die Search Analytics API und wann den Bulk Data Export

Beide Quellen liefern dieselben Kennzahlen, lösen aber unterschiedliche Probleme. Google schreibt in der Ankündigung des Exports, dass er besonders für große Websites mit Zehntausenden Seiten oder mit Traffic aus Zehntausenden Suchanfragen pro Tag nützlich ist, während kleine und mittlere Websites über die Oberfläche, den Looker-Studio-Connector oder die Search Analytics API Zugriff auf alle ihre Daten haben (Google Search Central Blog).

KriteriumSearch Analytics APIBulk Data Export
Zeilenlimit25.000 pro Anfrage, 50.000 pro Tag und SuchtypKein tägliches Zeilenlimit
Anonymisierte SuchanfragenAusgelassenAusgelassen
AktualitätVorläufige (all) und stündliche (hourly_all) DatenTäglicher Abzug
Wer kann es einrichtenJeder Nutzer mit Zugriff auf die PropertyNur der Inhaber der Property
Wohin die Daten gehenDorthin, wo Ihr Skript sie speichertIn Ihr BigQuery-Projekt

In der Praxis ergänzen sich beide Ansätze. Der Export nach BigQuery dient als Archiv und Quelle für Long-Tail-Analysen, ein schlankes API-Skript mit dataState: "hourly_all" überwacht die letzten Stunden nach einer Veröffentlichung oder einem Deployment. Für ein kleines WordPress-Blog reicht meist das Skript aus den vorherigen Abschnitten, einmal täglich per Cron ausgeführt.

#Wie verknüpft man Search Console Daten mit der WordPress-Datenbank

Rohdaten aus der Search Console gewinnen den größten geschäftlichen Wert, wenn man sie mit der internen Inhaltsstruktur des CMS verbindet. Ein klassischer Export aus der Search Console enthält nur vollständige URLs als Zeichenketten. Er sagt nichts über den Beitragstyp (Beitrag, WooCommerce-Produkt, Landingpage), das Datum der letzten Änderung im Gutenberg-Editor oder den Autor.

Die Integration besteht darin, den URL-Pfad in die Objekt-ID in WordPress (post_id) zu übersetzen. Dafür gibt es in WordPress die Funktion url_to_postid($url) oder den direkten Abgleich des Slugs in der Tabelle wp_posts.

Der folgende PHP-Code zeigt, wie man die per API importierten Suchdaten dem richtigen Produkt oder Beitrag in der Datenbank zuordnet:

<?php
/**
 * Verknuepfung von Search Console Performancedaten mit Beitraegen
 */
declare(strict_types=1);

namespace WPPoland\Analytics;

class SearchConsoleIngestor {
    
    public function syncUrlMetrics(string $url, int $clicks, int $impressions, float $position): void {
        $path = wp_parse_url($url, PHP_URL_PATH);
        if (!$path) {
            return;
        }

        $postId = url_to_postid($url);
        
        if ($postId === 0) {
            $postId = $this->resolveTaxonomyTerm($path);
        }

        if ($postId > 0) {
            update_post_meta($postId, '_gsc_clicks_30d', $clicks);
            update_post_meta($postId, '_gsc_impressions_30d', $impressions);
            update_post_meta($postId, '_gsc_position_avg', $position);
            update_post_meta($postId, '_gsc_last_synced', current_time('mysql', true));
        }
    }

    private function resolveTaxonomyTerm(string $path): int {
        global $wpdb;
        $slug = trim($path, '/');
        $parts = explode('/', $slug);
        $termSlug = end($parts);

        $termId = $wpdb->get_var($wpdb->prepare(
            "SELECT t.term_id FROM {$wpdb->terms} t 
             JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id 
             WHERE t.slug = %s LIMIT 1",
            $termSlug
        ));

        return $termId ? (int)$termId : 0;
    }
}

Mit dieser Verknüpfung sieht das Redaktionsteam im WordPress-Backend die genaue Zahl der Impressionen und die Position jeder Unterseite. Fällt die durchschnittliche Position eines Beitrags nach einem Theme-Update oder einem neuen Deployment von Platz 4 auf Platz 18, kann das System automatisch eine Benachrichtigung in Slack senden oder eine Audit-Aufgabe für den Entwickler anlegen.

Bei Architekturen mit Headless WordPress oder statischen Seitengeneratoren lassen sich die Daten aus der Search Console API zur Build-Zeit abrufen und für dynamische Bereiche mit beliebten Themen und verwandten Beiträgen nutzen.

#Wie prüft man den Indexierungsstatus exportierter URLs mit der URL Inspection API

Ein Klickrückgang eines Beitrags in den Search-Analytics-Daten sagt nicht, ob die Seite noch im Index ist. Die Antwort liefert die URL Inspection API, die dasselbe Dienstkonto und dieselben Scopes (webmasters oder webmasters.readonly) nutzt. Die Anfrage lautet POST https://searchconsole.googleapis.com/v1/urlInspection/index:inspect mit den Feldern inspectionUrl (vollständige Adresse, die zur Property gehören muss), siteUrl (im selben Format wie zuvor: sc-domain: oder Präfix mit Schrägstrich) und dem optionalen languageCode (Dokumentation der Methode inspect).

Das Ergebnis indexStatusResult enthält unter anderem (Beschreibung von UrlInspectionResult):

FeldBedeutung
verdictGesamtergebnis: ob die Adresse indexiert ist
coverageStateOb Google die Seite gefunden und indexiert hat
indexingStateOb eine noindex-Regel die Indexierung blockiert
robotsTxtStateOb robots.txt das Crawling blockiert
lastCrawlTimeWann der Haupt-Crawler die Adresse zuletzt abgerufen hat
googleCanonical und userCanonicalVon Google gewählte und auf der Seite deklarierte kanonische URL

In WordPress lässt sich das gut mit der Klasse SearchConsoleIngestor aus dem vorherigen Abschnitt verbinden: Fällt die Position eines Beitrags, prüft das Skript seine Adresse und speichert coverageState und googleCanonical in den Post-Meta. Eine Abweichung zwischen der kanonischen URL von Google und der des SEO-Plugins erklärt einen Rückgang oft schneller als eine Analyse der Suchbegriffe. Das Limit ist allerdings niedrig: 2.000 Anfragen pro Tag und 600 pro Minute pro Website (Limits der Search Console API). Prüfen Sie daher nur Adressen mit einem Rückgangssignal, nicht die ganze Sitemap. Die Methode zeigt die Version aus dem Google-Index und testet die Adresse nicht live. Den Unterschied zwischen diesem Werkzeug und der Indexing API beschreibt unser Leitfaden zu GSC und Indexing API.

#Wie geht man mit Abfragelimits und Fehlern der API um

Die Search Analytics API hat Limits, die in der Google-Dokumentation beschrieben sind. Eine Überschreitung endet mit einem Kontingentfehler, und das Skript muss warten:

GeltungsbereichWert
Pro Website (Abfragen derselben Property)1.200 Abfragen pro Minute
Pro Nutzer (Abfragen desselben Kontos)1.200 Abfragen pro Minute
Pro Google-Cloud-Projekt40.000 Abfragen pro Minute und 30.000.000 pro Tag

Zusätzlich gilt ein Lastkontingent (load quota), gemessen in 10-Minuten- und Tagesfenstern. Laut Google sind Abfragen teuer, wenn man nach Seite oder Suchanfrage gruppiert oder filtert, und die Last steigt mit der Länge des Zeitraums. Google rät ausdrücklich davon ab, dieselben Daten wiederholt abzurufen, etwa bei jedem Lauf den gesamten Vormonat. Ein Archivierungsskript sollte daher nur fehlende Tage nachladen.

Damit Skripte, die Millionen Datensätze für große Onlineshops abrufen, zuverlässig laufen, braucht es drei Schutzmechanismen:

  1. Exponentielles Backoff (Exponential Backoff): Bei einem Fehlercode 429 oder 503 bricht das Skript nicht ab, sondern wartet vor dem nächsten Versuch eine wachsende Zahl von Sekunden (2 hoch n plus zufälliger Jitter).
  2. Aufteilung nach einzelnen Tagen (Daily Date Chunking): Statt die Daten eines ganzen Jahres in einem Aufruf mit riesiger Paginierung abzurufen, teilt man die Aufgabe in Tagesschleifen. Scheitert eine Abfrage an einem kurzen Netzwerkfehler, wiederholt man nur den fehlenden Tag.
  3. Zwischenspeichern der Zugriffstoken: Die Google-Clientbibliotheken erneuern das OAuth2-Token anhand des Dienstkonto-Schlüssels automatisch, in Serverless-Umgebungen (AWS Lambda, Cloudflare Workers) sollte man aber sicherstellen, dass das Token nicht für jede einzelne HTTP-Anfrage neu erzeugt wird.

Der folgende Code zeigt eine Abfrage, die fehlgeschlagene Anfragen automatisch wiederholt:

async function executeResilientQuery(queryAction, maxRetries = 5) {
  let attempt = 0;
  while (attempt < maxRetries) {
    try {
      return await queryAction();
    } catch (err) {
      attempt++;
      const isRateLimited = err.code === 429 || err.status === 429;
      const isServerIssue = err.code >= 500 && err.code < 600;

      if ((isRateLimited || isServerIssue) && attempt < maxRetries) {
        const delayMs = Math.pow(2, attempt) * 1000 + Math.random() * 500;
        console.warn(`Fehler ${err.code}. Neuer Versuch in ${Math.round(delayMs)} ms (Versuch ${attempt}/${maxRetries})...`);
        await new Promise((resolve) => setTimeout(resolve, delayMs));
      } else {
        throw err;
      }
    }
  }
}

Diese drei Mechanismen sorgen dafür, dass die Archivierung der SEO-Daten unabhängig von Fehlern im Browser-Panel der Google Search Console läuft.

#Wie verwaltet man SEO-Daten aus der Search Console API

Fehler der grafischen Oberfläche, wie der Ausfall der Datumsauswahl und der Sprung des Kalenders ins Jahr 1969, erinnern daran, dass die Analysedaten einer Website im System des Betreibers liegen sollten und nicht nur in einem externen Panel.

Eine eigene Pipeline auf Basis der Search Console API bringt messbare Vorteile:

  • Bis zu 50.000 Zeilen pro Tag und Suchtyp statt 1.000 Tabellenzeilen im Panel, mit dem Bulk Data Export der vollständige Datensatz ohne anonymisierte Suchanfragen.
  • Reporting unabhängig von Frontend-Fehlern bei Google.
  • Schutz vor dem Verlust historischer Daten nach 16 Monaten durch Archivierung in BigQuery oder einer relationalen Datenbank.
  • Direkte Korrelation des Traffics mit den Umsätzen eines WooCommerce-Shops und mit Änderungen im Code des WordPress-Themes.

Für fortgeschrittene Analysen, automatisiertes Reporting oder ein technisches Audit lohnt sich ein Gespräch mit einem WordPress-Entwickler, der die Datenpipeline mit der Architektur Ihres Shops verbindet und gegen Ausfälle absichert. Für technische Beratung können Sie unser Team kontaktieren.

Nächster Schritt

Machen Sie aus dem Artikel eine echte Umsetzung

Dieser Block stärkt die interne Verlinkung und führt Nutzer gezielt zum nächsten sinnvollen Schritt im Service- und Content-System.

Soll das Thema auf Ihrer Website umgesetzt werden?

Wenn Sichtbarkeit in Google und KI-Systemen wichtig ist, baue ich die passende Content-Architektur, FAQ, Schema-Daten und interne Verlinkung auf.

Relevanter Cluster

Weitere WordPress-Dienste und Wissensbasis entdecken

Stärken Sie Ihr Unternehmen mit professionellem technischen Support in den Kernbereichen des WordPress-Ökosystems.

Warum bleibt die Datumsauswahl in der Google Search Console bei 1969-12-31 hängen#
Google hat keine Ursache veröffentlicht. Das Datum deutet auf einen Zeitstempel mit dem Wert null hin, also Mitternacht am 1. Januar 1970 UTC (Unix-Epoche), der in Zeitzonen westlich von Greenwich als 31. Dezember 1969 angezeigt wird. Search Engine Roundtable beschrieb den Fehler am 13. Oktober 2026; die Auswahl wurde repariert, fiel am 14. Oktober erneut aus und funktionierte am selben Tag wieder.
Wie viele Zeilen können über die Google Search Console API exportiert werden#
Ein einzelner Aufruf von searchanalytics.query liefert bis zu 25 000 Zeilen (Standard 1000). Mit dem Parameter startRow lassen sich die Ergebnisse paginieren, aber Google stellt über die API höchstens 50 000 Zeilen pro Tag und Suchtyp bereit, sortiert nach Klicks. Einen vollständigeren Datensatz ohne anonymisierte Suchanfragen liefert der Bulk Data Export nach BigQuery.
Was ist der Unterschied zwischen sc-domain und einem URL-Präfix in der API#
Die Syntax sc-domain fasst den gesamten Traffic über alle Subdomains und Protokolle zusammen. Eine URL-Präfix-Property bezieht sich auf eine exakte Verzeichnisstruktur und erfordert einen abschließenden Schrägstrich im Parameter siteUrl.
Wie lange speichert Google die Leistungsdaten in der Search Console#
Google behält Leistungsdaten 16 Monate. Ältere Daten werden unwiderruflich gelöscht. Ein Export in BigQuery oder eine relationale Datenbank ermöglicht mehrjährige Jahresvergleiche (YoY).
Wie verknüpft man Search Console API-Daten mit WordPress#
Das Skript verknüpft die Seiten-URL aus der API-Antwort über die Funktion url_to_postid mit der Tabelle wp_posts. So lassen sich Klicks und Positionsveränderungen direkt im WordPress-Backend einzelnen Beiträgen zuordnen.

Sie brauchen ein FAQ für Branche und Zielmarkt? Wir erstellen eine Version passend zu Ihren Business-Zielen.

Kontakt aufnehmen

Ähnliche Artikel