Overview
This workflow refreshes franchise operator data weekly across all monitored locations. It queries Google for each franchise brand + zip code combination, extracts current ratings, review counts, and competitive context, and flags locations with significant changes. Designed for franchise development teams tracking operator performance and territory opportunities.
Trigger
Cron schedule (every Sunday at 5 AM UTC)
Schedule
Runs every Sunday at 5:00 AM UTC
Workflow Steps
Load franchise location database
Read all monitored franchise brand + zip code combinations.
Query Google local data
For each location, query Scavio Google for current local pack data.
Extract operator metrics
Parse ratings, review counts, addresses, and competitive mentions.
Compare against previous week
Flag rating changes, new competitor openings, and location closures.
Update location database
Write current data to storage and generate change report.
Python Implementation
import requests
import json
from datetime import datetime
from pathlib import Path
API_KEY = "your_scavio_api_key"
def refresh_franchise_data(brands_zips: list[dict]) -> dict:
prev_path = Path("franchise_data.json")
previous = json.loads(prev_path.read_text()) if prev_path.exists() else {}
current = {}
changes = []
for entry in brands_zips:
brand = entry["brand"]
zip_code = entry["zip"]
key = f"{brand}_{zip_code}"
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": f"{brand} {zip_code}"},
timeout=15,
)
if not res.ok:
continue
organic = res.json().get("organic", [])
current[key] = {
"brand": brand,
"zip": zip_code,
"result_count": len(organic),
"top_result": organic[0].get("title", "") if organic else "",
"updated": datetime.utcnow().isoformat(),
}
prev = previous.get(key, {})
if prev.get("result_count") and current[key]["result_count"] != prev["result_count"]:
changes.append({"key": key, "prev_results": prev["result_count"], "current_results": current[key]["result_count"]})
prev_path.write_text(json.dumps(current, indent=2))
date = datetime.utcnow().strftime("%Y-%m-%d")
print(f"Franchise refresh {date}: {len(current)} locations, {len(changes)} changes")
return {"date": date, "locations": len(current), "changes": changes}
data = [
{"brand": "Subway", "zip": "75001"},
{"brand": "Subway", "zip": "75002"},
{"brand": "McDonald's", "zip": "75001"},
]
refresh_franchise_data(data)JavaScript Implementation
const API_KEY = "your_scavio_api_key";
async function refreshFranchise(brandsZips) {
const results = [];
for (const { brand, zip } of brandsZips) {
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: `${brand} ${zip}` }),
});
if (!res.ok) continue;
const organic = (await res.json()).organic ?? [];
results.push({ brand, zip, resultCount: organic.length, topResult: organic[0]?.title ?? "" });
}
console.log(`Refreshed ${results.length} franchise locations`);
return results;
}
await refreshFranchise([{ brand: "Subway", zip: "75001" }]);Platforms Used
Web search with knowledge graph, PAA, and AI overviews