Tutorial

How to Track AI Overview Citations for Your Brand

Monitor when Google AI Overviews cite your brand. Daily tracking pipeline shows citation rate, position, and competitor comparison.

Google AI Overviews now appear on 40%+ of informational queries and cite specific brands. If competitors get cited and you do not, you lose traffic you cannot see in traditional SEO tools. This tracker checks your target keywords daily, logs citation status, and alerts when competitors gain or lose citations.

Prerequisites

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

Walkthrough

Step 1: Scan keywords for AI Overview citations

Check each keyword for AI Overview presence and brand citation status.

Python
import os, requests, json
from datetime import datetime

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

DOMAIN = 'yourbrand.com'
COMPETITORS = ['competitor1.com', 'competitor2.com']
KEYWORDS = [
    'best project management tool',
    'project management software comparison',
    'agile vs waterfall tools',
    'remote team project management',
    'project management for startups',
]

def scan_citations(keyword):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
    aio = data.get('ai_overview', data.get('answer_box', {}))
    aio_text = json.dumps(aio).lower() if aio else ''
    result = {
        'keyword': keyword,
        'has_aio': bool(aio),
        'brand_cited': DOMAIN.lower() in aio_text,
        'competitors_cited': {c: c.lower() in aio_text for c in COMPETITORS}
    }
    return result

results = []
for kw in KEYWORDS:
    r = scan_citations(kw)
    results.append(r)
    brand = 'CITED' if r['brand_cited'] else 'absent'
    comps = sum(1 for v in r['competitors_cited'].values() if v)
    print(f'  [{brand:6}] {kw:45} | competitors: {comps}/{len(COMPETITORS)}')
print(f'\nCost: ${len(KEYWORDS) * 0.005:.3f}')

Step 2: Calculate citation metrics and gaps

Compute your citation share vs competitors and identify gaps.

Python
def citation_report(results):
    total = len(results)
    with_aio = sum(1 for r in results if r['has_aio'])
    brand_cited = sum(1 for r in results if r['brand_cited'])
    print(f'\n=== AI Citation Report - {DOMAIN} ===')
    print(f'  Keywords: {total}')
    print(f'  AI Overviews present: {with_aio} ({with_aio/total*100:.0f}%)')
    print(f'  Your brand cited: {brand_cited} ({brand_cited/with_aio*100:.0f}% of AIO)' if with_aio else '  No AI Overviews found')
    # Competitor comparison
    print(f'\n  Citation Share:')
    comp_counts = {c: sum(1 for r in results if r['competitors_cited'].get(c)) for c in COMPETITORS}
    all_brands = {DOMAIN: brand_cited, **comp_counts}
    for brand, count in sorted(all_brands.items(), key=lambda x: x[1], reverse=True):
        bar = '#' * count
        print(f'    {brand:25} | {count:2} citations | {bar}')
    # Gaps: keywords where competitors are cited but you are not
    gaps = [r for r in results if r['has_aio'] and not r['brand_cited'] and any(r['competitors_cited'].values())]
    if gaps:
        print(f'\n  Citation Gaps ({len(gaps)} keywords where competitors beat you):')
        for g in gaps:
            cited_comps = [c for c, v in g['competitors_cited'].items() if v]
            print(f'    "{g["keyword"]}" -> cited: {", ".join(cited_comps)}')

citation_report(results)

Step 3: Store history and detect changes

Log daily results and alert when citation status changes.

Python
def track_changes(results, history_file='citation_history.json'):
    try:
        with open(history_file) as f:
            history = json.load(f)
    except FileNotFoundError:
        history = []
    today = {
        'date': datetime.now().strftime('%Y-%m-%d'),
        'total': len(results),
        'aio_count': sum(1 for r in results if r['has_aio']),
        'cited': sum(1 for r in results if r['brand_cited']),
        'keywords': {r['keyword']: r['brand_cited'] for r in results}
    }
    changes = []
    if history:
        prev = history[-1]
        prev_kws = prev.get('keywords', {})
        for kw, cited in today['keywords'].items():
            if kw in prev_kws and prev_kws[kw] != cited:
                change = 'GAINED' if cited else 'LOST'
                changes.append(f'{change}: "{kw}"')
    history.append(today)
    with open(history_file, 'w') as f:
        json.dump(history, f, indent=2)
    print(f'\n=== Citation Changes ===')
    if changes:
        for c in changes:
            print(f'  {c}')
    else:
        print(f'  No changes since last scan.')
    print(f'  History: {len(history)} scans saved')

track_changes(results)

Python Example

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

def check_cited(keyword, domain):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
    aio = data.get('ai_overview', {})
    cited = domain.lower() in json.dumps(aio).lower() if aio else False
    print(f'{"CITED" if cited else "absent":6} | {keyword}')

for kw in ['best search api', 'serp api comparison']:
    check_cited(kw, 'scavio.dev')
print('Cost: $0.010')

JavaScript Example

JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function checkCited(keyword, domain) {
  const data = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: SH,
    body: JSON.stringify({ query: keyword, country_code: 'us' })
  }).then(r => r.json());
  const aio = data.ai_overview || {};
  const cited = JSON.stringify(aio).toLowerCase().includes(domain);
  console.log(`${cited ? 'CITED' : 'absent'} | ${keyword}`);
}
await checkCited('best search api', 'scavio.dev');

Expected Output

JSON
  [CITED ] best project management tool                    | competitors: 1/2
  [absent] project management software comparison           | competitors: 2/2
  [CITED ] agile vs waterfall tools                         | competitors: 0/2
  [absent] remote team project management                   | competitors: 1/2
  [absent] project management for startups                  | competitors: 0/2

Cost: $0.025

=== AI Citation Report - yourbrand.com ===
  Keywords: 5
  AI Overviews present: 4 (80%)
  Your brand cited: 2 (50% of AIO)

  Citation Gaps (1 keywords where competitors beat you):
    "project management software comparison" -> cited: competitor1.com, competitor2.com

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 domain 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

Monitor when Google AI Overviews cite your brand. Daily tracking pipeline shows citation rate, position, and competitor comparison.