AI Engine Optimization (AEO) is becoming essential for brands that want to appear in LLM-generated answers. The most measurable AEO metric in 2026 is Google AI Overview citation tracking: monitoring whether your pages appear as cited sources in Google's AI-generated summaries. This tutorial builds an automated tracker that queries your target keywords daily, parses AI Overview citations, and reports your citation share over time.
Prerequisites
- Python 3.8+ installed
- requests library installed
- A Scavio API key from scavio.dev
- A list of target keywords relevant to your business
Walkthrough
Step 1: Define your keyword list and domain
List the keywords you want to monitor and the domain you are tracking citations for.
import os
API_KEY = os.environ['SCAVIO_API_KEY']
MY_DOMAIN = 'yourdomain.com'
KEYWORDS = [
'best project management tool 2026',
'crm for small business',
'invoice software comparison',
'task management app reviews',
]Step 2: Query the Google endpoint for each keyword
Call Scavio's Google search endpoint and parse the AI Overview section from each response.
import requests
def check_ai_overview(keyword: str) -> dict:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY},
json={'platform': 'google', 'query': keyword}, timeout=10)
data = resp.json()
ai_overview = data.get('ai_overview', {})
sources = ai_overview.get('sources', [])
cited = any(MY_DOMAIN in s.get('link', '') for s in sources)
return {
'keyword': keyword,
'has_ai_overview': bool(ai_overview),
'total_sources': len(sources),
'cited': cited,
'source_domains': [s.get('link', '').split('/')[2] for s in sources if '/' in s.get('link', '')]
}Step 3: Run across all keywords and calculate citation share
Process the full keyword list and compute what percentage of AI Overviews cite your domain.
def run_aeo_report(keywords: list) -> dict:
results = [check_ai_overview(kw) for kw in keywords]
with_overview = [r for r in results if r['has_ai_overview']]
cited_count = sum(1 for r in with_overview if r['cited'])
return {
'total_keywords': len(keywords),
'with_ai_overview': len(with_overview),
'cited': cited_count,
'citation_share': round(cited_count / max(len(with_overview), 1) * 100, 1),
'details': results
}
report = run_aeo_report(KEYWORDS)
print(f'Citation share: {report["citation_share"]}% ({report["cited"]}/{report["with_ai_overview"]} AI Overviews)')Step 4: Save daily reports for trending
Store each daily report as a JSON file so you can track citation share changes over time.
import json, datetime
def save_daily_report(report: dict):
date = datetime.date.today().isoformat()
filename = f'aeo_report_{date}.json'
with open(filename, 'w') as f:
json.dump({'date': date, **report}, f, indent=2)
print(f'Saved to {filename}')
save_daily_report(report)Python Example
import requests, os, json
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}
DOMAIN = 'yourdomain.com'
def check_citations(keywords):
results = []
for kw in keywords:
data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'platform': 'google', 'query': kw}, timeout=10).json()
sources = data.get('ai_overview', {}).get('sources', [])
results.append({'keyword': kw, 'cited': any(DOMAIN in s.get('link', '') for s in sources)})
cited = sum(r['cited'] for r in results)
print(f'{cited}/{len(results)} keywords cite {DOMAIN}')
return resultsJavaScript Example
async function checkCitations(keywords, domain) {
const results = [];
for (const kw of keywords) {
const data = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST', headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
body: JSON.stringify({platform: 'google', query: kw})
}).then(r => r.json());
const sources = data.ai_overview?.sources || [];
results.push({keyword: kw, cited: sources.some(s => s.link?.includes(domain))});
}
return results;
}Expected Output
A daily AEO citation report showing citation share percentage, which keywords have AI Overviews, and whether your domain appears as a cited source.