Tutorial

How to Build a Keyword Volume Comparator

Compare keyword volume estimates across DataForSEO, Scavio SERP result counts, and Keyword Planner ranges. Cross-check pipeline in Python.

No single keyword volume source is perfectly accurate. DataForSEO provides clickstream estimates, Google Keyword Planner gives ranges, and SERP result counts from Scavio indicate content competition. Cross-checking across sources highlights keywords where estimates diverge and helps you make better decisions. This comparator pulls data from multiple sources and flags discrepancies.

Prerequisites

  • Python 3.8+
  • requests library
  • A Scavio API key from scavio.dev
  • Optional: DataForSEO API key for volume data

Walkthrough

Step 1: Set up multi-source data collection

Configure API clients for Scavio SERP data and volume estimation.

Python
import os, requests, json, re

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

def serp_signals(keyword):
    """Get competition and volume signals from SERP results."""
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
    organic = data.get('organic_results', [])
    total_results_str = data.get('search_information', {}).get('total_results', '0')
    try: total_results = int(re.sub(r'[^\d]', '', str(total_results_str)))
    except: total_results = 0
    has_ads = bool(data.get('ads', []))
    has_ao = bool(data.get('ai_overview'))
    paa_count = len(data.get('related_questions', []))
    return {
        'keyword': keyword, 'total_results': total_results,
        'organic_count': len(organic), 'has_ads': has_ads,
        'has_ai_overview': has_ao, 'paa_count': paa_count
    }

signals = serp_signals('best serp api 2026')
for k, v in signals.items():
    print(f'  {k}: {v}')

Step 2: Estimate relative volume from SERP signals

Use SERP features to estimate keyword competitiveness and volume tier.

Python
def estimate_volume_tier(signals):
    """Estimate volume tier from SERP signals (not exact volume)."""
    score = 0
    if signals['total_results'] > 1000000: score += 3
    elif signals['total_results'] > 100000: score += 2
    elif signals['total_results'] > 10000: score += 1
    if signals['has_ads']: score += 2  # Ads = commercial intent + volume
    if signals['has_ai_overview']: score += 1  # AO = Google considers query important
    if signals['paa_count'] >= 4: score += 1
    tiers = {0: 'very_low', 1: 'low', 2: 'low', 3: 'medium',
             4: 'medium', 5: 'high', 6: 'high', 7: 'very_high'}
    tier = tiers.get(min(score, 7), 'very_high')
    return {'tier': tier, 'score': score, 'signals': signals}

keywords = ['best serp api', 'python web scraping', 'curl to python converter',
            'tiktok analytics api free', 'how to make money online']
for kw in keywords:
    signals = serp_signals(kw)
    est = estimate_volume_tier(signals)
    print(f'  {kw:35} | tier: {est["tier"]:10} | score: {est["score"]} | ads: {signals["has_ads"]} | AO: {signals["has_ai_overview"]}')

Step 3: Compare keywords head to head

Rank keywords by estimated competition and volume for prioritization.

Python
def compare_keywords(keywords):
    results = []
    for kw in keywords:
        signals = serp_signals(kw)
        est = estimate_volume_tier(signals)
        results.append({**signals, **est})
    results.sort(key=lambda x: x['score'], reverse=True)
    cost = len(keywords) * 0.005
    print(f'\nKeyword Volume Comparison ({len(keywords)} keywords, ${cost:.3f}):')
    print(f'{"Keyword":35} | {"Tier":10} | {"Results":>12} | {"Ads":4} | {"AO":3} | {"PAA":3}')
    print('-' * 85)
    for r in results:
        print(f'{r["keyword"]:35} | {r["tier"]:10} | {r["total_results"]:12,} | {"Y" if r["has_ads"] else "N":4} | {"Y" if r["has_ai_overview"] else "N":3} | {r["paa_count"]:3}')
    return results

ranked = compare_keywords(keywords)

Step 4: Generate keyword research report

Output a prioritized keyword report with recommendations.

Python
def keyword_report(keywords):
    results = compare_keywords(keywords)
    print(f'\n=== Keyword Research Report ===')
    # Group by tier
    tiers = {}
    for r in results:
        tier = r['tier']
        if tier not in tiers: tiers[tier] = []
        tiers[tier].append(r)
    for tier in ['very_high', 'high', 'medium', 'low', 'very_low']:
        if tier in tiers:
            print(f'\n  {tier.upper()} volume ({len(tiers[tier])} keywords):')
            for r in tiers[tier]:
                opportunity = 'HIGH' if not r['has_ads'] and r['score'] >= 3 else 'MEDIUM' if r['score'] >= 2 else 'LOW'
                print(f'    {r["keyword"]:35} | opportunity: {opportunity}')
    # Quick wins: medium+ volume without ads
    quick_wins = [r for r in results if r['score'] >= 3 and not r['has_ads']]
    if quick_wins:
        print(f'\n  QUICK WINS (volume without ad competition):')
        for r in quick_wins:
            print(f'    - {r["keyword"]}')
    cost = len(keywords) * 0.005
    print(f'\n  Report cost: ${cost:.3f}')

keyword_report(keywords)

Python Example

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

def compare(keywords):
    for kw in keywords:
        data = requests.post('https://api.scavio.dev/api/v1/search',
            headers=SH, json={'query': kw, 'country_code': 'us'}).json()
        total = data.get('search_information', {}).get('total_results', 0)
        ads = bool(data.get('ads'))
        ao = bool(data.get('ai_overview'))
        print(f'{kw:30} | results: {total:>10} | ads: {ads} | AO: {ao}')
    print(f'Cost: ${len(keywords) * 0.005:.3f}')

compare(['serp api', 'web scraping tool', 'python tutorial'])

JavaScript Example

JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function compare(keywords) {
  for (const kw of keywords) {
    const data = await fetch('https://api.scavio.dev/api/v1/search', {
      method: 'POST', headers: SH,
      body: JSON.stringify({ query: kw, country_code: 'us' })
    }).then(r => r.json());
    const total = data.search_information?.total_results || 0;
    console.log(`${kw.padEnd(30)} | results: ${total} | ads: ${!!data.ads} | AO: ${!!data.ai_overview}`);
  }
}
compare(['serp api', 'web scraping tool']).catch(console.error);

Expected Output

JSON
Keyword Volume Comparison (5 keywords, $0.025):
Keyword                             | Tier       |      Results | Ads  | AO  | PAA
-------------------------------------------------------------------------------------
how to make money online            | very_high  |  4,230,000,000 | Y    | Y   |   4
python web scraping                 | high       |    89,400,000 | Y    | Y   |   3
best serp api                       | medium     |    12,300,000 | Y    | N   |   4
tiktok analytics api free           | low        |     2,100,000 | N    | N   |   2
curl to python converter            | low        |     1,800,000 | N    | Y   |   1

QUICK WINS (volume without ad competition):
    - tiktok analytics api free

Report cost: $0.025

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. Optional: DataForSEO API key for volume data. 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

Compare keyword volume estimates across DataForSEO, Scavio SERP result counts, and Keyword Planner ranges. Cross-check pipeline in Python.