Workflow

Historical SERP Snapshot

Weekly SERP snapshot archival for competitive trend analysis. Track organic positions, AI Overviews, and SERP features over time.

Overview

This workflow archives a full SERP snapshot for target keywords every week. Each snapshot captures organic positions, AI Overview presence, featured snippets, People Also Ask questions, and local pack results. Over time, the archive enables competitive trend analysis, algorithm update impact measurement, and SERP feature evolution tracking.

Trigger

Cron schedule (every Sunday at 6:00 AM UTC)

Schedule

Runs every Sunday at 6:00 AM UTC

Workflow Steps

1

Load keyword list

Read the list of keywords to archive from configuration. These should include your tracked keywords plus competitive terms.

2

Query full SERP for each keyword

Call Scavio with num=20 and ai_overview=true to capture the full SERP state including all features.

3

Extract structured snapshot data

Parse each response into a structured snapshot: positions, domains, features, PAA questions, and AI Overview content.

4

Archive to storage

Append the weekly snapshot to the historical archive with a timestamp for time-series analysis.

Python Implementation

Python
import requests
import json
from pathlib import Path
from datetime import datetime

API_KEY = "your_scavio_api_key"

KEYWORDS = [
    "best SERP API 2026",
    "search API for AI agents",
    "web scraping API alternative",
    "MCP search server",
    "Google SERP data structured",
]

def snapshot_keyword(keyword: str) -> dict:
    res = requests.post(
        "https://api.scavio.dev/api/v1/search",
        headers={"x-api-key": API_KEY},
        json={"platform": "google", "query": keyword, "num": 20, "ai_overview": True},
        timeout=15,
    )
    res.raise_for_status()
    data = res.json()
    return {
        "keyword": keyword,
        "organic": [
            {
                "position": r.get("position"),
                "domain": r.get("link", "").split("/")[2] if "/" in r.get("link", "") else "",
                "title": r.get("title", ""),
            }
            for r in data.get("organic", [])[:20]
        ],
        "has_ai_overview": bool(data.get("ai_overview")),
        "ai_overview_preview": (data.get("ai_overview", {}) or {}).get("text", "")[:300],
        "has_featured_snippet": bool(data.get("featured_snippet")),
        "people_also_ask": [q.get("question", "") for q in data.get("people_also_ask", [])],
        "has_local_pack": bool(data.get("local_pack")),
    }

def run():
    date = datetime.utcnow().strftime("%Y-%m-%d")
    snapshots = [snapshot_keyword(kw) for kw in KEYWORDS]

    # Save weekly snapshot
    archive_dir = Path("serp_archive")
    archive_dir.mkdir(exist_ok=True)
    snapshot_path = archive_dir / f"snapshot_{date}.json"
    snapshot_path.write_text(json.dumps({"date": date, "keywords": len(KEYWORDS), "snapshots": snapshots}, indent=2))

    # Summary
    aio_count = sum(1 for s in snapshots if s["has_ai_overview"])
    snippet_count = sum(1 for s in snapshots if s["has_featured_snippet"])
    local_count = sum(1 for s in snapshots if s["has_local_pack"])

    print(f"Archived {len(KEYWORDS)} keywords for {date}")
    print(f"  AI Overviews: {aio_count}/{len(KEYWORDS)}")
    print(f"  Featured Snippets: {snippet_count}/{len(KEYWORDS)}")
    print(f"  Local Packs: {local_count}/{len(KEYWORDS)}")
    print(f"  Credits used: {len(KEYWORDS)}")

if __name__ == "__main__":
    run()

JavaScript Implementation

JavaScript
const API_KEY = "your_scavio_api_key";
const KEYWORDS = ["best SERP API 2026", "search API for AI agents", "web scraping API alternative"];

async function snapshotKeyword(keyword) {
  const res = await fetch("https://api.scavio.dev/api/v1/search", {
    method: "POST",
    headers: { "x-api-key": API_KEY, "content-type": "application/json" },
    body: JSON.stringify({ platform: "google", query: keyword, num: 20, ai_overview: true }),
  });
  if (!res.ok) throw new Error(`scavio ${res.status}`);
  const data = await res.json();
  return {
    keyword,
    organic: (data.organic ?? []).slice(0, 20).map((r) => ({ position: r.position, domain: r.link ? new URL(r.link).hostname : "", title: r.title ?? "" })),
    hasAiOverview: !!data.ai_overview,
    hasFeaturedSnippet: !!data.featured_snippet,
    paa: (data.people_also_ask ?? []).map((q) => q.question ?? ""),
  };
}

const snapshots = [];
for (const kw of KEYWORDS) snapshots.push(await snapshotKeyword(kw));
const aio = snapshots.filter((s) => s.hasAiOverview).length;
console.log(`Archived ${KEYWORDS.length} keywords: ${aio} with AI Overviews`);

Platforms Used

Google

Web search with knowledge graph, PAA, and AI overviews

Frequently Asked Questions

This workflow archives a full SERP snapshot for target keywords every week. Each snapshot captures organic positions, AI Overview presence, featured snippets, People Also Ask questions, and local pack results. Over time, the archive enables competitive trend analysis, algorithm update impact measurement, and SERP feature evolution tracking.

This workflow uses a cron schedule (every sunday at 6:00 am utc). Runs every Sunday at 6:00 AM UTC.

This workflow uses the following Scavio platforms: google. Each platform is called via the same unified API endpoint.

Yes. Scavio's free tier includes 250 credits per month with no credit card required. That is enough to test and validate this workflow before scaling it.

Historical SERP Snapshot

Weekly SERP snapshot archival for competitive trend analysis. Track organic positions, AI Overviews, and SERP features over time.