AI Overview visibility is becoming a critical SEO metric as Google surfaces AI-generated answers for more queries. A weekly report that tracks which of your target keywords trigger AI Overviews, whether your domain gets cited, and how citations change over time gives you actionable intelligence for AEO strategy. This tutorial shows how to build an automated weekly AEO report using the Scavio API. You will monitor a keyword list, track citation counts, and generate a formatted report showing week-over-week changes.
Prerequisites
- Python 3.8+ installed
- requests library installed
- A Scavio API key from scavio.dev
- A list of target keywords to monitor
Walkthrough
Step 1: Define the keyword list
Set up the keywords you want to monitor for AI Overview visibility.
import os, requests, json
from datetime import date, timedelta
API_KEY = os.environ["SCAVIO_API_KEY"]
KEYWORDS = [
"best crm for startups",
"how to build a landing page",
"project management tools comparison",
"what is product-led growth",
"saas pricing strategies",
]Step 2: Check AI Overview for each keyword
Query each keyword and extract AI Overview presence and citation data.
def check_aeo(keyword):
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": keyword})
data = resp.json()
aio = data.get("ai_overview", {})
sources = aio.get("sources", []) if aio else []
return {
"keyword": keyword,
"has_aio": bool(aio),
"source_count": len(sources),
"domains": [s.get("link","").split("/")[2] for s in sources if s.get("link")],
}Step 3: Build the weekly snapshot
Run checks across all keywords and save the snapshot for comparison.
def weekly_snapshot():
snapshot = {"date": date.today().isoformat(), "keywords": []}
for kw in KEYWORDS:
result = check_aeo(kw)
snapshot["keywords"].append(result)
filename = f"aeo_snapshot_{date.today().isoformat()}.json"
with open(filename, "w") as f:
json.dump(snapshot, f, indent=2)
return snapshotStep 4: Compare with previous week
Load the previous snapshot and calculate week-over-week changes.
def compare_weeks(current, previous_file):
try:
with open(previous_file) as f:
previous = json.load(f)
except FileNotFoundError:
return current
prev_map = {k["keyword"]: k for k in previous.get("keywords", [])}
for kw in current["keywords"]:
prev = prev_map.get(kw["keyword"], {})
kw["aio_change"] = "new" if kw["has_aio"] and not prev.get("has_aio") else \
"lost" if not kw["has_aio"] and prev.get("has_aio") else "stable"
kw["source_delta"] = kw["source_count"] - prev.get("source_count", 0)
return current
snap = weekly_snapshot()
prev_date = (date.today() - timedelta(days=7)).isoformat()
report = compare_weeks(snap, f"aeo_snapshot_{prev_date}.json")
for kw in report["keywords"]:
print(f"{kw['keyword']}: AIO={'yes' if kw['has_aio'] else 'no'} sources={kw['source_count']}")Python Example
import os, requests
API_KEY = os.environ["SCAVIO_API_KEY"]
def aeo_check(kw):
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": kw})
aio = resp.json().get("ai_overview", {})
sources = aio.get("sources", []) if aio else []
return {"keyword": kw, "aio": bool(aio), "sources": len(sources)}
for kw in ["best crm", "what is plg"]:
print(aeo_check(kw))JavaScript Example
const H = {"x-api-key": process.env.SCAVIO_API_KEY, "Content-Type": "application/json"};
async function aeoCheck(kw) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query: kw})
});
const aio = (await r.json()).ai_overview || {};
return {keyword: kw, aio: !!Object.keys(aio).length,
sources: (aio.sources||[]).length};
}
aeoCheck("best crm").then(console.log);Expected Output
A weekly AEO report showing which keywords trigger AI Overviews, domain citation counts, and week-over-week changes in AI Overview visibility.