Tutorial

How to Build a Domain Metrics Pipeline via SERP Analysis

Check domain authority signals by analyzing SERP presence, ranking frequency, and featured snippet ownership using the Scavio search API.

Domain authority is not a single metric you can look up -- it is a composite signal derived from how often a domain ranks, where it ranks, and what SERP features it owns. Third-party DA scores from Moz or Ahrefs are proprietary estimates that lag behind reality. A SERP-based approach queries multiple relevant keywords, counts how often a target domain appears in the top 10, tracks its average position, and checks for featured snippet or AI Overview citations. This tutorial builds that pipeline using the Scavio API, producing a domain strength report based on live SERP data rather than stale crawl indices.

Prerequisites

  • Python 3.8 or higher installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • A list of industry keywords relevant to the target domain

Walkthrough

Step 1: Define the target domain and keyword set

Choose the domain you want to evaluate and a set of keywords that represent its competitive landscape. More keywords produce a more accurate picture.

Python
TARGET_DOMAIN = "example.com"
KEYWORDS = [
    "best project management tool",
    "project management software 2026",
    "team collaboration platform",
    "agile project tracking",
    "free project management app"
]

Step 2: Query SERPs and extract ranking data

For each keyword, fetch the SERP and check if the target domain appears in organic results. Record its position and any SERP features it owns.

Python
import os
import requests

API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
ENDPOINT = "https://api.scavio.dev/api/v1/search"

def analyze_serp(query: str, domain: str) -> dict:
    r = requests.post(
        ENDPOINT,
        headers={"x-api-key": API_KEY},
        json={"query": query, "country_code": "us"}
    )
    data = r.json()
    result = {"query": query, "position": None, "featured_snippet": False, "ai_overview": False}
    for item in data.get("organic_results", []):
        if domain in item.get("link", ""):
            result["position"] = item["position"]
            break
    snippet = data.get("featured_snippet", {})
    if domain in snippet.get("link", ""):
        result["featured_snippet"] = True
    for src in data.get("ai_overview", {}).get("sources", []):
        if domain in src.get("domain", ""):
            result["ai_overview"] = True
    return result

Step 3: Aggregate metrics into a domain score

Calculate visibility rate, average position, and SERP feature ownership across all queried keywords.

Python
def compute_metrics(results: list[dict]) -> dict:
    total = len(results)
    ranked = [r for r in results if r["position"] is not None]
    positions = [r["position"] for r in ranked]
    snippets = sum(1 for r in results if r["featured_snippet"])
    ai_cites = sum(1 for r in results if r["ai_overview"])
    return {
        "keywords_checked": total,
        "keywords_ranked": len(ranked),
        "visibility_rate": round(len(ranked) / total * 100, 1) if total else 0,
        "avg_position": round(sum(positions) / len(positions), 1) if positions else None,
        "featured_snippets": snippets,
        "ai_overview_citations": ai_cites
    }

Python Example

Python
import os
import json
import requests

API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
ENDPOINT = "https://api.scavio.dev/api/v1/search"

def analyze_serp(query: str, domain: str) -> dict:
    r = requests.post(
        ENDPOINT,
        headers={"x-api-key": API_KEY},
        json={"query": query, "country_code": "us"}
    )
    r.raise_for_status()
    data = r.json()
    result = {"query": query, "position": None, "featured_snippet": False, "ai_overview": False}
    for item in data.get("organic_results", []):
        if domain in item.get("link", ""):
            result["position"] = item["position"]
            break
    snippet = data.get("featured_snippet", {})
    if domain in snippet.get("link", ""):
        result["featured_snippet"] = True
    for src in data.get("ai_overview", {}).get("sources", []):
        if domain in src.get("domain", ""):
            result["ai_overview"] = True
    return result

def domain_metrics(domain: str, keywords: list[str]) -> dict:
    results = [analyze_serp(kw, domain) for kw in keywords]
    ranked = [r for r in results if r["position"] is not None]
    positions = [r["position"] for r in ranked]
    return {
        "domain": domain,
        "keywords_checked": len(keywords),
        "keywords_ranked": len(ranked),
        "visibility_pct": round(len(ranked) / len(keywords) * 100, 1),
        "avg_position": round(sum(positions) / len(positions), 1) if positions else None,
        "featured_snippets": sum(1 for r in results if r["featured_snippet"]),
        "ai_overview_citations": sum(1 for r in results if r["ai_overview"]),
        "details": results
    }

if __name__ == "__main__":
    keywords = ["best project management tool", "project management software 2026", "team collaboration platform"]
    report = domain_metrics("example.com", keywords)
    print(json.dumps(report, indent=2))

JavaScript Example

JavaScript
const API_KEY = process.env.SCAVIO_API_KEY || "your_scavio_api_key";
const ENDPOINT = "https://api.scavio.dev/api/v1/search";

async function analyzeSerp(query, domain) {
  const res = await fetch(ENDPOINT, {
    method: "POST",
    headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ query, country_code: "us" })
  });
  const data = await res.json();
  const result = { query, position: null, featuredSnippet: false, aiOverview: false };
  for (const item of data.organic_results || []) {
    if ((item.link || "").includes(domain)) { result.position = item.position; break; }
  }
  if ((data.featured_snippet?.link || "").includes(domain)) result.featuredSnippet = true;
  for (const src of data.ai_overview?.sources || []) {
    if ((src.domain || "").includes(domain)) result.aiOverview = true;
  }
  return result;
}

async function domainMetrics(domain, keywords) {
  const results = [];
  for (const kw of keywords) results.push(await analyzeSerp(kw, domain));
  const ranked = results.filter(r => r.position !== null);
  const positions = ranked.map(r => r.position);
  console.log(`${domain}: ${ranked.length}/${keywords.length} keywords ranked`);
  if (positions.length) console.log(`Avg position: ${(positions.reduce((a,b) => a+b, 0) / positions.length).toFixed(1)}`);
  console.log(`Featured snippets: ${results.filter(r => r.featuredSnippet).length}`);
  console.log(`AI Overview citations: ${results.filter(r => r.aiOverview).length}`);
}

domainMetrics("example.com", ["best project management tool", "project management software 2026"]).catch(console.error);

Expected Output

JSON
{
  "domain": "example.com",
  "keywords_checked": 5,
  "keywords_ranked": 3,
  "visibility_pct": 60.0,
  "avg_position": 4.7,
  "featured_snippets": 1,
  "ai_overview_citations": 1,
  "details": [
    { "query": "best project management tool", "position": 3, "featured_snippet": true, "ai_overview": false },
    { "query": "project management software 2026", "position": 5, "featured_snippet": false, "ai_overview": true },
    { "query": "team collaboration platform", "position": 6, "featured_snippet": false, "ai_overview": false }
  ]
}

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 or higher installed. requests library installed. A Scavio API key from scavio.dev. A list of industry keywords relevant to the target domain. 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

Check domain authority signals by analyzing SERP presence, ranking frequency, and featured snippet ownership using the Scavio search API.