Tutorial

How to Monitor Brand Mentions in AI Overviews

Track daily whether your brand appears in Google AI Overview snippets. Alert on new citations or drops. Python pipeline at $0.005/keyword.

Appearing in a Google AI Overview drives clicks even from position 8 or lower in organic results. Disappearing from an AI Overview can cut traffic overnight with no warning in Search Console. This monitor checks your target keywords daily for AI Overview presence and brand citations, alerting on gains and losses so you can react before traffic drops compound.

Prerequisites

  • Python 3.8+
  • requests library
  • A Scavio API key from scavio.dev
  • Target keywords and brand terms to monitor

Walkthrough

Step 1: Configure the AI Overview monitor

Set up keywords and brand terms to track in AI Overviews.

Python
import os, requests, json, sqlite3
from datetime import datetime

API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}

CONFIG = {
    'brand_terms': ['scavio', 'scavio.dev'],
    'keywords': ['best search api for developers', 'serp api comparison 2026',
                 'google search api python', 'web scraping api alternative',
                 'ai agent search tool', 'mcp search server',
                 'reddit api for agents', 'tiktok data api']
}

db = sqlite3.connect('ao_monitor.db')
db.execute('''CREATE TABLE IF NOT EXISTS ao_checks (
    keyword TEXT, checked_at TEXT, has_ao INTEGER,
    brand_cited INTEGER, ao_snippet TEXT
)''')
db.commit()
print(f'Monitoring {len(CONFIG["keywords"])} keywords for AI Overview brand citations')

Step 2: Check each keyword for AI Overview and brand citations

Query with include_ai_overview and parse the response for brand mentions.

Python
def check_ao(keyword, brand_terms):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us',
                          'include_ai_overview': True}).json()
    ao = data.get('ai_overview', {})
    ao_text = json.dumps(ao).lower() if ao else ''
    cited = any(b.lower() in ao_text for b in brand_terms)
    snippet = ao_text[:300] if ao else ''
    now = datetime.now().isoformat()
    db.execute('INSERT INTO ao_checks VALUES (?,?,?,?,?)',
        (keyword, now, 1 if ao else 0, 1 if cited else 0, snippet))
    db.commit()
    return {'keyword': keyword, 'has_ao': bool(ao), 'cited': cited}

results = []
for kw in CONFIG['keywords']:
    r = check_ao(kw, CONFIG['brand_terms'])
    results.append(r)
    icon = 'CITED' if r['cited'] else 'AO' if r['has_ao'] else '---'
    print(f'  [{icon:6}] {kw}')
print(f'\nCost: ${len(CONFIG["keywords"]) * 0.005:.3f}')

Step 3: Detect changes from previous check

Compare today versus yesterday to find new citations and drops.

Python
def detect_ao_changes(keyword):
    rows = db.execute(
        'SELECT has_ao, brand_cited, checked_at FROM ao_checks WHERE keyword=? ORDER BY checked_at DESC LIMIT 2',
        (keyword,)).fetchall()
    if len(rows) < 2:
        return None
    curr_ao, curr_cited = rows[0][0], rows[0][1]
    prev_ao, prev_cited = rows[1][0], rows[1][1]
    changes = []
    if curr_ao and not prev_ao: changes.append('AO_APPEARED')
    if not curr_ao and prev_ao: changes.append('AO_DISAPPEARED')
    if curr_cited and not prev_cited: changes.append('BRAND_GAINED')
    if not curr_cited and prev_cited: changes.append('BRAND_LOST')
    return changes if changes else None

print('\nChanges detected:')
alerts = []
for kw in CONFIG['keywords']:
    changes = detect_ao_changes(kw)
    if changes:
        alerts.append({'keyword': kw, 'changes': changes})
        for c in changes:
            priority = 'HIGH' if 'LOST' in c or 'DISAPPEARED' in c else 'INFO'
            print(f'  [{priority}] {kw}: {c}')
if not alerts:
    print('  No changes from previous check.')

Step 4: Generate daily summary report

Aggregate results into a dashboard-ready daily summary.

Python
def daily_summary():
    today = datetime.now().strftime('%Y-%m-%d')
    rows = db.execute(
        'SELECT keyword, has_ao, brand_cited FROM ao_checks WHERE checked_at LIKE ?',
        (f'{today}%',)).fetchall()
    total = len(rows)
    ao_count = sum(1 for r in rows if r[1])
    cited_count = sum(1 for r in rows if r[2])
    print(f'\n=== AI Overview Monitor - {today} ===')
    print(f'  Keywords checked: {total}')
    print(f'  AI Overview present: {ao_count}/{total} ({ao_count/total*100:.0f}%)')
    print(f'  Brand cited: {cited_count}/{total} ({cited_count/total*100:.0f}%)')
    print(f'  Citation rate: {cited_count/ao_count*100:.0f}% of AOs' if ao_count else '  No AOs found')
    print(f'  Daily cost: ${total * 0.005:.3f}')
    print(f'  Monthly estimate: ${total * 0.005 * 30:.2f}')
    # Keywords where brand is cited
    cited_kws = [r[0] for r in rows if r[2]]
    if cited_kws:
        print(f'\n  Brand cited in AO for:')
        for kw in cited_kws:
            print(f'    - {kw}')

daily_summary()

Python Example

Python
import os, requests, json
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}

def check_ao(keyword, brand):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us', 'include_ai_overview': True}).json()
    ao = data.get('ai_overview', {})
    cited = brand.lower() in json.dumps(ao).lower() if ao else False
    print(f'{keyword}: AO={bool(ao)}, cited={cited}. Cost: $0.005')

check_ao('best serp api 2026', 'scavio')

JavaScript Example

JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function checkAO(keyword, brand) {
  const data = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: SH,
    body: JSON.stringify({ query: keyword, country_code: 'us', include_ai_overview: true })
  }).then(r => r.json());
  const ao = data.ai_overview || {};
  const cited = JSON.stringify(ao).toLowerCase().includes(brand.toLowerCase());
  console.log(`${keyword}: AO=${!!data.ai_overview}, cited=${cited}`);
}
checkAO('best serp api 2026', 'scavio').catch(console.error);

Expected Output

JSON
Monitoring 8 keywords for AI Overview brand citations
  [CITED ] best search api for developers
  [AO    ] serp api comparison 2026
  [---   ] google search api python
  [AO    ] web scraping api alternative
  [CITED ] ai agent search tool
  [AO    ] mcp search server
  [---   ] reddit api for agents
  [AO    ] tiktok data api

Cost: $0.040

=== AI Overview Monitor - 2026-05-19 ===
  Keywords checked: 8
  AI Overview present: 6/8 (75%)
  Brand cited: 2/8 (25%)
  Citation rate: 33% of AOs
  Daily cost: $0.040
  Monthly estimate: $1.20

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.8+. requests library. A Scavio API key from scavio.dev. Target keywords and brand terms to monitor. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Track daily whether your brand appears in Google AI Overview snippets. Alert on new citations or drops. Python pipeline at $0.005/keyword.