ScavioScavio
ProductPricingDocs
Sign InGet Started
  1. Home
  2. Tutorials
  3. How to Track AI Overview Citations on a Budget
Tutorial

How to Track AI Overview Citations on a Budget

Monitor which sites get cited in Google AI Overviews without expensive rank tracking tools. Python script using search API at $0.005/query.

Get Free API KeyAPI Docs

Google AI Overviews now appear for a large share of informational queries, and getting cited in them drives significant traffic. Traditional rank trackers charge hundreds of dollars to monitor AI Overview citations. You can build your own tracker with a search API that returns AI Overview data in its SERP response. This tutorial builds a citation monitoring pipeline that checks your target keywords, records which domains get cited, and tracks your citation share over time. Each check costs $0.005 via the Scavio API.

Prerequisites

  • Python 3.9+ installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • A list of keywords where you expect AI Overviews

Walkthrough

Step 1: Check if a query triggers an AI Overview

Search for a keyword and check whether the SERP response includes an AI Overview section. Not all queries trigger one, so this step filters your keyword list.

Python
import requests, os

API_KEY = os.environ['SCAVIO_API_KEY']

def check_ai_overview(query: str) -> dict:
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
        json={'query': query, 'country_code': 'us'})
    data = resp.json()
    ai_overview = data.get('ai_overview', {})
    has_overview = bool(ai_overview and ai_overview.get('text'))
    citations = ai_overview.get('citations', []) if has_overview else []
    return {
        'query': query,
        'has_ai_overview': has_overview,
        'citation_count': len(citations),
        'cited_domains': [c.get('domain', '') for c in citations]
    }

result = check_ai_overview('what is the best crm for startups')
print(f'AI Overview: {result["has_ai_overview"]}, Citations: {result["citation_count"]}')

Step 2: Batch check keywords and find citation patterns

Run through your keyword list and collect citation data. Identify which domains get cited most frequently across your target keywords.

Python
import time
from collections import Counter

def batch_citation_check(keywords: list) -> dict:
    results = []
    domain_counts = Counter()
    for kw in keywords:
        data = check_ai_overview(kw)
        results.append(data)
        for domain in data['cited_domains']:
            domain_counts[domain] += 1
        time.sleep(0.3)
    return {
        'total_keywords': len(keywords),
        'with_ai_overview': sum(1 for r in results if r['has_ai_overview']),
        'top_cited_domains': domain_counts.most_common(10),
        'details': results
    }

keywords = [
    'what is the best crm for startups',
    'how to choose a crm 2026',
    'crm software comparison',
    'best free crm tools'
]
report = batch_citation_check(keywords)
print(f'{report["with_ai_overview"]}/{report["total_keywords"]} keywords have AI Overviews')

Step 3: Track your domain citation share

Calculate how often your domain appears in AI Overview citations compared to competitors. This is your AI Overview share of voice.

Python
def citation_share(report: dict, your_domain: str) -> dict:
    total_citations = sum(count for _, count in report['top_cited_domains'])
    your_citations = sum(count for domain, count in report['top_cited_domains']
                         if your_domain in domain)
    share = (your_citations / max(total_citations, 1)) * 100
    # Find keywords where you are cited
    your_keywords = [r['query'] for r in report['details']
                     if any(your_domain in d for d in r['cited_domains'])]
    # Find keywords where you are NOT cited
    missing_keywords = [r['query'] for r in report['details']
                        if r['has_ai_overview'] and
                        not any(your_domain in d for d in r['cited_domains'])]
    return {
        'your_domain': your_domain,
        'citation_share': round(share, 1),
        'your_citations': your_citations,
        'total_citations': total_citations,
        'cited_keywords': your_keywords,
        'missing_keywords': missing_keywords
    }

share = citation_share(report, 'yoursite.com')
print(f'Citation share: {share["citation_share"]}% ({share["your_citations"]}/{share["total_citations"]})')
print(f'Missing from: {share["missing_keywords"]}')

Step 4: Store historical data for trend tracking

Save daily citation data to track whether your AEO efforts are working over time. A simple JSON file stores the time series.

Python
import json
from datetime import date

def save_citation_history(report: dict, your_domain: str) -> None:
    history_file = 'citation_history.json'
    try:
        with open(history_file) as f:
            history = json.load(f)
    except FileNotFoundError:
        history = []
    share = citation_share(report, your_domain)
    history.append({
        'date': date.today().isoformat(),
        'citation_share': share['citation_share'],
        'your_citations': share['your_citations'],
        'total_citations': share['total_citations'],
        'keywords_checked': report['total_keywords'],
        'keywords_with_overview': report['with_ai_overview']
    })
    with open(history_file, 'w') as f:
        json.dump(history, f, indent=2)
    print(f'Saved citation data for {date.today()}')
    if len(history) > 1:
        prev = history[-2]['citation_share']
        curr = share['citation_share']
        delta = curr - prev
        print(f'Trend: {prev}% -> {curr}% ({delta:+.1f}%)')

