Early-stage SaaS companies need organic traffic but cannot afford to write hundreds of pages manually. Programmatic SEO generates keyword-targeted pages at scale by combining search data with templates. The approach works especially well for comparison pages, feature directories, and integration listings. This tutorial shows how to use SERP data from the Scavio API to identify long-tail keywords, validate demand, and generate pages that target real search queries. You will build a pipeline that produces dozens of SEO pages from a single keyword seed list.
Prerequisites
- Python 3.8+ installed
- requests library installed
- A Scavio API key from scavio.dev
- A SaaS product with defined features or integrations
Walkthrough
Step 1: Seed keyword discovery
Use People Also Ask and related searches to expand your seed keywords into long-tail targets.
import os, requests
API_KEY = os.environ["SCAVIO_API_KEY"]
def expand_keywords(seed):
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": seed})
data = resp.json()
paa = [q.get("question","") for q in data.get("people_also_ask", [])]
related = [r.get("query","") for r in data.get("related_searches", [])]
return {"seed": seed, "paa": paa, "related": related}
result = expand_keywords("crm for startups")
print(f"Found {len(result['paa'])} PAA + {len(result['related'])} related")Step 2: Validate keyword demand
Check each keyword candidate for competition level and content gaps.
def validate_keyword(keyword):
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": keyword})
data = resp.json()
results = data.get("organic_results", [])[:10]
weak_results = sum(1 for r in results
if len(r.get("snippet","")) < 50 or "reddit.com" in r.get("link",""))
return {
"keyword": keyword,
"competition": "low" if weak_results >= 3 else "medium" if weak_results >= 1 else "high",
"has_aio": bool(data.get("ai_overview")),
}Step 3: Generate page data
Build structured data for each page using search results as content enrichment.
def generate_page(keyword, template_type="comparison"):
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": keyword})
data = resp.json()
return {
"slug": keyword.lower().replace(" ", "-"),
"title": keyword.title(),
"type": template_type,
"top_results": [{"title": r["title"], "url": r.get("link","")}
for r in data.get("organic_results", [])[:5]],
"questions": [q.get("question","") for q in data.get("people_also_ask", [])],
}Step 4: Batch generate pages
Process all validated keywords and output page data for your template engine.
import json
seeds = ["crm for startups", "project management for freelancers"]
all_keywords = []
for seed in seeds:
expanded = expand_keywords(seed)
all_keywords.extend(expanded["paa"][:3])
all_keywords.extend(expanded["related"][:3])
pages = []
for kw in all_keywords:
v = validate_keyword(kw)
if v["competition"] != "high":
pages.append(generate_page(kw))
with open("programmatic_pages.json", "w") as f:
json.dump(pages, f, indent=2)
print(f"Generated {len(pages)} pages from {len(all_keywords)} keywords")Python Example
import os, requests
API_KEY = os.environ["SCAVIO_API_KEY"]
def expand(seed):
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": seed})
d = resp.json()
paa = [q.get("question","") for q in d.get("people_also_ask",[])]
related = [r.get("query","") for r in d.get("related_searches",[])]
return paa + related
for kw in expand("crm for startups"):
print(kw)JavaScript Example
const H = {"x-api-key": process.env.SCAVIO_API_KEY, "Content-Type": "application/json"};
async function expand(seed) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query: seed})
});
const d = await r.json();
const paa = (d.people_also_ask||[]).map(q=>q.question);
const rel = (d.related_searches||[]).map(r=>r.query);
return [...paa, ...rel];
}
expand("crm for startups").then(kws => kws.forEach(k => console.log(k)));Expected Output
A programmatic SEO pipeline that discovers long-tail keywords, validates demand, and generates page data for template-based content at scale.