Resumen
Este flujo de trabajo goes mas alla de seguimiento de posiciones by monitoreo el entire SERP structure for un establecer of palabras clave. It detecta cuando fragmentos destacados appear o disappear, cuando People Also Ask boxes cambio, cuando nuevo caracteristicas SERP like video carousels o knowledge panels mostrar up, y cuando posiciones organicas cambio. SEO teams usar it to understand el full competitive landscape, no solo position numbers.
Desencadenador
Cron programar (diario at 6 AM UTC)
Programación
Ejecuta diario at 6 AM UTC
Pasos del flujo de trabajo
Cargar palabra clave establecer
Leer el palabras clave objetivo y el caracteristicas SERP to monitorear for cada.
Obtener full SERP datos
Call el Scavio API con plataforma google for cada palabra clave, requesting todos disponible caracteristicas SERP.
Extraer SERP structure
Analizar el respuesta for posiciones organicas, fragmentos destacados, People Also Ask, knowledge panels, y video carousels.
Diff contra anterior snapshot
Comparar el actual SERP structure to el anterior day's snapshot. Identificar que appeared, disappeared, o moved.
Clasificar cambios
Tag cada cambio as un posicionamiento cambio, caracteristica appearance, caracteristica removal, o contenido cambio dentro de un caracteristica.
Generar informe
Compile todos cambios en un structured informe y deliver via correo electronico o Slack.
Implementacion en Python
import requests
import json
from pathlib import Path
from datetime import datetime
API_KEY = "your_scavio_api_key"
def fetch_serp(query: str) -> dict:
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={
"platform": "google",
"query": query,
"num": 20,
"ai_overview": True,
},
timeout=15,
)
res.raise_for_status()
data = res.json()
return {
"top_3": [r.get("link", "") for r in data.get("organic", [])[:3]],
"has_featured_snippet": data.get("featured_snippet") is not None,
"has_ai_overview": data.get("ai_overview") is not None,
"paa_count": len(data.get("people_also_ask", [])),
"has_knowledge_panel": data.get("knowledge_graph") is not None,
}
def run():
keywords = [
"best SERP API 2026",
"Google search API alternative",
"web scraping vs API",
]
snapshot_path = Path("serp_snapshots.json")
previous = json.loads(snapshot_path.read_text()) if snapshot_path.exists() else {}
changes = []
current = {}
for kw in keywords:
serp = fetch_serp(kw)
current[kw] = serp
prev = previous.get(kw)
if prev:
diffs = []
if prev["top_3"] != serp["top_3"]:
diffs.append("top 3 organic positions changed")
if prev["has_featured_snippet"] != serp["has_featured_snippet"]:
status = "appeared" if serp["has_featured_snippet"] else "disappeared"
diffs.append(f"featured snippet {status}")
if prev["has_ai_overview"] != serp["has_ai_overview"]:
status = "appeared" if serp["has_ai_overview"] else "disappeared"
diffs.append(f"AI Overview {status}")
if diffs:
changes.append({"keyword": kw, "changes": diffs})
snapshot_path.write_text(json.dumps(current, indent=2))
date_str = datetime.utcnow().strftime("%Y-%m-%d")
if changes:
print(f"SERP changes detected on {date_str}:")
for c in changes:
print(f" {c['keyword']}: {', '.join(c['changes'])}")
else:
print(f"No SERP changes on {date_str}")
if __name__ == "__main__":
run()Implementacion en JavaScript
const API_KEY = "your_scavio_api_key";
async function fetchSerp(query) {
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,
num: 20,
ai_overview: true,
}),
});
if (!res.ok) throw new Error(`scavio ${res.status}`);
const data = await res.json();
return {
top3: (data.organic ?? []).slice(0, 3).map((r) => r.link ?? ""),
hasFeaturedSnippet: data.featured_snippet != null,
hasAiOverview: data.ai_overview != null,
paaCount: (data.people_also_ask ?? []).length,
hasKnowledgePanel: data.knowledge_graph != null,
};
}
async function run() {
const fs = await import("fs/promises");
const keywords = [
"best SERP API 2026",
"Google search API alternative",
"web scraping vs API",
];
let previous = {};
try {
previous = JSON.parse(await fs.readFile("serp_snapshots.json", "utf8"));
} catch {}
const current = {};
const changes = [];
for (const kw of keywords) {
const serp = await fetchSerp(kw);
current[kw] = serp;
const prev = previous[kw];
if (prev) {
const diffs = [];
if (JSON.stringify(prev.top3) !== JSON.stringify(serp.top3)) {
diffs.push("top 3 organic positions changed");
}
if (prev.hasFeaturedSnippet !== serp.hasFeaturedSnippet) {
diffs.push(`featured snippet ${serp.hasFeaturedSnippet ? "appeared" : "disappeared"}`);
}
if (prev.hasAiOverview !== serp.hasAiOverview) {
diffs.push(`AI Overview ${serp.hasAiOverview ? "appeared" : "disappeared"}`);
}
if (diffs.length) changes.push({ keyword: kw, changes: diffs });
}
}
await fs.writeFile("serp_snapshots.json", JSON.stringify(current, null, 2));
const date = new Date().toISOString().slice(0, 10);
if (changes.length) {
console.log(`SERP changes detected on ${date}:`);
for (const c of changes) {
console.log(` ${c.keyword}: ${c.changes.join(", ")}`);
}
} else {
console.log(`No SERP changes on ${date}`);
}
}
run();Plataformas utilizadas
Búsqueda web con grafo de conocimiento, PAA y resúmenes de IA