Overview
Google AI Overviews now answer over 30% of informational queries directly in the SERP. This workflow checks your target keywords daily, extracts which domains are cited in the AI Overview panel, and alerts you when a competitor gains a citation you do not have. It replaces manual spot-checking with automated, daily coverage of hundreds of keywords at $0.005 each.
Trigger
Cron schedule (daily at 7 AM UTC)
Schedule
Daily at 7 AM UTC
Workflow Steps
Load keyword watchlist
Read target keywords and your domain from a config file or database. Include competitor domains to track.
Query AI Overviews
For each keyword, call the Scavio API with ai_overview enabled. Extract the AI Overview text and cited source URLs.
Parse citations
Extract all cited domains from AI Overview sources. Flag whether your domain or any competitor domain is cited.
Compare against previous day
Load yesterday's citation data from storage. Identify new competitor citations and lost own citations.
Generate alert
Format changes into a summary: keywords where competitors gained citations, keywords where you lost citations.
Send notification and update storage
Push the alert to Slack or email. Save today's citation data as the new baseline.
Python Implementation
import requests, os, json
from datetime import date
from pathlib import Path
H = {"x-api-key": os.environ["SCAVIO_API_KEY"]}
MY_DOMAIN = "yourdomain.com"
COMPETITORS = ["competitor1.com", "competitor2.com"]
KEYWORDS = ["best search api 2026", "serp api for agents", "web search tool for llm"]
def check_citations(keywords):
results = []
for kw in keywords:
r = requests.post("https://api.scavio.dev/api/v1/search", headers=H,
json={"platform": "google", "query": kw, "ai_overview": True}, timeout=10).json()
aio = r.get("ai_overview")
cited = []
if aio:
cited = [s.get("link", "") for s in aio.get("sources", [])]
results.append({
"keyword": kw, "date": str(date.today()),
"has_aio": bool(aio),
"my_cited": any(MY_DOMAIN in u for u in cited),
"competitor_cited": [c for c in COMPETITORS if any(c in u for u in cited)],
"all_cited": cited
})
return results
today = check_citations(KEYWORDS)
baseline_path = Path("aio_baseline.json")
if baseline_path.exists():
yesterday = json.loads(baseline_path.read_text())
for t in today:
prev = next((y for y in yesterday if y["keyword"] == t["keyword"]), None)
if prev and not prev.get("competitor_cited") and t["competitor_cited"]:
print(f"ALERT: {t['keyword']} - new competitor citation: {t['competitor_cited']}")
baseline_path.write_text(json.dumps(today, indent=2))
print(json.dumps(today, indent=2))JavaScript Implementation
const H = {"x-api-key": process.env.SCAVIO_API_KEY, "Content-Type": "application/json"};
const MY_DOMAIN = "yourdomain.com";
const COMPETITORS = ["competitor1.com", "competitor2.com"];
async function checkCitations(keywords) {
const results = [];
for (const kw of keywords) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query: kw, ai_overview: true})
}).then(r => r.json());
const aio = r.ai_overview;
const cited = aio ? (aio.sources || []).map(s => s.link || "") : [];
results.push({
keyword: kw, date: new Date().toISOString().slice(0, 10),
hasAio: !!aio,
myCited: cited.some(u => u.includes(MY_DOMAIN)),
competitorCited: COMPETITORS.filter(c => cited.some(u => u.includes(c))),
allCited: cited
});
}
return results;
}Platforms Used
Web search with knowledge graph, PAA, and AI overviews