Tutorial

How to Track Google Maps Rank by Location

Monitor your Google Maps ranking across geographic grid points using the Scavio API. Build heatmaps of local search visibility. Python tutorial.

Track your Google Maps ranking across a geographic grid by running location-scoped search queries at multiple grid points and recording your business position in the results for each point. Local SEO depends on rank in the Google Maps pack, which varies significantly by searcher location. A rank grid reveals blind spots where your business drops out of the top results and identifies the geographic radius of your visibility. This tutorial builds a grid scanner using the Scavio API.

Prerequisites

  • Python 3.8+ installed
  • requests library installed
  • A Scavio API key from scavio.dev
  • Your business name and target service area coordinates

Walkthrough

Step 1: Define the geographic grid

Set up a grid of latitude/longitude points centered on your business location.

Python
import os, requests, json

API_KEY = os.environ['SCAVIO_API_KEY']

BUSINESS_NAME = 'Your Business Name'
CENTER_LAT = 30.2672  # Austin, TX example
CENTER_LNG = -97.7431
GRID_SIZE = 5  # 5x5 grid
GRID_STEP = 0.02  # ~1.4 miles per step

def generate_grid(center_lat: float, center_lng: float, size: int, step: float) -> list:
    points = []
    half = size // 2
    for i in range(-half, half + 1):
        for j in range(-half, half + 1):
            lat = round(center_lat + i * step, 4)
            lng = round(center_lng + j * step, 4)
            points.append({'lat': lat, 'lng': lng})
    return points

grid = generate_grid(CENTER_LAT, CENTER_LNG, GRID_SIZE, GRID_STEP)
print(f'Grid: {len(grid)} points ({GRID_SIZE}x{GRID_SIZE})')

Step 2: Query each grid point

Run a local search query at each grid point and find your business position in the results.

Python
def search_at_location(query: str, lat: float, lng: float) -> list:
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers={'x-api-key': API_KEY},
        json={'platform': 'google', 'query': f'{query} near {lat},{lng}'}, timeout=15)
    return resp.json().get('organic_results', [])

def find_rank(results: list, business_name: str) -> int:
    name_lower = business_name.lower()
    for i, r in enumerate(results):
        title = r.get('title', '').lower()
        if name_lower in title:
            return i + 1
    return 0  # Not found

results = search_at_location('plumber', CENTER_LAT, CENTER_LNG)
rank = find_rank(results, BUSINESS_NAME)
print(f'Rank at center: {rank if rank else "not found"}')

Step 3: Record positions across the grid

Scan all grid points and record the rank at each location.

Python
def scan_grid(query: str, business: str, grid: list) -> list:
    scan_results = []
    for i, point in enumerate(grid):
        results = search_at_location(query, point['lat'], point['lng'])
        rank = find_rank(results, business)
        scan_results.append({
            'lat': point['lat'],
            'lng': point['lng'],
            'rank': rank,
            'total_results': len(results),
        })
        if (i + 1) % 5 == 0:
            print(f'Scanned {i + 1}/{len(grid)} points')
    return scan_results

# For demo, scan a small subset
small_grid = grid[:4]
results = scan_grid('plumber', BUSINESS_NAME, small_grid)
for r in results:
    status = f'Rank {r["rank"]}' if r['rank'] else 'Not found'
    print(f'({r["lat"]}, {r["lng"]}): {status}')

Step 4: Compute rank changes over time

Compare today's scan with a previous scan to identify locations where rank improved or dropped.

Python
def compare_scans(current: list, previous: list) -> list:
    prev_map = {(p['lat'], p['lng']): p['rank'] for p in previous}
    changes = []
    for c in current:
        key = (c['lat'], c['lng'])
        prev_rank = prev_map.get(key, 0)
        curr_rank = c['rank']
        if prev_rank and curr_rank:
            change = prev_rank - curr_rank  # positive = improved
        elif curr_rank and not prev_rank:
            change = 'NEW'
        elif prev_rank and not curr_rank:
            change = 'LOST'
        else:
            change = 0
        changes.append({**c, 'prev_rank': prev_rank, 'change': change})
    return changes

# Example:
prev = [{'lat': 30.27, 'lng': -97.74, 'rank': 5}]
curr = [{'lat': 30.27, 'lng': -97.74, 'rank': 3, 'total_results': 10}]
for c in compare_scans(curr, prev):
    print(f'({c["lat"]}, {c["lng"]}): {c["prev_rank"]} -> {c["rank"]} (change: {c["change"]})')

Step 5: Visualize the rank grid

Generate a text-based heatmap of your rank across the grid for quick analysis.

Python
def print_heatmap(scan_results: list, grid_size: int):
    print(f'\nRank Heatmap ({grid_size}x{grid_size}):')
    print('1-3=top, 4-7=mid, 8+=low, .=not found\n')
    for i in range(grid_size):
        row = []
        for j in range(grid_size):
            idx = i * grid_size + j
            if idx < len(scan_results):
                rank = scan_results[idx]['rank']
                if rank == 0:
                    row.append('.')
                elif rank <= 3:
                    row.append(str(rank))
                elif rank <= 7:
                    row.append('m')
                else:
                    row.append('L')
            else:
                row.append(' ')
        print(' '.join(row))

# Demo with mock data
mock_scan = [{'rank': r} for r in [1,2,3,0,5, 2,1,4,3,6, 0,3,1,2,0, 5,4,3,2,7, 0,6,5,4,0]]
print_heatmap(mock_scan, 5)

Python Example

Python
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}

def rank_at(query, lat, lng, business):
    data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'platform': 'google', 'query': f'{query} near {lat},{lng}'}).json()
    for i, r in enumerate(data.get('organic_results', [])):
        if business.lower() in r.get('title', '').lower():
            return i + 1
    return 0

print(f'Rank: {rank_at("plumber", 30.2672, -97.7431, "Your Business")}')

JavaScript Example

JavaScript
const H = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
async function rankAt(query, lat, lng, business) {
  const r = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: H,
    body: JSON.stringify({platform: 'google', query: `${query} near ${lat},${lng}`})
  });
  const results = (await r.json()).organic_results || [];
  const idx = results.findIndex(r => r.title?.toLowerCase().includes(business.toLowerCase()));
  return idx >= 0 ? idx + 1 : 0;
}
rankAt('plumber', 30.2672, -97.7431, 'Your Business').then(console.log);

Expected Output

JSON
A geographic grid scan that shows your Google Maps ranking at each location point, with change tracking over time and a text-based heatmap visualization.

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.8+ installed. requests library installed. A Scavio API key from scavio.dev. Your business name and target service area coordinates. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Monitor your Google Maps ranking across geographic grid points using the Scavio API. Build heatmaps of local search visibility. Python tutorial.