# Google Maps Scraper (`abotapi/google-maps-scraper`) Actor

Extract business data from Google Maps at scale. Get names, addresses, phone numbers, websites, ratings, reviews, opening hours, popular times, photos, and 40+ data points per listing.

- **URL**: https://apify.com/abotapi/google-maps-scraper.md
- **Developed by:** [AbotAPI](https://apify.com/abotapi) (community)
- **Categories:** Lead generation, Social media, Real estate
- **Stats:** 67 total users, 7 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.70 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Google Maps Business Scraper

![Google Maps Business Scraper](https://i.postimg.cc/dtWn9qwr/banner.png)

Extract business data from Google Maps at scale. Get names, addresses, phone numbers, websites, ratings, reviews, opening hours, popular times, photos, and 40+ data points per listing.

### What Data Can You Extract?

#### Business Information
- Business name, category, subcategories
- Full address with street, city, state, postal code, country
- Phone number and website URL
- Google Place ID and Maps URL

#### Ratings & Reviews
- Average rating (1-5 stars)
- Total review count
- Individual reviews with text, rating, date, author
- Owner responses to reviews

#### Location Data
- Latitude and longitude coordinates
- Plus Code (Google's location code)
- "Located in" parent location (e.g., mall, airport)

#### Operational Details
- Opening hours (daily schedule)
- Popular times (hourly occupancy by day)
- Temporarily/permanently closed status
- Price level ($, $$, $$$, $$$$)

#### Rich Content
- Photo URLs (configurable limit)
- Menu URL
- Order/delivery links (DoorDash, UberEats, etc.)
- "People also search" related businesses

#### Search Context
- Search query that found the business
- Rank in search results
- Sponsored/advertisement indicator

### Quick Start

#### Basic Search
```json
{
  "searchStringsArray": ["restaurants"],
  "location": "New York, NY",
  "maxResultsPerSearch": 100
}
````

#### Search by Coordinates

```json
{
  "searchStringsArray": ["coffee shops"],
  "lat": 40.7128,
  "lng": -74.0060,
  "zoom": 15,
  "maxResultsPerSearch": 50
}
```

#### Large Area with Grid Search

```json
{
  "searchStringsArray": ["hotels"],
  "customGeolocation": {
    "type": "Polygon",
    "coordinates": [[[-122.5, 37.7], [-122.3, 37.7], [-122.3, 37.85], [-122.5, 37.85], [-122.5, 37.7]]]
  },
  "zoom": 16,
  "maxResultsPerSearch": 200
}
```

#### With Reviews

```json
{
  "searchStringsArray": ["dentists"],
  "location": "Chicago, IL",
  "maxResultsPerSearch": 50,
  "maxReviews": 20,
  "reviewsSort": "newest"
}
```

#### Direct Place ID Lookup

```json
{
  "searchStringsArray": ["place_id:ChIJN1t_tDeuEmsRUsoyG83frY4"]
}
```

### Input Parameters

#### Search Options

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchStringsArray` | string\[] | `["restaurants"]` | Search queries or Place IDs (`place_id:ChIJ...`) |
| `startUrls` | object\[] | `[]` | Direct Google Maps URLs to scrape |
| `location` | string | `"New York, NY"` | Location text appended to search |

#### Geographic Targeting

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `lat` | number | - | Latitude for coordinate search (-90 to 90) |
| `lng` | number | - | Longitude for coordinate search (-180 to 180) |
| `customGeolocation` | object | - | GeoJSON Polygon/MultiPolygon for grid search |
| `zoom` | integer | `14` | Map zoom level (1-21). Higher = smaller grid cells |
| `country` | string | - | Country filter |
| `state` | string | - | State/region filter |
| `city` | string | - | City filter |
| `postalCode` | string | - | Postal/ZIP code filter |

#### Extraction Limits

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `maxResultsPerSearch` | integer | `5` | Max results per search query (up to 10,000) |
| `maxReviews` | integer | `0` | Max reviews per business (0 = skip reviews) |
| `maxImages` | integer | `10` | Max photo URLs per business |

#### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape — the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each record — not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify → Settings → Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Output Options

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `reviewsSort` | string | `"relevant"` | Sort reviews: `relevant`, `newest`, `highest`, `lowest` |
| `skipClosedPlaces` | boolean | `false` | Skip closed businesses |
| `oneReviewPerRow` | boolean | `false` | Output one row per review (for CSV) |
| `language` | string | `"en"` | Language code for results |

#### Performance

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `maxConcurrency` | integer | `5` | Parallel browser pages (1-20) |
| `proxyConfiguration` | object | - | Apify proxy settings |

#### Resume Options

| Parameter | Type | Description |
|-----------|------|-------------|
| `resumeRunId` | string | Run ID to resume from (loads previously scraped Place IDs) |

### Output Schema

Each business is saved with the following structure:

```json
{
  "placeId": "ChIJ49sQuK-AhYARM6U646SA12Y",
  "title": "Blue Bottle Coffee",
  "url": "https://www.google.com/maps/place/...",
  "categoryName": "Coffee shop",
  "address": "315 Linden St, San Francisco, CA 94102",
  "street": "315 Linden St",
  "city": "San Francisco",
  "state": "CA",
  "postalCode": "94102",
  "countryCode": "US",
  "phone": "+1 510-653-3394",
  "website": "https://bluebottlecoffee.com",
  "totalScore": 4.5,
  "reviewsCount": 1842,
  "priceLevel": "$$",
  "location": {
    "lat": 37.7763,
    "lng": -122.4158
  },
  "plusCode": "QHFJ+8R Hayes Valley, San Francisco, CA",
  "openingHours": [
    { "day": "Monday", "hours": "7 AM - 6 PM" },
    { "day": "Tuesday", "hours": "7 AM - 6 PM" }
  ],
  "popularTimes": [
    {
      "day": "Monday",
      "hours": [
        { "hour": 7, "occupancyPercent": 20 },
        { "hour": 8, "occupancyPercent": 45 },
        { "hour": 9, "occupancyPercent": 65 }
      ]
    }
  ],
  "imageUrls": ["https://lh3.googleusercontent.com/..."],
  "peopleAlsoSearch": [
    { "title": "Sightglass Coffee", "placeId": "ChIJ...", "url": "..." }
  ],
  "menuUrl": "https://bluebottlecoffee.com/menu",
  "orderLinks": [
    { "platform": "DoorDash", "url": "https://..." }
  ],
  "temporarilyClosed": false,
  "permanentlyClosed": false,
  "searchString": "coffee shops",
  "rank": 3,
  "isAdvertisement": false,
  "scrapedAt": "2025-12-06T10:30:00.000Z",
  "reviews": [
    {
      "name": "John D.",
      "text": "Great coffee and atmosphere!",
      "rating": 5,
      "date": "2 weeks ago",
      "responseFromOwner": "Thanks for visiting!"
    }
  ]
}
```

### Scaling to Millions of Records

Google Maps limits search results to ~120-400 per query. To scrape millions of businesses:

#### Strategy 1: Grid Search (Recommended)

Use `customGeolocation` to define a polygon. The scraper auto-generates grid points based on zoom level:

| Zoom | Grid Cell Size | Example: California |
|------|----------------|---------------------|
| 14 | ~6 km | ~2,500 cells |
| 15 | ~3 km | ~10,000 cells |
| 16 | ~1.5 km | ~40,000 cells |

Each cell runs a separate search, so:

- 10,000 cells × 200 results/cell = **2 million potential results**

```json
{
  "searchStringsArray": ["restaurants"],
  "customGeolocation": {
    "type": "Polygon",
    "coordinates": [[[...california boundary...]]]
  },
  "zoom": 15,
  "maxResultsPerSearch": 200
}
```

#### Strategy 2: Multiple Search Terms

Different queries return different businesses:

```json
{
  "searchStringsArray": [
    "restaurants", "cafes", "bars", "hotels",
    "gyms", "dentists", "plumbers", "lawyers"
  ],
  "location": "Los Angeles, CA"
}
```

#### Strategy 3: Neighborhood Batching

Run separate Actor calls per area:

```bash
## Run 1: Downtown
{"searchStringsArray": ["restaurants"], "location": "Downtown, Los Angeles"}

## Run 2: Hollywood
{"searchStringsArray": ["restaurants"], "location": "Hollywood, Los Angeles"}
```

### Resume & Recovery

#### Automatic Protection

- **Deduplication**: Place IDs saved to persistent storage
- **Incremental saves**: Results pushed immediately (never lost)
- **Migration handling**: State saved when Apify migrates servers

#### Manual Resume

If a run crashes, start a new run with `resumeRunId`:

```json
{
  "searchStringsArray": ["restaurants"],
  "location": "San Francisco, CA",
  "resumeRunId": "abc123xyz"
}
```

The scraper loads Place IDs from the previous run and skips already-scraped businesses.

### Anti-Detection Features

Built-in protections for reliable scraping:

- Browser fingerprint rotation
- Webdriver detection masking
- Human-like scrolling with random delays
- Rate limiting (30 requests/minute)
- CAPTCHA detection with exponential backoff
- Automatic retry with session rotation

**Tip**: For high-volume scraping, use residential proxies via `proxyConfiguration`.

### Performance

| Metric | Typical Value |
|--------|---------------|
| Speed | 800-1,200 listings/hour |
| Memory | < 1 GB |
| Concurrency | 1-20 parallel pages |
| Retry attempts | 3 per failed request |

### Export Formats

Download from Apify Dataset:

- **JSON** - Full nested structure
- **CSV** - Flattened for spreadsheets
- **Excel** - .xlsx format
- **XML** - For integrations

### Use Cases

- **Lead Generation**: Build prospect lists with contact info
- **Market Research**: Analyze competitors, pricing, ratings
- **Local SEO**: Track rankings and reviews
- **Real Estate**: Map amenities near properties
- **Investment**: Assess retail density and competition
- **Data Enrichment**: Add location data to existing records

# Actor input Schema

## `searchStringsArray` (type: `array`):

List of search queries (e.g., 'restaurants', 'coffee shops')

## `startUrls` (type: `array`):

Direct Google Maps URLs to scrape

## `location` (type: `string`):

Location text (e.g., 'New York, NY', 'Tokyo, Japan')

## `lat` (type: `number`):

Latitude for coordinate-based search

## `lng` (type: `number`):

Longitude for coordinate-based search

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

Country for geolocation filtering

## `state` (type: `string`):

State or region for geolocation filtering

## `city` (type: `string`):

City for geolocation filtering

## `postalCode` (type: `string`):

Postal/ZIP code for geolocation filtering

## `customGeolocation` (type: `object`):

GeoJSON geometry (Polygon, MultiPolygon, or Point with radius)

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

Map zoom level (1=world, 21=building). Higher = more precise, fewer results

## `maxResultsPerSearch` (type: `integer`):

Maximum number of results to extract per search query

## `maxReviews` (type: `integer`):

Maximum reviews to extract per business. Set to 0 to disable review extraction (faster)

## `maxImages` (type: `integer`):

Maximum number of image URLs to extract per business

## `reviewsSort` (type: `string`):

How to sort reviews when extracting

## `oneReviewPerRow` (type: `boolean`):

Output each review as a separate Dataset row (useful for CSV export)

## `skipClosedPlaces` (type: `boolean`):

Skip temporarily or permanently closed businesses

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

Language code for search results (e.g., 'en', 'es', 'ja')

## `maxConcurrency` (type: `integer`):

Number of parallel browser contexts (higher = faster but more memory)

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

Apify Proxy settings. Residential proxies recommended for high volume

## `resumeRunId` (type: `string`):

Run ID to resume from. The Actor will load already-scraped Place IDs from that run and skip them.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "searchStringsArray": [
    "restaurants"
  ],
  "location": "New York, NY",
  "zoom": 14,
  "maxResultsPerSearch": 2,
  "maxReviews": 0,
  "maxImages": 10,
  "reviewsSort": "relevant",
  "oneReviewPerRow": false,
  "skipClosedPlaces": false,
  "language": "en",
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `businesses` (type: `string`):

Dataset containing all scraped business listings with full details.

# 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 = {
    "searchStringsArray": [
        "restaurants"
    ],
    "location": "New York, NY",
    "maxResultsPerSearch": 2,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/google-maps-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 = {
    "searchStringsArray": ["restaurants"],
    "location": "New York, NY",
    "maxResultsPerSearch": 2,
    "proxyConfiguration": { "useApifyProxy": False },
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchStringsArray": [
    "restaurants"
  ],
  "location": "New York, NY",
  "maxResultsPerSearch": 2,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call abotapi/google-maps-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=abotapi/google-maps-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps Scraper",
        "description": "Extract business data from Google Maps at scale. Get names, addresses, phone numbers, websites, ratings, reviews, opening hours, popular times, photos, and 40+ data points per listing.",
        "version": "1.0",
        "x-build-id": "ZWITcDFADb6CjLDYZ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/abotapi~google-maps-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-abotapi-google-maps-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/abotapi~google-maps-scraper/runs": {
            "post": {
                "operationId": "runs-sync-abotapi-google-maps-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/abotapi~google-maps-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-abotapi-google-maps-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchStringsArray": {
                        "title": "Search Terms",
                        "type": "array",
                        "description": "List of search queries (e.g., 'restaurants', 'coffee shops')",
                        "items": {
                            "type": "string"
                        },
                        "default": [
                            "restaurants"
                        ]
                    },
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Direct Google Maps URLs to scrape",
                        "items": {
                            "type": "object"
                        }
                    },
                    "location": {
                        "title": "Location",
                        "type": "string",
                        "description": "Location text (e.g., 'New York, NY', 'Tokyo, Japan')",
                        "default": "New York, NY"
                    },
                    "lat": {
                        "title": "Latitude",
                        "minimum": -90,
                        "maximum": 90,
                        "type": "number",
                        "description": "Latitude for coordinate-based search"
                    },
                    "lng": {
                        "title": "Longitude",
                        "minimum": -180,
                        "maximum": 180,
                        "type": "number",
                        "description": "Longitude for coordinate-based search"
                    },
                    "country": {
                        "title": "Country",
                        "type": "string",
                        "description": "Country for geolocation filtering"
                    },
                    "state": {
                        "title": "State/Region",
                        "type": "string",
                        "description": "State or region for geolocation filtering"
                    },
                    "city": {
                        "title": "City",
                        "type": "string",
                        "description": "City for geolocation filtering"
                    },
                    "postalCode": {
                        "title": "Postal Code",
                        "type": "string",
                        "description": "Postal/ZIP code for geolocation filtering"
                    },
                    "customGeolocation": {
                        "title": "Custom Geolocation (GeoJSON)",
                        "type": "object",
                        "description": "GeoJSON geometry (Polygon, MultiPolygon, or Point with radius)"
                    },
                    "zoom": {
                        "title": "Zoom Level",
                        "minimum": 1,
                        "maximum": 21,
                        "type": "integer",
                        "description": "Map zoom level (1=world, 21=building). Higher = more precise, fewer results",
                        "default": 14
                    },
                    "maxResultsPerSearch": {
                        "title": "Max Results Per Search",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of results to extract per search query",
                        "default": 2
                    },
                    "maxReviews": {
                        "title": "Max Reviews Per Business",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum reviews to extract per business. Set to 0 to disable review extraction (faster)",
                        "default": 0
                    },
                    "maxImages": {
                        "title": "Max Images Per Business",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of image URLs to extract per business",
                        "default": 10
                    },
                    "reviewsSort": {
                        "title": "Reviews Sort Order",
                        "enum": [
                            "relevant",
                            "newest",
                            "highest",
                            "lowest"
                        ],
                        "type": "string",
                        "description": "How to sort reviews when extracting",
                        "default": "relevant"
                    },
                    "oneReviewPerRow": {
                        "title": "One Review Per Row",
                        "type": "boolean",
                        "description": "Output each review as a separate Dataset row (useful for CSV export)",
                        "default": false
                    },
                    "skipClosedPlaces": {
                        "title": "Skip Closed Places",
                        "type": "boolean",
                        "description": "Skip temporarily or permanently closed businesses",
                        "default": false
                    },
                    "language": {
                        "title": "Language",
                        "type": "string",
                        "description": "Language code for search results (e.g., 'en', 'es', 'ja')",
                        "default": "en"
                    },
                    "maxConcurrency": {
                        "title": "Max Concurrency",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Number of parallel browser contexts (higher = faster but more memory)",
                        "default": 5
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Apify Proxy settings. Residential proxies recommended for high volume",
                        "default": {
                            "useApifyProxy": false
                        }
                    },
                    "resumeRunId": {
                        "title": "Resume From Run ID",
                        "type": "string",
                        "description": "Run ID to resume from. The Actor will load already-scraped Place IDs from that run and skip them."
                    },
                    "mcpConnectors": {
                        "title": "Pipe results into your apps (optional)",
                        "type": "array",
                        "description": "Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON — the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com)."
                    },
                    "notionParentPageUrl": {
                        "title": "Notion parent page (Notion connector only)",
                        "type": "string",
                        "description": "URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors."
                    },
                    "maxNotifyListings": {
                        "title": "Max items to export per connector",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Cap on items written to each connector per run. Does not affect the dataset.",
                        "default": 50
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
