# Google Maps Search Scraper (`romy/google-maps-search-scraper`) Actor

Get place search results from Google Maps. Talks directly to Google Maps' internal mobile API, no login needed. Split from the mature, published google-maps-all-in-one-api for a focused, single-purpose workflow.

- **URL**: https://apify.com/romy/google-maps-search-scraper.md
- **Developed by:** [Romy](https://apify.com/romy) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.60 / 1,000 result chargeds

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

### What does Google Maps Search Scraper do?

**Google Maps Search Scraper** searches Google Maps for places near a location, and/or gets search-as-you-type autocomplete suggestions — pass in an array of search queries and/or an array of suggestion queries, and every result item is pushed to the dataset as its own row, tagged with which query it came from.

### Why use Google Maps Search Scraper?

It talks directly to the same internal gRPC API the official Google Maps Android app uses (`mobilemaps-pa-gz.googleapis.com`), reverse-engineered by live capture against a real device — real protobuf request/response schemas, real headers, no API key of your own needed. No account, no browser automation, no scraping setup.

This is the search-and-autocomplete slice of [Google Maps All-in-One API](https://apify.com/romy/google-maps-all-in-one-api), split out as its own focused, batch-run Actor (input in, dataset out) instead of that Actor's always-on Standby REST API.

- **Real place data** — name, coordinates, address, rating, review count, phone, website, hours, category, and more, straight from Google's servers
- **Autocomplete** — the same search-as-you-type predictions the app shows while typing, with resolved place IDs and coordinates where available
- **Batch-friendly** — run many searches and/or suggestion lookups in a single Actor run
- **Use cases:** local business lead generation, market/competitor research, place-data enrichment, address/POI autocomplete for your own app

### How it connects to the parent

This Actor ports the `search()` and `suggest()` logic (and the shared gRPC/protobuf plumbing) verbatim from [Google Maps All-in-One API](https://apify.com/romy/google-maps-all-in-one-api), which exposes those two endpoints plus place detail, reviews, directions, live traffic, reverse geocoding, photos, shareable links, EV reference data, and a business category catalog as an always-on REST API. If you need those other endpoints, or prefer calling a REST API on demand instead of running a batch Actor, use the parent.

### Input

At least one of `searches` or `suggestions` must be a non-empty array.

**`searches[]`**

| Field        | Type    | Required | Description                                                                             |
| ------------ | ------- | -------- | --------------------------------------------------------------------------------------- |
| `query`      | string  | yes      | Search text, e.g. `coffee`, `pizza restaurant`.                                         |
| `lat`        | number  | yes      | Latitude to search near.                                                                |
| `lng`        | number  | yes      | Longitude to search near.                                                               |
| `maxResults` | integer | no       | Max results to return. Default `20`.                                                    |
| `radiusKm`   | number  | no       | Search radius in kilometers. Default `50`.                                              |
| `language`   | string  | no       | BCP-47 language code, e.g. `en-US`. Default `en-US`.                                    |
| `openNow`    | boolean | no       | Only places currently open (applied client-side, see Known limitations).                |
| `minRating`  | number  | no       | Only places with rating >= this value (applied client-side).                            |
| `category`   | string  | no       | Case-insensitive substring match against place categories, e.g. `coffee` (client-side). |

**`suggestions[]`**

| Field      | Type   | Required | Description                                                                                                 |
| ---------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------- |
| `query`    | string | yes      | Partial text as the user would type it, e.g. `White Hous`.                                                  |
| `lat`      | number | no       | Biases suggestions toward this location. Default `0`.                                                       |
| `lng`      | number | no       | Biases suggestions toward this location. Default `0`.                                                       |
| `radiusKm` | number | no       | Declared for parity with the upstream API; not currently wired into the request (mirrors the parent Actor). |
| `language` | string | no       | BCP-47 language code, e.g. `en-US`. Default `en-US`.                                                        |

Example:

```json
{
    "searches": [{ "query": "coffee", "lat": 38.8977, "lng": -77.0365, "maxResults": 5 }],
    "suggestions": [{ "query": "White House", "lat": 38.9, "lng": -77.03 }]
}
```

### Output

One dataset row per result item, tagged with `queryType` and the originating `query`.

Search result row:

```json
{
    "queryType": "search",
    "query": "coffee",
    "lat": 38.8977,
    "lng": -77.0365,
    "placeId": "0x89b7b7bcdecbb1df:0x715969d86d0b76bf",
    "name": "Compass Coffee",
    "fullAddress": "1535 7th St NW, Washington, DC 20001, United States",
    "rating": 4.6,
    "reviewCount": 812,
    "categories": ["Coffee shop"]
}
```

Suggestion row:

```json
{
    "queryType": "suggestion",
    "query": "White House",
    "fullText": "White House, Pennsylvania Avenue Northwest, Washington, DC, USA",
    "primaryText": "White House",
    "placeId": "0x89b7b7bcdecbb1df:0x715969d86d0b76bf",
    "lat": 38.8976763,
    "lng": -77.0365298
}
```

### Known limitations

- **`searches` results can be biased toward the US (Ashburn/Sterling, VA) regardless of the `lat`/`lng` you pass.** Confirmed on the parent Actor via a live A/B test: the real Google Maps Android app, run from a phone physically in Jakarta, correctly returns Jakarta-area results for the same query — but the identical request sent from Apify's infrastructure returns US results instead. This reproduces across independently-built actors and execution models, so it isn't a bug in the request-building code — Google's backend appears to weight the caller's IP geolocation over the request's explicit coordinates for unauthenticated requests, and Apify's compute runs in AWS `us-east-1` (Ashburn, VA).
- **`openNow`/`minRating`/`category` filters on `searches` are applied client-side**, not passed through to Google's servers — there's no server-side filter parameter for these. Filtered requests fetch more raw results under the hood so filtering still returns close to `maxResults`, but a very narrow filter on a sparse area can come back with fewer results than requested.
- Place detail, reviews, directions, live traffic, reverse geocoding, photos, shareable links, EV reference data, and the business category catalog are not exposed here — use [Google Maps All-in-One API](https://apify.com/romy/google-maps-all-in-one-api) for those.

### Pricing

Pay per event, via the `result` event — charged once per place result or suggestion pushed to the dataset, starting at $0.001 (FREE tier). See the Actor's Pricing tab for current rates.

# Actor input Schema

## `searches` (type: `array`):

Place searches to run. Each entry needs "query", "lat", and "lng" — everything else is optional.

## `suggestions` (type: `array`):

Autocomplete (search-as-you-type) lookups to run. Each entry needs "query" — location narrows results but is optional.

## Actor input object example

```json
{
  "searches": [
    {
      "query": "coffee",
      "lat": 38.8977,
      "lng": -77.0365
    }
  ],
  "suggestions": [
    {
      "query": "White House",
      "lat": 38.9,
      "lng": -77.03
    }
  ]
}
```

# Actor output Schema

## `dataset` (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 = {
    "searches": [
        {
            "query": "coffee",
            "lat": 38.8977,
            "lng": -77.0365
        }
    ],
    "suggestions": [
        {
            "query": "White House",
            "lat": 38.9,
            "lng": -77.03
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("romy/google-maps-search-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 = {
    "searches": [{
            "query": "coffee",
            "lat": 38.8977,
            "lng": -77.0365,
        }],
    "suggestions": [{
            "query": "White House",
            "lat": 38.9,
            "lng": -77.03,
        }],
}

# Run the Actor and wait for it to finish
run = client.actor("romy/google-maps-search-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 '{
  "searches": [
    {
      "query": "coffee",
      "lat": 38.8977,
      "lng": -77.0365
    }
  ],
  "suggestions": [
    {
      "query": "White House",
      "lat": 38.9,
      "lng": -77.03
    }
  ]
}' |
apify call romy/google-maps-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,romy/google-maps-search-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/LYErL0pYuabiO86aA/builds/SQ8T1dNxom8p4jVdM/openapi.json
