Agency SEO API Rank Tracking at Predictable Cost
Track 500 keywords across 10 clients for $10/mo via SERP API instead of $52-499/mo for dedicated rank tracking tools.
Agency rank tracking via SERP API provides predictable per-keyword pricing ($0.005-0.015/check) instead of the opaque per-seat or per-project pricing of SEO platforms. An agency tracking 500 keywords across 10 clients pays $2.50-7.50/month with a SERP API versus $52-199/month for dedicated rank tracking tools like SE Ranking, AccuRanker, or Wincher.
Why agencies overpay for rank tracking
SEO platforms bundle rank tracking with keyword research, backlink analysis, and content tools. If you already have separate tools for those functions, you are paying for the bundle to get one feature. Worse, most platforms price by keyword count tiers that force you into higher plans when you add one more client.
Building predictable-cost rank tracking
import os, requests, json, csv
from datetime import datetime
SCAVIO_KEY = os.environ["SCAVIO_API_KEY"]
HEADERS = {"x-api-key": SCAVIO_KEY}
def check_rankings(client: dict) -> list:
"""Check keyword rankings for a client. Cost: 1 credit/keyword."""
results = []
for kw in client["keywords"]:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers=HEADERS,
json={"query": kw, "num_results": 20,
"include_ai_overview": True},
)
data = resp.json()
organic = data.get("organic_results", [])
# Find client position
position = None
matching_url = None
for i, r in enumerate(organic):
if client["domain"] in r.get("link", ""):
position = i + 1
matching_url = r["link"]
break
results.append({
"keyword": kw,
"position": position,
"url": matching_url,
"has_ai_overview": bool(data.get("ai_overview")),
"ai_overview_cited": (
client["domain"] in str(data.get("ai_overview", {}).get("citations", []))
if data.get("ai_overview") else False
),
"date": datetime.utcnow().strftime("%Y-%m-%d"),
})
return results
client = {
"name": "Austin Dental",
"domain": "austindental.com",
"keywords": ["dentist austin tx", "teeth whitening austin",
"dental implants austin", "emergency dentist austin"],
}
rankings = check_rankings(client)Multi-client tracking with cost control
def agency_rank_check(clients: list, frequency: str = "weekly") -> dict:
"""Check rankings for all agency clients."""
total_keywords = sum(len(c["keywords"]) for c in clients)
cost = total_keywords * 0.005
multiplier = {"daily": 30, "weekly": 4, "biweekly": 2, "monthly": 1}
monthly_cost = cost * multiplier.get(frequency, 4)
all_results = {}
for client in clients:
all_results[client["name"]] = check_rankings(client)
return {
"clients": len(clients),
"total_keywords": total_keywords,
"cost_per_check": "$" + f"{cost:.2f}",
"monthly_cost": "$" + f"{monthly_cost:.2f}",
"frequency": frequency,
"results": all_results,
}
agency_clients = [
{"name": "Client A", "domain": "clienta.com",
"keywords": ["keyword1", "keyword2"] * 25}, # 50 keywords
{"name": "Client B", "domain": "clientb.com",
"keywords": ["keyword3", "keyword4"] * 25}, # 50 keywords
]
# 10 clients x 50 keywords = 500 keywords
# Weekly: 500 x 4 = 2,000 credits/mo = $10/mo
# Compare: SE Ranking 500 keywords = $52/moHistorical tracking with CSV storage
def save_rankings(client_name: str, rankings: list):
"""Append rankings to per-client CSV for historical tracking."""
filename = f"rankings_{client_name.lower().replace(' ', '_')}.csv"
file_exists = os.path.exists(filename)
with open(filename, "a", newline="") as f:
writer = csv.DictWriter(f, fieldnames=[
"date", "keyword", "position", "url",
"has_ai_overview", "ai_overview_cited"
])
if not file_exists:
writer.writeheader()
for r in rankings:
writer.writerow(r)
def generate_rank_report(client_name: str) -> str:
"""Generate a summary report from historical data."""
filename = f"rankings_{client_name.lower().replace(' ', '_')}.csv"
with open(filename, "r") as f:
reader = csv.DictReader(f)
rows = list(reader)
latest_date = max(r["date"] for r in rows)
latest = [r for r in rows if r["date"] == latest_date]
ranked = sum(1 for r in latest if r["position"])
avg_pos = (
sum(int(r["position"]) for r in latest if r["position"])
/ max(ranked, 1)
)
return f"""Rank Report: {client_name} ({latest_date})
Keywords tracked: {len(latest)}
Keywords in top 20: {ranked}
Average position: {avg_pos:.1f}
AI Overview coverage: {sum(1 for r in latest if r['has_ai_overview'] == 'True')}/{len(latest)}
AI Overview citations: {sum(1 for r in latest if r['ai_overview_cited'] == 'True')}"""
save_rankings("Austin Dental", rankings)
print(generate_rank_report("Austin Dental"))Cost comparison at agency scale
- 10 clients, 50 keywords each, weekly checks:
- Scavio: 2,000 credits/mo = $10/mo
- SE Ranking: $52/mo (500 keywords plan)
- AccuRanker: $129/mo (1,000 keywords)
- Wincher: $49/mo (500 keywords)
- Semrush: $499.95/mo (Business, includes rank tracking)
What you get that rank trackers miss
SERP API rank checks include AI Overview status, People Also Ask questions, featured snippet data, and local pack positions -- all in the same query. Dedicated rank trackers are adding AI Overview tracking as a premium feature. With SERP API, it is included in every check at no extra cost.
Key takeaway
Agency rank tracking is a commodity. The data is identical regardless of provider -- it is Google's ranking for a keyword. Paying $50-500/month for a dashboard around that data makes sense only if you need the UI. If you have technical capacity to run a script and read a CSV, SERP API rank tracking costs $10/month for 10 clients.