Overview
This workflow monitors SERP changes following Google I/O 2026 announcements: AI Mode expansion to 1B+ users, Gemini 3.5 Flash deployment, Information Agents, and search box redesign. It tracks both organic ranking shifts and AI Overview content changes daily, alerting on significant movements. Critical for SEO teams responding to the largest Google search update of 2026.
Trigger
Cron schedule (daily at 7 AM UTC)
Schedule
Runs daily at 7:00 AM UTC
Workflow Steps
Load tracked keywords
Read keywords being monitored for post-I/O SERP changes.
Query with AI Overview extraction
Search each keyword via Scavio with ai_overview enabled for both organic and AI data.
Compare against pre-I/O baseline
Check organic position changes and AI Overview content differences vs the pre-I/O baseline.
Calculate change severity
Score each keyword's change magnitude: position shifts, new/lost AI citations, AI Overview content changes.
Alert on significant changes
Send alerts for keywords with position changes > 3 or AI citation status changes.
Python Implementation
import requests
import json
from datetime import datetime
from pathlib import Path
API_KEY = "your_scavio_api_key"
DOMAIN = "yourdomain.com"
def monitor_serp_changes(keywords: list[str]) -> dict:
baseline_path = Path("serp_baseline.json")
baseline = json.loads(baseline_path.read_text()) if baseline_path.exists() else {}
current = {}
alerts = []
for kw in keywords:
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": kw, "ai_overview": True},
timeout=15,
)
if not res.ok:
continue
data = res.json()
organic_pos = None
for r in data.get("organic", []):
if DOMAIN in r.get("link", ""):
organic_pos = r.get("position")
break
ai_text = data.get("ai_overview", {}).get("text", "")
ai_cited = DOMAIN in ai_text.lower()
current[kw] = {"position": organic_pos, "ai_cited": ai_cited}
prev = baseline.get(kw, {})
if prev.get("position") and organic_pos:
pos_change = organic_pos - prev["position"]
if abs(pos_change) >= 3:
alerts.append({"keyword": kw, "type": "position", "prev": prev["position"], "current": organic_pos, "change": pos_change})
if prev.get("ai_cited") != ai_cited:
alerts.append({"keyword": kw, "type": "ai_citation", "prev": prev.get("ai_cited", False), "current": ai_cited})
baseline_path.write_text(json.dumps(current, indent=2))
date = datetime.utcnow().strftime("%Y-%m-%d")
print(f"SERP Monitor {date}: {len(keywords)} keywords, {len(alerts)} alerts")
for a in alerts:
print(f" [{a['type']}] {a['keyword']}: {a.get('prev')} -> {a.get('current')}")
return {"date": date, "alerts": alerts}
monitor_serp_changes(["best search api", "serp api pricing", "ai overview tracking"])JavaScript Implementation
const API_KEY = "your_scavio_api_key";
const DOMAIN = "yourdomain.com";
async function monitorChanges(keywords) {
const results = [];
for (const kw of keywords) {
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: kw, ai_overview: true }),
});
const data = await res.json();
const match = (data.organic ?? []).find((r) => (r.link ?? "").includes(DOMAIN));
const aiText = data.ai_overview?.text ?? "";
results.push({ keyword: kw, position: match?.position ?? null, aiCited: aiText.toLowerCase().includes(DOMAIN) });
}
console.log(`Monitored ${results.length} keywords`);
return results;
}
await monitorChanges(["best search api", "serp api pricing"]);Platforms Used
Web search with knowledge graph, PAA, and AI overviews