ScavioScavio
ProductPricingDocs
Sign InGet Started
  1. Home
  2. Tutorials
  3. How to Build Keyword Gap Finder with SERP Data
Tutorial

How to Build Keyword Gap Finder with SERP Data

Find keywords where competitors rank but you do not. SERP-based gap analysis at $0.005/keyword without expensive SEO tools.

Get Free API KeyAPI Docs

Keyword gap analysis shows which queries competitors rank for that you do not. SEO tools charge $100+/month for this feature. This tutorial builds the same analysis using raw SERP data at $0.005/keyword. Feed in your domain and competitor domains, and get a prioritized list of content opportunities.

Prerequisites

  • Python 3.8+
  • requests library
  • A Scavio API key from scavio.dev
  • Your domain and 2-3 competitor domains

Walkthrough

Step 1: Generate keyword candidates from competitor SERPs

Find keywords by checking what competitors rank for in your niche.

Python
import os, requests, json
from collections import defaultdict

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

MY_DOMAIN = 'yourdomain.com'
COMPETITORS = ['competitor1.com', 'competitor2.com']
SEED_KEYWORDS = ['search api', 'serp api', 'web search api', 'mcp search', 'ai agent search']

def check_rankings(keyword, domains):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
    organic = data.get('organic_results', [])
    rankings = {}
    for i, r in enumerate(organic):
        link = r.get('link', '')
        for domain in domains:
            if domain in link and domain not in rankings:
                rankings[domain] = i + 1
    return rankings

results = []
for kw in SEED_KEYWORDS:
    all_domains = [MY_DOMAIN] + COMPETITORS
    rankings = check_rankings(kw, all_domains)
    results.append({'keyword': kw, 'rankings': rankings})
    my_pos = rankings.get(MY_DOMAIN, '-')
    comp_pos = {c: rankings.get(c, '-') for c in COMPETITORS}
    print(f'  {kw:30} | You: {str(my_pos):5} | {", ".join(f"{c.split(".")[0]}: {v}" for c, v in comp_pos.items())}')
print(f'\nCost: ${len(SEED_KEYWORDS) * 0.005:.3f}')

Step 2: Identify keyword gaps

Find keywords where competitors rank but you do not.

Python
def find_gaps(results, my_domain, competitors):
    gaps = []
    for r in results:
        kw = r['keyword']
        rankings = r['rankings']
        my_rank = rankings.get(my_domain)
        comp_ranks = {c: rankings.get(c) for c in competitors if rankings.get(c)}
        if not my_rank and comp_ranks:
            best_comp = min(comp_ranks.items(), key=lambda x: x[1])
            gaps.append({
                'keyword': kw,
                'best_competitor': best_comp[0],
                'competitor_position': best_comp[1],
                'num_competitors_ranking': len(comp_ranks),
                'difficulty': 'easy' if best_comp[1] > 5 else 'medium' if best_comp[1] > 2 else 'hard'
            })
    gaps.sort(key=lambda g: g['competitor_position'])
    print(f'\n=== Keyword Gaps ===')
    print(f'  You are missing from {len(gaps)} keywords where competitors rank:')
    for g in gaps:
        print(f'  [{g["difficulty"]:6}] "{g["keyword"]}" - {g["best_competitor"]} at #{g["competitor_position"]}')
    return gaps

gaps = find_gaps(results, MY_DOMAIN, COMPETITORS)

Step 3: Expand gaps with related keywords

Use People Also Ask data to find more gap opportunities.

Python
def expand_gaps(gaps):
    expanded = []
    for gap in gaps[:5]:  # Expand top 5 gaps
        kw = gap['keyword']
        data = requests.post('https://api.scavio.dev/api/v1/search',
            headers=SH, json={'query': kw, 'country_code': 'us'}).json()
        paa = data.get('people_also_ask', [])
        related = [q.get('question', '') for q in paa if q.get('question')]
        if related:
            expanded.append({'seed': kw, 'related': related[:4]})
    print(f'\n=== Expanded Gap Opportunities ===')
    total_new = 0
    for e in expanded:
        print(f'\n  "{e["seed"]}" -> {len(e["related"])} related keywords:')
        for r in e['related']:
            print(f'    - {r[:55]}')
            total_new += 1
    print(f'\n  New keyword opportunities: {total_new}')
    print(f'  Expansion cost: ${len(expanded) * 0.005:.3f}')
    print(f'  Total cost: ${(len(SEED_KEYWORDS) + len(expanded)) * 0.005:.3f}')
    return expanded

expand_gaps(gaps)

Python Example

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

def gap_check(keyword, my_domain, competitors):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
    organic = data.get('organic_results', [])
    my_rank = next((i+1 for i, r in enumerate(organic) if my_domain in r.get('link', '')), None)
    comp_ranks = {c: next((i+1 for i, r in enumerate(organic) if c in r.get('link', '')), None) for c in competitors}
    is_gap = not my_rank and any(comp_ranks.values())
    print(f'{"GAP" if is_gap else "OK":3} | {keyword:30} | You: {my_rank or "-"} | Comps: {comp_ranks}')

gap_check('search api python', 'scavio.dev', ['tavily.com'])
print('Cost: $0.005')

JavaScript Example

JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
async function gapCheck(keyword, myDomain, competitors) {
  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 organic = data.organic_results || [];
  const myRank = organic.findIndex(r => r.link?.includes(myDomain));
  const compRank = organic.findIndex(r => competitors.some(c => r.link?.includes(c)));
  console.log(`${keyword}: You ${myRank >= 0 ? '#'+(myRank+1) : 'absent'} | Comp ${compRank >= 0 ? '#'+(compRank+1) : 'absent'}`);
}
await gapCheck('search api python', 'scavio.dev', ['tavily.com']);

Expected Output

JSON
  search api                      | You: 2     | competitor1: 4, competitor2: 7
  serp api                        | You: -     | competitor1: 3
  web search api                  | You: 5     | competitor1: 2, competitor2: 6
  mcp search                      | You: -     | competitor1: 1, competitor2: 5
  ai agent search                 | You: 3     | competitor1: -, competitor2: 8

Cost: $0.025

=== Keyword Gaps ===
  You are missing from 2 keywords where competitors rank:
  [hard  ] "mcp search" - competitor1.com at #1
  [medium] "serp api" - competitor1.com at #3

=== Expanded Gap Opportunities ===
  "mcp search" -> 4 related keywords:
    - What is MCP protocol for AI agents
    - Best MCP search servers 2026
  New keyword opportunities: 8

Related Tutorials

  • How to Build a DIY Keyword Rank Tracker
  • How to Build a Keyword Volume Comparator
  • How to Build SEO Dashboard with Raw APIs

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. Your domain and 2-3 competitor domains. 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

Best Of

Best SEO Keyword APIs for Agency Work in 2026

Read more
Glossary

SERP Gap Analysis

Read more
Solution

Automated SERP Gap Analysis

Read more
Best Of

Best API for Agency SEO Reporting in 2026

Read more
Use Case

AppSumo SEO Tool to API Migration

Read more
Comparison

Semrush API vs Raw SERP API

Read more

Start Building

Find keywords where competitors rank but you do not. SERP-based gap analysis at $0.005/keyword without expensive SEO tools.

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