# Google Maps Rank Tracker: Geo-Grid Local SEO (`plainrows/google-maps-rank-tracker`) Actor

See where a business ranks on Google Maps at every point of a grid around it (3x3 to 9x9) for up to 5 keywords: rank per point, top 3 competitors, average rank and share of local voice. Pay per grid point, no subscription.

- **URL**: https://apify.com/plainrows/google-maps-rank-tracker.md
- **Developed by:** [PlainRows](https://apify.com/plainrows) (community)
- **Categories:** Marketing, SEO tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 grid point checkeds

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 Rank Tracker: Geo-Grid Local SEO

See **where a business ranks on Google Maps at every point of a grid around it**, for up to 5 keywords. A pay-per-point alternative to Local Falcon, BrightLocal Local Search Grid or Whitespark grids: **no subscription, no credits that expire**, a 5x5 grid for one keyword costs $0.25 plus $0.002 per run (less on higher Apify plans).

For each point of a 3x3, 5x5, 7x7 or 9x9 grid (0.1 to 20 km apart), the Actor searches Google Maps **from that point** and returns the business's rank there and the **top 3 places** competing for it. Then one free summary row per keyword: **average rank, share of local voice (% of points in the top 3), points where it ranks, the competitor ranked first most often** and the rank grid itself, ready for a heatmap.

It calls a commercial data API instead of driving a browser: no proxies, no CAPTCHAs, no Google account. Only business data is returned (names, IDs, ratings of places), no personal data.

### Typical uses

- **Local SEO agencies**: monthly geo-grid reports for each client, at cost per point, scheduled and sent to a spreadsheet or a dashboard.
- **Business owners**: see the streets where you disappear from the map pack, and who takes your place there.
- **Before / after**: measure the effect of a Google Business Profile change, new reviews or a new category on the same grid.
- **Competitor research**: the competitor ranked first at the most points, with its rating and review count.
- **AI agents (MCP)**: "how visible is this dentist in its neighbourhood?" answered with numbers.

### Input

```json
{
  "business": "Monmouth Coffee Company, Borough, London",
  "keywords": ["coffee shop", "espresso"],
  "gridSize": "5",
  "gridSpacingKm": "1",
  "country": "GB",
  "maxRank": 20
}
```

| Field | Description |
|---|---|
| `business` | Name and city, Google Maps link, place ID (`ChIJ...`) or CID. Accepts the `placeId`, `cid` and `googleMapsUrl` of [Google Maps Businesses](https://apify.com/plainrows/google-maps-businesses). Found once at the start (free); if it is not found, the run stops and nothing is charged. With a name, the first of the top 3 results whose name matches the name you typed (before the first comma) is used; if none matches, the run stops for free and lists the candidates. A place ID is the surest. |
| `keywords` | 1 to 5 keywords, without the city: each search is made from the grid point. |
| `gridSize` | 3, 5 (default), 7 or 9 points per side. |
| `gridSpacingKm` | Distance between neighbouring points (default 1 km). |
| `centerLat`, `centerLng` | Optional grid centre (default: the business location). |
| `country`, `languageCode` | Country of the business and search language (default: the country's main language). |
| `maxRank` | How many results to read at each point (default 20, up to 100). The price per grid point does not depend on it. |
| `zoom` | Map zoom at each point (default 15). Keep it constant to compare runs. |

### What you get

One row per point and keyword (`type: "grid-point"`, billed):

| Field | Description |
|---|---|
| `keyword`, `row`, `col` | Keyword; grid position (row 0 = north, col 0 = west) |
| `latitude`, `longitude`, `distanceKm` | The point and its distance from the centre |
| `rank` | Position of the business on Google Maps at this point (1 = first), `null` when not in the first `maxRank` results |
| `inTop3` | Rank 1 to 3 (the local pack) |
| `top3` | The first 3 places at this point: rank, name, place ID, CID, rating, number of reviews, `isYourBusiness` |
| `resultsChecked` | Results read at this point |
| `businessName`, `businessPlaceId`, `businessCid` | The tracked business |
| `observedAt` | When the search was made (UTC) |

Then one row per keyword (`type: "keyword-summary"`, free): `pointsTotal`, `pointsChecked` (points searched and delivered), `pointsFound`, `pointsInTop3`, `averageRankWhereFound`, `averageRankAllPoints` (not ranked counted as `maxRank + 1`), `shareOfLocalVoiceTop3Pct`, `foundPct`, `topCompetitor` and `rankGrid` (ranks laid out as the grid, north row first).

The business is matched by its **place ID or CID, never by name**, so a branch of the same chain is not mistaken for it. Sponsored pins are not counted in the rank.

### Pricing

Pay per event:

- **Grid point**: $0.01 (free Apify plan), $0.008 (Bronze), $0.007 (Silver), $0.006 (Gold), per point and keyword where Google Maps returned places, whether the business ranks among them or not.
- Actor start: $0.002 per run.

Free: the business lookup, the summary rows, a business not found (or a name that matches none of the first results: the run stops and lists them so you can pass the right place ID), points where Google Maps returned no place, and any point where it did not answer or answered something unreadable.

Grid points per keyword (add $0.002 per run for the Actor start):

| Grid | Points per keyword | Free plan | Gold |
|---|---|---|---|
| 3x3 | 9 | $0.09 | $0.054 |
| 5x5 | 25 | $0.25 | $0.15 |
| 7x7 | 49 | $0.49 | $0.294 |
| 9x9 | 81 | $0.81 | $0.486 |

The run's maximum cost is respected. Before any search, the Actor keeps only the keywords whose full grid fits in it (skipped keywords are skipped whole, the budget never cuts a grid in half), and a maximum cost below one grid plus the $0.002 start stops the run before any search: for one keyword, set at least $0.252 for a 5x5 on the free plan or $0.056 for a 3x3 on Gold (exactly $0.25 or $0.054 is refused).

Points are searched from the centre of the grid outwards. A run can still end with part of a grid: when the data service fails or answers in a form the Actor cannot read, or when searches with no place at all cost more than the points the run charged (about 6 such searches before the first point with places: a grid that reaches out to sea, for example), the run stops. Points not searched are not charged; the run's warnings give their number and the summary shows `pointsChecked` below `pointsTotal`. On the free Apify plan, runs are limited to 1 keyword and a 3x3 grid.

### Good to know

- Rankings depend on the searcher's location, time and Google's tests: two runs a few minutes apart can differ by a place or two. Compare averages, not single points.
- A point where Google Maps returns no place at all for the keyword gets a free row (`rank: null`, `billed: false`, with a `note`).
- With 5 keywords on a 9x9 grid (405 searches) a run takes a few minutes.

### Related Actors

- [Google Maps Businesses](https://apify.com/plainrows/google-maps-businesses): all places for a search, with contacts.
- [Google Maps Reviews Scraper](https://apify.com/plainrows/google-maps-reviews): reviews of the business and its competitors.

### More PlainRows tools

Same pay-per-result pricing, same clean JSON, built to chain together in n8n, Make, Zapier or AI agents.

- **SEO and keywords:** [Keyword Search Volume, CPC & Difficulty](https://apify.com/plainrows/keyword-search-volume) · [Keyword Ideas Generator](https://apify.com/plainrows/keyword-ideas-generator) · [Google Autocomplete & People Also Ask](https://apify.com/plainrows/google-autocomplete-questions) · [Google Trends Explorer](https://apify.com/plainrows/google-trends-explorer) · [Website Organic Traffic & Top Keywords](https://apify.com/plainrows/domain-seo-overview) · [Bulk Domain Authority Checker](https://apify.com/plainrows/domain-authority-checker) · [Backlink Checker](https://apify.com/plainrows/backlink-checker) · [Broken Link Checker](https://apify.com/plainrows/broken-link-checker) · [AI Search Visibility Tracker (ChatGPT, Gemini, AI Mode)](https://apify.com/plainrows/ai-search-brand-visibility)
- **Leads and companies:** [Google Maps Scraper](https://apify.com/plainrows/google-maps-businesses) · [Website Technology Checker](https://apify.com/plainrows/website-tech-stack) · [ATS Jobs Scraper (Workday, Greenhouse, Lever, Ashby)](https://apify.com/plainrows/ats-job-postings) · [Google Jobs Scraper](https://apify.com/plainrows/google-jobs-scraper) · [Google Ads Scraper (Transparency Center)](https://apify.com/plainrows/google-ads-transparency) · [Company Registry Lookup (SIRENE, LEI, Brreg)](https://apify.com/plainrows/company-registry-lookup) · [Public Tenders Search (EU TED & UK)](https://apify.com/plainrows/public-tenders-search)
- **E-commerce and travel:** [Amazon Product Search Scraper](https://apify.com/plainrows/amazon-product-search) · [Google Shopping Prices Scraper](https://apify.com/plainrows/google-shopping-prices) · [Google Hotels Prices Scraper](https://apify.com/plainrows/google-hotels-prices) · [Tripadvisor Reviews Scraper](https://apify.com/plainrows/tripadvisor-reviews)
- **Content and media:** [Google News Scraper](https://apify.com/plainrows/google-news-scraper) · [YouTube Search Scraper](https://apify.com/plainrows/youtube-search-scraper) · [YouTube Comments Scraper](https://apify.com/plainrows/youtube-comments-scraper) · [Google Images Scraper](https://apify.com/plainrows/google-images-scraper) · [Website Screenshot API](https://apify.com/plainrows/website-screenshot) · [Google Maps Reviews Scraper](https://apify.com/plainrows/google-maps-reviews) · [App Store & Google Play Reviews Scraper](https://apify.com/plainrows/app-reviews-scraper)

**Compared with other APIs:** [Local Falcon alternative without a subscription](https://nadaho.github.io/plainrows/local-falcon-alternative-pay-per-point/)

# Actor input Schema

## `business` (type: `string`):

The business to track: its name and city ("Monmouth Coffee, Borough, London"), its Google Maps link, place ID ("ChIJ...") or CID. One business per run. If it cannot be found, the run stops and no grid point is charged.

## `keywords` (type: `array`):

What customers type in Google Maps, 1 to 5 keywords: "coffee shop", "espresso bar". Do not add the city: each search is made from the grid point itself.

## `gridSize` (type: `string`):

Points per side: 3 (9 points), 5 (25), 7 (49) or 9 (81). Each point is one Google Maps search per keyword.

## `gridSpacingKm` (type: `string`):

Distance between two neighbouring points, from 0.1 to 20 km. 0.5-1 km for a city centre, 2-5 km for a suburb or a service area.

## `country` (type: `string`):

Country of the business (sets the default language and the search used to find the business).

## `languageCode` (type: `string`):

Two-letter language code, e.g. "en" or "fr". Leave empty to use the country's main language (for example German for Switzerland, French for Belgium).

## `maxRank` (type: `integer`):

How many Google Maps results to check at each point. A business beyond this rank is reported as not ranked (rank null). The price per grid point does not depend on this value.

## `centerLat` (type: `string`):

Centre the grid somewhere else than the business, e.g. "51.5074". Set both latitude and longitude.

## `centerLng` (type: `string`):

e.g. "-0.1278".

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

Zoom of the Google Maps view at each point (15 = a few streets around the searcher, as on a phone). Keep the same value between runs to compare them.

## Actor input object example

```json
{
  "business": "Monmouth Coffee Company, Borough, London",
  "keywords": [
    "coffee shop"
  ],
  "gridSize": "5",
  "gridSpacingKm": "1",
  "country": "GB",
  "maxRank": 20,
  "zoom": 15
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (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 = {
    "business": "Monmouth Coffee Company, Borough, London",
    "keywords": [
        "coffee shop"
    ],
    "gridSize": "5",
    "country": "GB"
};

// Run the Actor and wait for it to finish
const run = await client.actor("plainrows/google-maps-rank-tracker").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 = {
    "business": "Monmouth Coffee Company, Borough, London",
    "keywords": ["coffee shop"],
    "gridSize": "5",
    "country": "GB",
}

# Run the Actor and wait for it to finish
run = client.actor("plainrows/google-maps-rank-tracker").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 '{
  "business": "Monmouth Coffee Company, Borough, London",
  "keywords": [
    "coffee shop"
  ],
  "gridSize": "5",
  "country": "GB"
}' |
apify call plainrows/google-maps-rank-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plainrows/google-maps-rank-tracker"
        }
    }
}
```

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/VMPWBpZF8CgUgtRrd/builds/Ladv0Hfq96nu6zz63/openapi.json
