# Google Maps Local SEO Grid Scraper (`rainminer/google-maps-local-seo-grid-scraper`) Actor

Local SEO geo-grid for Google Maps: scan a keyword from many GPS points around your center coordinate and get ranked businesses plus Place IDs per cell. Track your GBP rank block by block, export heatmap SVG, and power agency reports via API—without a separate Maps SERP API.

- **URL**: https://apify.com/rainminer/google-maps-local-seo-grid-scraper.md
- **Developed by:** [rainminer](https://apify.com/rainminer) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.49 / 1,000 grid points

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Maps Local SEO Grid Scraper

A **local SEO grid** (geo-grid) shows how your **Google Business Profile** ranks on Maps from many nearby GPS points—not one city-center search. Rankings change block by block with searcher proximity. This Actor runs the full grid for you and returns **ranked businesses and Place IDs** at every cell, plus an optional **heatmap SVG** for client reports.

[![Local SEO grid heatmap on Google Maps](https://api.apify.com/v2/key-value-stores/vdPXKRB5smkRYhtEV/records/google-maps-local-seo-grid-scraper-banner.jpg)](https://apify.com/rainminer/google-maps-local-seo-grid-scraper)

***

### What can this Actor do?

- Run **5×5, 7×7, or custom grids** around any lat/lng with configurable **spacing in meters**
- Fetch **keyword rankings** at each pin (`plumber`, `dentist near me`, `personal injury lawyer`, …)
- Export **Google Place IDs**, ratings, addresses, and Maps URLs for every listing
- **Track your business** with `trackPlaceId` or `trackBusinessName` → `trackedRank` per cell
- Output **GRID\_HEATMAP\_SVG** (color-coded pins on a map) and **GRID\_SUMMARY** JSON for dashboards
- Scale via **Apify API**, schedules, and webhooks—no separate SERP API subscription required

***

### Use cases

1. **Agency geo-grid reports** — deliver heatmaps that prove local visibility before/after SEO work
2. **GBP rank tracking** — see where you rank in the top 3 vs page two across a neighborhood
3. **Competitor mapping** — list who owns each cell for a high-value keyword
4. **Multi-location brands** — compare grids around each store or franchise
5. **Citation & review campaigns** — target weak grid cells where you rank 11+
6. **Sales demos** — show prospects block-by-block visibility vs a single “city rank”
7. **API backends** — replace custom grid runners + paid Maps SERP vendors with one Actor
8. **White-label tools** — pull dataset + SVG into your own reporting UI
9. **Scheduled monitoring** — monthly runs to catch ranking drift after Google updates
10. **Hyperlocal content planning** — find zones where you are invisible and need geo pages

***

### Key features

- **Grid geometry** — `gridSize`, `spacingMeters`, auto **zoom** from span (same idea as agency geo-grid tools)
- **Place IDs** — `ChIJ…` on listings when Google exposes them
- **Parallel scans** — `concurrency` with automatic retry on failed cells
- **Dataset + KV** — one row per grid cell; full run in `GRID_SUMMARY` and `GRID_HEATMAP_SVG`

***

### Who is it for?

- **Local SEO agencies** delivering geo-grid reports to clients
- **Multi-location brands** comparing visibility around each store
- **Developers** building rank trackers without maintaining Maps scrapers

***

### Input

| Field | Description |
| --- | --- |
| `keyword` | Maps search query (required) |
| `latitude`, `longitude` | Grid center (required) |
| `gridSize` | Rows/columns (default **5**, 3–15) |
| `spacingMeters` | Distance between pins (default **500**) |
| `zoom` | Optional; auto-derived from grid span if omitted |
| `maxItems` | Listings per point (default **20**, max **120**) |
| `trackPlaceId` | Your `ChIJ…` Place ID for per-cell rank |
| `trackBusinessName` | Name fallback when Place ID is missing |
| `concurrency` | Parallel grid points (default **5**) |
| `language` | UI language (default `en`) |
| `proxyConfiguration` | Proxies if needed (default: no Apify Proxy) |

#### Example

```json
{
  "keyword": "plumber",
  "latitude": 42.6574441,
  "longitude": 23.3498259,
  "gridSize": 5,
  "spacingMeters": 500,
  "maxItems": 20,
  "trackPlaceId": "ChIJGQJ9BlG0N0oRGujIOSt2C64",
  "concurrency": 5
}
```

***

### Output

#### Dataset (one row per grid cell)

Each item includes `businesses[]` with `rank`, `title`, `placeId`, `rating`, `reviewsCount`, `address`, and `url`.

#### Key-value store

| Key | Contents |
| --- | --- |
| `GRID_SUMMARY` | Full grid, aggregates (`avgTrackedRank`, `top3PointCount`) |
| `GRID_HEATMAP_SVG` | Map heatmap (set tracking fields for meaningful colors) |

***

### Tips

- Start with **3×3** and low `maxItems` for testing; scale on Apify Cloud.
- Enable **Apify Proxy** if Google blocks datacenter IPs in your region.
- Set **`trackPlaceId`** so `GRID_HEATMAP_SVG` shows green/teal/amber ranks instead of `–`.

***

### How much does it cost?

Pricing is **pay-per-event**: one **grid point** charge per cell that returns listings, plus a small **Actor start** fee. Run the Actor from Apify Console to see current tier prices. Platform usage (compute/proxy) is included in typical PPE runs at our listed grid-point rates—check your plan on the Store page.

***

### Image Credit

Map tiles in run heatmaps and the banner: [© OpenStreetMap contributors](https://www.openstreetmap.org/copyright) (ODbL).

# Actor input Schema

## `keyword` (type: `string`):

Google Maps search query (e.g. plumber near me, pizza delivery, personal injury lawyer).

## `latitude` (type: `number`):

Latitude of the grid center (your business or neighborhood anchor).

## `longitude` (type: `number`):

Longitude of the grid center.

## `gridSize` (type: `integer`):

Number of rows and columns (e.g. 5 = 5×5 = 25 search points).

## `spacingMeters` (type: `integer`):

Distance between adjacent grid points in meters.

## `zoom` (type: `integer`):

Override automatic zoom derived from grid size and spacing. Leave empty to auto-calculate.

## `maxItems` (type: `integer`):

Maximum ranked businesses returned for each coordinate (up to 120).

## `trackPlaceId` (type: `string`):

Optional Google Place ID (ChIJ…) of your business to compute trackedRank on each grid cell.

## `trackBusinessName` (type: `string`):

Fallback name match when Place ID is missing or not found in results.

## `concurrency` (type: `integer`):

How many grid points to query in parallel.

## `language` (type: `string`):

Maps UI language code (e.g. en, de).

## `proxyConfiguration` (type: `object`):

Use proxies if Google blocks datacenter IPs in your region.

## Actor input object example

```json
{
  "keyword": "plumber",
  "latitude": 42.6574441,
  "longitude": 23.3498259,
  "gridSize": 5,
  "spacingMeters": 500,
  "maxItems": 20,
  "concurrency": 5,
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `heatmap` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keyword": "plumber",
    "latitude": 42.6574441,
    "longitude": 23.3498259
};

// Run the Actor and wait for it to finish
const run = await client.actor("rainminer/google-maps-local-seo-grid-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keyword": "plumber",
    "latitude": 42.6574441,
    "longitude": 23.3498259,
}

# Run the Actor and wait for it to finish
run = client.actor("rainminer/google-maps-local-seo-grid-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keyword": "plumber",
  "latitude": 42.6574441,
  "longitude": 23.3498259
}' |
apify call rainminer/google-maps-local-seo-grid-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,rainminer/google-maps-local-seo-grid-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/sZ21oVDXJ0TJ4J6Fw/builds/XUAU06LpmB0be7pFK/openapi.json
