Workflow

GSC + GA4 + SERP Weekly Report via MCP

Weekly SEO report combining GSC impressions, GA4 traffic, and live SERP data. Correlate ranking changes with business impact.

Overview

This workflow generates a weekly SEO report that combines Google Search Console impressions and clicks, GA4 organic traffic and conversions, and live SERP data from Scavio. The combined view reveals correlations between ranking changes and business metrics that are invisible when data lives in separate dashboards.

Trigger

Cron schedule (every Monday at 8:00 AM UTC)

Schedule

Runs every Monday at 8:00 AM UTC

Workflow Steps

1

Pull GSC data for the past week

Query Google Search Console API for impressions, clicks, CTR, and average position per keyword.

2

Pull GA4 organic traffic data

Query GA4 Reporting API for organic sessions, bounce rate, and conversions per landing page.

3

Fetch current SERP positions

Call Scavio for each tracked keyword to get the current position, SERP features, and AI Overview status.

4

Join data on keyword and URL

Combine GSC, GA4, and SERP data into a unified row per keyword showing the full picture from ranking to conversion.

5

Generate report with alerts

Flag keywords where drops in position correlate with drops in clicks and sessions. Output as JSON for dashboard or email.

Python Implementation

Python
import requests
import json
from pathlib import Path
from datetime import datetime

API_KEY = "your_scavio_api_key"
DOMAIN = "yourdomain.com"

def get_serp_data(keyword: str) -> dict:
    res = requests.post(
        "https://api.scavio.dev/api/v1/search",
        headers={"x-api-key": API_KEY},
        json={"platform": "google", "query": keyword, "num": 20, "ai_overview": True},
        timeout=15,
    )
    res.raise_for_status()
    data = res.json()
    position = None
    for item in data.get("organic", []):
        if DOMAIN in item.get("link", ""):
            position = item.get("position")
            break
    return {
        "serp_position": position,
        "has_ai_overview": bool(data.get("ai_overview")),
        "has_featured_snippet": bool(data.get("featured_snippet")),
        "organic_count": len(data.get("organic", [])),
    }

def generate_weekly_report(keywords: list[str], gsc_data: dict, ga4_data: dict) -> dict:
    rows = []
    for kw in keywords:
        serp = get_serp_data(kw)
        gsc = gsc_data.get(kw, {})
        ga4 = ga4_data.get(kw, {})
        row = {
            "keyword": kw,
            "serp_position": serp["serp_position"],
            "has_ai_overview": serp["has_ai_overview"],
            "gsc_impressions": gsc.get("impressions", 0),
            "gsc_clicks": gsc.get("clicks", 0),
            "gsc_ctr": gsc.get("ctr", 0),
            "ga4_sessions": ga4.get("sessions", 0),
            "ga4_conversions": ga4.get("conversions", 0),
        }
        # Alert: position dropped AND traffic dropped
        row["alert"] = (
            serp["serp_position"] is not None
            and serp["serp_position"] > 10
            and gsc.get("clicks", 0) < gsc.get("prev_clicks", gsc.get("clicks", 0)) * 0.8
        )
        rows.append(row)

    alerts = [r for r in rows if r["alert"]]
    date = datetime.utcnow().strftime("%Y-%m-%d")
    return {"date": date, "keywords": len(rows), "alerts": len(alerts), "rows": rows}

# GSC and GA4 data would come from their respective APIs
gsc = {"best search API": {"impressions": 2400, "clicks": 180, "ctr": 0.075, "prev_clicks": 200}}
ga4 = {"best search API": {"sessions": 170, "conversions": 12}}
report = generate_weekly_report(["best search API"], gsc, ga4)
print(f"Weekly report: {report['keywords']} keywords, {report['alerts']} alerts")
for row in report["rows"]:
    status = "ALERT" if row["alert"] else "OK"
    print(f"  [{status}] {row['keyword']}: #{row['serp_position']} | {row['gsc_clicks']} clicks | {row['ga4_sessions']} sessions")

JavaScript Implementation

JavaScript
const API_KEY = "your_scavio_api_key";
const DOMAIN = "yourdomain.com";

async function getSerpData(keyword) {
  const res = await fetch("https://api.scavio.dev/api/v1/search", {
    method: "POST",
    headers: { "x-api-key": API_KEY, "content-type": "application/json" },
    body: JSON.stringify({ platform: "google", query: keyword, num: 20, ai_overview: true }),
  });
  if (!res.ok) throw new Error(`scavio ${res.status}`);
  const data = await res.json();
  let position = null;
  for (const item of data.organic ?? []) {
    if (item.link?.includes(DOMAIN)) { position = item.position; break; }
  }
  return { serpPosition: position, hasAiOverview: !!data.ai_overview };
}

async function weeklyReport(keywords, gscData, ga4Data) {
  const rows = [];
  for (const kw of keywords) {
    const serp = await getSerpData(kw);
    const gsc = gscData[kw] ?? {};
    const ga4 = ga4Data[kw] ?? {};
    rows.push({ keyword: kw, serpPosition: serp.serpPosition, hasAiOverview: serp.hasAiOverview, gscClicks: gsc.clicks ?? 0, ga4Sessions: ga4.sessions ?? 0, alert: serp.serpPosition > 10 });
  }
  console.log(`Report: ${rows.length} keywords, ${rows.filter((r) => r.alert).length} alerts`);
  for (const r of rows) console.log(`  [${r.alert ? "ALERT" : "OK"}] ${r.keyword}: #${r.serpPosition}`);
}

await weeklyReport(["best search API"], { "best search API": { clicks: 180 } }, { "best search API": { sessions: 170 } });

Platforms Used

Google

Web search with knowledge graph, PAA, and AI overviews

Frequently Asked Questions

This workflow generates a weekly SEO report that combines Google Search Console impressions and clicks, GA4 organic traffic and conversions, and live SERP data from Scavio. The combined view reveals correlations between ranking changes and business metrics that are invisible when data lives in separate dashboards.

This workflow uses a cron schedule (every monday at 8:00 am utc). Runs every Monday at 8:00 AM UTC.

This workflow uses the following Scavio platforms: google. Each platform is called via the same unified API endpoint.

Yes. Scavio's free tier includes 250 credits per month with no credit card required. That is enough to test and validate this workflow before scaling it.

GSC + GA4 + SERP Weekly Report via MCP

Weekly SEO report combining GSC impressions, GA4 traffic, and live SERP data. Correlate ranking changes with business impact.