local-seorank-trackingapi

Local SEO Map Rank Tracker with API

Track Google Local Pack rankings across queries and locations programmatically. Alert on ranking drops before they compound.

6 min read

Local SEO map rank tracking requires checking your Google Business Profile position across multiple search queries and locations. Manual checking does not scale past 10 locations. An API-based tracker checks hundreds of queries programmatically and alerts you when rankings drop.

Why Map Rankings Matter

Google's Local Pack (the map with 3 business listings) appears for 46% of all Google searches. If your business drops from position 1 to position 4 in the local pack, you disappear from the visible results. Unlike organic rankings that change gradually, local pack rankings can shift overnight due to review velocity, NAP inconsistencies, or competitor actions.

Building a Map Rank Tracker

Search for your target keywords, parse the local pack results, and find your business position. Run this daily across all your target queries and locations.

Python
import requests, os
from datetime import datetime

H = {"x-api-key": os.environ["SCAVIO_API_KEY"]}

def check_local_rank(business_name, query, location=None):
    """Check business position in Google Local Pack."""
    search_query = f"{query} {location}" if location else query
    r = requests.post("https://api.scavio.dev/api/v1/search",
        headers=H,
        json={"platform": "google", "query": search_query},
        timeout=10
    ).json()

    local_pack = r.get("localPack", [])
    for i, result in enumerate(local_pack):
        if business_name.lower() in result.get("title", "").lower():
            return {
                "query": search_query,
                "position": i + 1,
                "total_results": len(local_pack),
                "found": True,
                "rating": result.get("rating"),
                "reviews": result.get("reviews"),
            }
    return {
        "query": search_query,
        "position": None,
        "found": False,
    }

rank = check_local_rank("Blue Bottle Coffee", "coffee shop", "San Francisco")
if rank["found"]:
    print(f"Position {rank['position']} for '{rank['query']}'")
else:
    print(f"Not in Local Pack for '{rank['query']}")

Multi-Location Tracking

Track rankings across multiple cities or neighborhoods. Each location query returns different local pack results. A business ranking #1 in downtown may not appear at all in suburban searches.

Python
def track_all_locations(business, keywords, locations):
    """Track map rankings across all keyword-location combos."""
    results = []
    for keyword in keywords:
        for location in locations:
            rank = check_local_rank(business, keyword, location)
            rank["keyword"] = keyword
            rank["location"] = location
            rank["date"] = datetime.now().strftime("%Y-%m-%d")
            results.append(rank)
    return results

keywords = ["coffee shop", "best coffee", "coffee near me"]
locations = ["San Francisco", "Oakland", "Berkeley"]
rankings = track_all_locations("Blue Bottle Coffee", keywords, locations)

found = [r for r in rankings if r["found"]]
print(f"Found in {len(found)}/{len(rankings)} queries")
for r in found:
    print(f"  {r['keyword']} + {r['location']}: position {r['position']}")

Alert on Ranking Drops

Python
def detect_ranking_changes(current, previous):
    """Compare current rankings to previous day."""
    alerts = []
    prev_map = {
        (r["keyword"], r["location"]): r["position"]
        for r in previous if r["found"]
    }
    for r in current:
        key = (r["keyword"], r["location"])
        prev_pos = prev_map.get(key)
        if r["found"] and prev_pos:
            if r["position"] > prev_pos:
                alerts.append({
                    "type": "drop",
                    "keyword": r["keyword"],
                    "location": r["location"],
                    "from": prev_pos,
                    "to": r["position"],
                })
        elif not r["found"] and prev_pos:
            alerts.append({
                "type": "lost",
                "keyword": r["keyword"],
                "location": r["location"],
                "previous_position": prev_pos,
            })
    return alerts

Cost at Scale

100 keywords across 10 locations = 1,000 daily queries. At $0.005/credit: $5/day or $150/month. Commercial local rank trackers (BrightLocal, Whitespark) charge $30-100/month for similar coverage but with less customization. The API approach lets you build exactly the tracker you need and integrate it into your existing monitoring stack.

Competitor Tracking

Run the same queries for competitors. If a competitor appears in a local pack where you do not, that is a gap to investigate. Track competitor review counts and ratings alongside your own to understand what drives ranking changes.