Step 5: Calculate monitoring costs

Budget your AI Overview monitoring based on keyword count and check frequency. Daily checks of 100 keywords cost $15/month.

Python
def monitoring_budget(num_keywords: int, checks_per_day: int = 1) -> dict:
    daily_credits = num_keywords * checks_per_day
    monthly_credits = daily_credits * 30
    monthly_cost = monthly_credits * 0.005
    return {
        'keywords': num_keywords,
        'daily_checks': checks_per_day,
        'monthly_credits': monthly_credits,
        'monthly_cost': f'${monthly_cost:.2f}',
        'plan': '$30/7K' if monthly_credits <= 7000
            else '$100/28K' if monthly_credits <= 28000
            else '$250/85K',
        'vs_semrush': f'Semrush Position Tracking: $139.95+/mo'
    }

for n in [50, 100, 500]:
    b = monitoring_budget(n)
    print(f'{b["keywords"]} keywords: {b["monthly_cost"]}/mo ({b["plan"]} plan)')
print(f'Comparison: Semrush starts at $139.95/mo for similar tracking')

Python Example

Python
import os, requests, time, json
from collections import Counter
from datetime import date

API_KEY = os.environ['SCAVIO_API_KEY']

def check_ai_overview(query):
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
        json={'query': query, 'country_code': 'us'})
    data = resp.json()
    aio = data.get('ai_overview', {})
    citations = aio.get('citations', []) if aio.get('text') else []
    return {'query': query, 'has_aio': bool(aio.get('text')),
            'domains': [c.get('domain', '') for c in citations]}

def main():
    keywords = ['best crm startups', 'crm comparison 2026', 'free crm tools']
    domain_counts = Counter()
    for kw in keywords:
        result = check_ai_overview(kw)
        print(f'{"+AIO" if result["has_aio"] else "-AIO"} {kw}: {len(result["domains"])} citations')
        for d in result['domains']:
            domain_counts[d] += 1
        time.sleep(0.3)
    print(f'\nTop cited domains:')
    for domain, count in domain_counts.most_common(5):
        print(f'  {domain}: {count}')
    print(f'Cost: ${len(keywords) * 0.005:.3f}')

if __name__ == '__main__':
    main()

JavaScript Example

JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;

async function checkAiOverview(query) {
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST',
    headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, country_code: 'us' })
  });
  const data = await resp.json();
  const aio = data.ai_overview || {};
  return {
    query,
    hasAio: Boolean(aio.text),
    domains: (aio.citations || []).map(c => c.domain || '')
  };
}

async function main() {
  const keywords = ['best crm startups', 'crm comparison 2026'];
  const domainCounts = {};
  for (const kw of keywords) {
    const r = await checkAiOverview(kw);
    console.log(`${r.hasAio ? '+AIO' : '-AIO'} ${kw}: ${r.domains.length} citations`);
    r.domains.forEach(d => { domainCounts[d] = (domainCounts[d] || 0) + 1; });
  }
  console.log('Top domains:', Object.entries(domainCounts).sort((a,b) => b[1]-a[1]).slice(0,5));
}

main().catch(console.error);

Expected Output

JSON
+AIO what is the best crm for startups: 4 citations
+AIO how to choose a crm 2026: 3 citations
+AIO crm software comparison: 5 citations
-AIO best free crm tools: 0 citations

3/4 keywords have AI Overviews
Citation share: 8.3% (1/12)
Missing from: ['crm software comparison']

50 keywords: $7.50/mo ($30/7K plan)
100 keywords: $15.00/mo ($30/7K plan)
500 keywords: $75.00/mo ($100/28K plan)

Related Tutorials

  • How to Build an Agency AEO Dashboard with a Search API
  • How to Batch SEO Rank Checks Overnight with an API
  • How to Replace Semrush API Credit Drain with a Lightweight Alternative

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.9+ installed. requests library installed. A Scavio API key from scavio.dev. A list of keywords where you expect AI Overviews. A Scavio API key gives you 50 free credits on signup.

Yes. The free tier includes 50 credits on signup, 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.

Related Resources

Use Case

AI Overview Citation Tracking

Read more
Workflow

AI Overview Citation Trust Check Workflow

Read more
Best Of

Best AI Overview Citation Trackers in 2026

Read more
Solution

AI Overview Citation Monitoring

Read more
Use Case

Track AI Citations vs Google Rankings

Read more
Glossary

AI Overview Citation Tracking

Read more

Start Building

Monitor which sites get cited in Google AI Overviews without expensive rank tracking tools. Python script using search API at $0.005/query.

Get Free API KeyRead the Docs
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy