Competitor analysis is a recurring task for product managers, marketers, and founders. Manually checking where competitors rank for key terms, what news they generate, and how their product listings evolve is time-consuming. This tutorial builds an automated competitor intelligence pipeline using the Scavio API. Given a list of competitor domains, it tracks their organic SERP positions for a set of keywords, fetches recent news mentions, and writes a weekly summary report.
Prerequisites
- Python 3.10 or higher
- requests library installed
- A Scavio API key
- A list of competitor domains and target keywords
Walkthrough
Step 1: Define competitors and keywords
Set up a dictionary mapping competitor names to their domains, and a list of keywords to track.
COMPETITORS = {
"Acme Corp": "acmecorp.com",
"Beta Tools": "betatools.io",
}
KEYWORDS = ["project management software", "task tracking tool", "team collaboration app"]Step 2: Track SERP positions for each competitor
For each keyword, fetch SERP results and scan organic_results for each competitor's domain.
def track_positions(keyword: str) -> dict:
data = search_google(keyword)
positions = {}
for name, domain in COMPETITORS.items():
for r in data.get("organic_results", []):
if domain in r.get("link", ""):
positions[name] = r["position"]
break
return positionsStep 3: Fetch news mentions
Search Google News for each competitor name to find recent articles, product announcements, and press coverage.
def get_news(competitor_name: str) -> list[dict]:
data = search_google(f"{competitor_name} news 2026")
return data.get("news_results", data.get("organic_results", []))[:5]Step 4: Generate the weekly report
Combine SERP rankings and news mentions into a structured report and save it as a markdown file.
from datetime import date
def generate_report() -> str:
lines = [f"# Competitor Intelligence Report — {date.today()}\n"]
for kw in KEYWORDS:
lines.append(f"## {kw}")
positions = track_positions(kw)
for name, pos in positions.items():
lines.append(f" - {name}: #{pos}")
return "\n".join(lines)Python Example
import os
import requests
from datetime import date
API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
ENDPOINT = "https://api.scavio.dev/api/v1/search"
COMPETITORS = {"Acme": "acmecorp.com", "Beta": "betatools.io"}
KEYWORDS = ["project management software", "task tracking tool"]
def search_google(q: str) -> dict:
r = requests.post(ENDPOINT, headers={"x-api-key": API_KEY},
json={"query": q, "country_code": "us"})
r.raise_for_status()
return r.json()
def track(kw: str) -> dict:
data = search_google(kw)
out = {}
for name, domain in COMPETITORS.items():
for r in data.get("organic_results", []):
if domain in r.get("link", ""):
out[name] = r["position"]
break
return out
if __name__ == "__main__":
for kw in KEYWORDS:
pos = track(kw)
print(f"\n{kw}:")
for name, p in pos.items():
print(f" {name}: #{p}")JavaScript Example
const API_KEY = process.env.SCAVIO_API_KEY || "your_scavio_api_key";
const ENDPOINT = "https://api.scavio.dev/api/v1/search";
const COMPETITORS = { "Acme": "acmecorp.com", "Beta": "betatools.io" };
const KEYWORDS = ["project management software", "task tracking tool"];
async function searchGoogle(q) {
const res = await fetch(ENDPOINT, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ query: q, country_code: "us" })
});
return res.json();
}
async function trackPositions(kw) {
const data = await searchGoogle(kw);
const out = {};
for (const [name, domain] of Object.entries(COMPETITORS)) {
const match = (data.organic_results || []).find(r => r.link.includes(domain));
if (match) out[name] = match.position;
}
return out;
}
async function main() {
for (const kw of KEYWORDS) {
const pos = await trackPositions(kw);
console.log(`\n${kw}:`);
Object.entries(pos).forEach(([n, p]) => console.log(` ${n}: #${p}`));
}
}
main().catch(console.error);Expected Output
project management software:
Acme: #3
Beta: #7
task tracking tool:
Acme: #5
Beta: not ranked