Geogrid Rank Scan
Map Google Maps rankings across a geographic grid centered on a location. Returns a rank matrix showing where a business ranks from each grid point, plus ARP, ATRP and SoLV scores. 5x5 by default; 3x3, 7x7 and 9x9 on request, at 2 credits a point.
When to use this
You want to see where your business ranks on Google Maps from different parts of your city — not just from one location, but from a grid of 9 to 81 points around your area. It's like checking your ranking from every neighborhood at once. Shows you exactly which parts of town you dominate and where you're invisible.
/v1/geogrid/scanParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| business | string | No | Business name to track, matched against listing titles. Required unless place_id is given. |
| place_id | string | No | Google place_id for the business. Matches exactly one listing, so it is the reliable choice; when given, business is not used for matching. |
| location | string | No | Center point — city/state or lat,lng (e.g. "Brooklyn, NY"). Required unless center is given. |
| center | object | No | Exact center as {"lat": 40.6892, "lng": -73.9857}. Overrides location. Use the business's own coordinates when tracking it over time, so the grid never moves. |
| keyword | string | Yes | Search keyword (e.g. "pizza") |
| grid_size | string | No | "3x3", "5x5", "7x7" or "9x9". Default: "5x5". Larger grids cost more: 2 credits per point. |
| radius_miles | number | No | Distance from the center to the edge of the grid, in miles. Default: 3 |
| zoom | string | integer | No | "auto" (14) or a Maps zoom from 3 to 21. Default: "auto". Fix it only to match an existing series. |
| include_listings | boolean | No | Also return the top 20 organic listings at every point, for competitor analysis. Same price; a 9x9 response runs to about half a megabyte. Default: false |
| callback_url | string | No | Public https URL to POST the finished scan to, instead of polling. |
Example Request
curl -X POST https://api.localseodata.com/v1/geogrid/scan \
-H "Authorization: Bearer sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"business": "Joe'\''s Pizza",
"location": "Brooklyn, NY",
"keyword": "pizza",
"grid_size": "5x5",
"radius_miles": 3
}'Example Response
// The submit. Credits are charged here.
{
"status": "success",
"credits_used": 50,
"data": {
"job_id": "geo_V1StGXR8Z5",
"status": "pending",
"estimated_seconds": 25,
"poll_url": "/v1/geogrid/status/geo_V1StGXR8Z5"
}
}
// GET the poll_url until status is "complete" or "failed". Polling is free.
{
"status": "success",
"credits_used": 0,
"data": {
"job_id": "geo_V1StGXR8Z5",
"status": "complete",
"grid_size": "5x5",
"radius_miles": 3,
"center": { "lat": 40.6892, "lng": -73.9857 },
"keyword": "pizza",
"business_name": "Joe's Pizza",
"zoom": 14,
"zoom_mode": "auto",
"average_rank": 3.2,
"atrp": 6.1,
"solv": 48,
"found_in": 21,
"failed_points": 0,
"total_points": 25,
"credits_refunded": 0,
"grid": [
[4, 2, 1, 3, 5],
[3, 1, 1, 2, 4]
],
"grid_points": [
{ "row": 0, "col": 0, "lat": 40.710, "lng": -74.006, "rank": 4, "status": "ok" },
{ "row": 0, "col": 1, "lat": 40.710, "lng": -73.996, "rank": 2, "status": "ok" }
],
"cached": false,
"completed_at": "2026-09-20T21:34:25.447Z"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
| job_id | string | The scan's id. The submit returns it; the poll URL carries it |
| status | string | "pending" or "running" while the scan is going, then "complete" or "failed" |
| poll_url | string | Submit only. GET this path to collect the scan. Polling is free and does not expire |
| estimated_seconds | integer | Submit only. Usual time to finish |
| progress | integer | While running: 0, then total once complete |
| average_rank | float | ARP: average rank across the points where the business was found (lower is better) |
| atrp | float | ATRP: average rank across every point that answered, counting not found as 21 |
| solv | float | SoLV: percentage of answered points where the business ranks in the top 3 |
| found_in | integer | How many grid points found the business in the top 20 |
| failed_points | integer | Points that could not be checked. They are left out of the scores and refunded |
| credits_refunded | integer | Credits returned for failed points: 2 each |
| total_points | integer | Points in the grid: 9, 25, 49 or 81 |
| grid | array[][] | Rank at each point as a plain 2D number matrix, row by row. 0 means not found, or a failed point |
| grid_points | array | The same points as objects carrying row, col, lat, lng, rank and status ("ok" or "error"). With include_listings, each also carries results: the top 20 organic listings (place_id, cid, title, category, rating, reviews_count, address, lat, lng) |
| grid_size | string | Grid dimensions ("3x3", "5x5", "7x7", "9x9") |
| center | object | Center point lat/lng of the grid |
| business_name | string | The business's name as Google Maps lists it, or null if it was not found |
| zoom | integer | The Maps zoom each point searched at |
| cached | boolean | Whether the scan was served from a previous run. A cached scan carries no job_id |
| error | string | On status "failed" only: why the scan died. A failed scan is refunded |
Notes
- This endpoint submits and returns immediately. It hands back a job_id and a poll_url, not a grid — GET the poll_url until status is "complete". Polling is free and does not expire.
- Credits are charged at submit. A scan that fails is refunded in full, and so is any single point that could not be checked. Polling costs nothing, so the poll response reads credits_used: 0.
- An identical submit inside the replay window returns the scan already running rather than starting a second one, and comes back with deduplicated: true at 0 credits.
- The default grid is 5x5 = 25 points (50 credits). Set grid_size for a different grid; every size costs 2 credits a point: 3x3 = 9 points (18 credits), 7x7 = 49 points (98 credits), 9x9 = 81 points (162 credits).
- Ranks count organic Google Maps listings only. Sponsored listings are skipped, so a business is never ranked on its own ad.
- Rankings hold across the whole grid, outer points included: a business is not lost at the edges of a wide grid.
- Rank of 0 means the business was not in the top 20 at that grid point.
- Combine with Claude via MCP for narrative interpretation of grid results.
- Store results over time to track geographic ranking trends.