# Google Maps Business & Contact Scraper (`herus13/google-maps-scraper`) Actor

Scrape Google Maps businesses with emails, reviews, images & social links. 33% cheaper than alternatives — emails included in base price. Compass-compatible input.

- **URL**: https://apify.com/herus13/google-maps-scraper.md
- **Developed by:** [bootforge](https://apify.com/herus13) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 12 total users, 5 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 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.

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 Scraper — Extract Business Emails, Reviews & Contacts

*Last updated: June 2026*

**Google Maps Scraper** is an [Apify](https://apify.com) actor that extracts business data — emails, phone numbers, reviews, images, and social links — from Google Maps. It returns 24 data fields per business at a flat **$7 per 1,000 results**, with emails, social links, reviews, and images all included at no extra charge. Drop-in replacement for compass/crawler-google-places.

### How to Scrape Google Maps for Business Leads

- **Flat $7 per 1,000 results** — emails, social links, reviews, and images included, no add-on events (a comparable Compass scrape with emails runs ~$8 per 1,000 on Apify's pay-as-you-go plan; see pricing below)
- **No subscription required** — single all-in rate, not a tiered price that needs a paid Apify plan to unlock
- **Fast** — HTTP-first pipeline, no browser needed for basic scrapes (~1s per query)
- **Deep email extraction** — homepage + /contact + /about pages, with personal vs generic classification
- **24 data fields** — more than any other scraper, including neighborhood, timezone, price level, and popular times
- **Compass-compatible** — same input field names, easy to switch
- **Zero duplicates** — deduplication by Google Maps place ID

### Use Cases

- **Lead generation** — Build prospect lists with verified emails and phone numbers for any industry or location
- **Local SEO monitoring** — Track ratings, review counts, and ranking positions for your clients or competitors
- **Market research** — Analyze business density, pricing, and categories across geographic areas
- **Sales prospecting** — Find businesses without websites or with low ratings that need your services
- **Real estate analysis** — Map businesses around properties to assess neighborhood commercial activity
- **Franchise expansion** — Identify underserved markets by analyzing competitor locations and density

### What Data Can You Extract? (24 fields)

**Always included (from HTTP — instant, no browser):**
name, address, phone, website, rating, categories, coordinates, place_id, google_maps_url, neighborhood, timezone, country_code, business_photo, open_status, scraped_at

**With `scrapeContacts: true` (website crawl):**
emails, email_type (personal/generic), social_links (Facebook, Instagram, LinkedIn, X, YouTube, TikTok)

**With `maxReviews` > 0 or `maxImages` > 0 (detail page):**
review_count, hours (full weekly schedule), reviews (author, rating, text, time, owner response), images (Google Maps photo URLs), price_level ($-$$$$), popular_times (current busy status)

### Quick Start

```json
{
  "searchStringsArray": ["dentist"],
  "locationQuery": "Austin, TX",
  "maxCrawledPlacesPerSearch": 20,
  "scrapeContacts": true
}
````

### Switching from Compass / crawler-google-places?

Same field names — copy your config:

`searchStringsArray`, `locationQuery`, `maxCrawledPlacesPerSearch`, `language`, `scrapeContacts`, `scrapePlaceDetailPage`, `placeMinimumStars`, `skipClosedPlaces`, `maxReviews`, `maxImages`, `scrapeSocialMediaProfiles`

### Input Parameters

| Parameter | Default | Description |
|-----------|---------|-------------|
| `searchStringsArray` | required | Search terms |
| `locationQuery` | null | Location (e.g., `Austin, TX`) |
| `maxCrawledPlacesPerSearch` | 100 | Max results per query |
| `scrapeContacts` | true | Extract emails & social links from business websites |
| `scrapeSocialMediaProfiles` | all true | Toggle per platform |
| `maxReviews` | 0 | Reviews per business (0 = skip, saves time) |
| `reviewsSort` | newest | Sort: newest, mostRelevant, highestRating, lowestRating |
| `maxImages` | 0 | Images per business (0 = skip, saves time) |
| `placeMinimumStars` | "" | Min rating filter (e.g., `4`, `4.5`) — drops places rated below this |
| `skipClosedPlaces` | true | Skip permanently closed businesses |
| `website` | allPlaces | Website filter: `allPlaces` (no filter), `withWebsite` (keep only places that **have** a website), `withoutWebsite` (keep only places with **no** website — lead-gen) |
| `language` | en | 19 languages supported |
| `geo_split` | false | Auto-split large areas into grid |
| `geo_split_max_cells` | 100 | Max grid cells (auto-adjusts) |
| `max_concurrency` | 1 | Parallel detail pages |
| `proxy` | null | Optional proxy config |

### Sample Output — Google Maps Business Data

```json
{
  "place_id": "ChIJb5gBC-u0RIYRHkntaUcdJGs",
  "name": "ATX Family Dental",
  "address": "1700 S 1st St, Austin, TX 78704, United States",
  "phone": "+1 512-717-3147",
  "website": "https://www.atxfamilydental.com/",
  "emails": ["info@atxfamilydental.com"],
  "email_type": "generic",
  "rating": 4.9,
  "review_count": 802,
  "categories": ["Dentist", "Cosmetic dentist", "Pediatric dentist"],
  "hours": {"Monday": "8 AM–4 PM", "Tuesday": "8 AM–4 PM"},
  "latitude": 30.2482229,
  "longitude": -97.7559705,
  "google_maps_url": "https://www.google.com/maps/place/...",
  "social_links": {
    "facebook": "https://facebook.com/...",
    "instagram": "https://instagram.com/..."
  },
  "reviews": [
    {
      "author": "John Smith",
      "rating": 5,
      "text": "Great dentist!",
      "time": "2 months ago",
      "response": "Thank you!"
    }
  ],
  "images": ["https://lh3.googleusercontent.com/..."],
  "neighborhood": "Bouldin Creek",
  "timezone": "America/Chicago",
  "country_code": "US",
  "business_photo": "https://lh5.googleusercontent.com/...",
  "open_status": "Open · Closes 4 PM",
  "price_level": "$$",
  "popular_times": "Not busy",
  "scraped_at": "2026-03-27T01:00:00+00:00"
}
```

### How Much Does It Cost to Scrape Google Maps?

**$0.007 per result** + $0.01 per GB of memory at run start (default 4 GB → $0.04/run). Emails, social links, reviews, and images are all included — one flat rate, no add-on events.

**Comparison to Compass / crawler-google-places (Apify pay-as-you-go / Free plan, scraping the same data — places + details + contact emails):**

| Line item (per 1,000 places, with emails) | Compass (pay-as-you-go) | This actor |
|-------------------------------------------|-------------------------|-----------|
| Base scraped place                        | $4.00                   | included  |
| + additional place details                | $2.00                   | included  |
| + company contacts enrichment (emails, social) | $2.00              | included  |
| **Subtotal**                              | **~$8.00 / 1,000**      | **$7.00 / 1,000** |
| Actor start                               | ~$0                     | ~$0.04/run |

On Apify's pay-as-you-go (Free) plan — what you pay with no paid subscription — a comparable Compass scrape with emails costs about **$8 per 1,000**, versus our flat **$7 per 1,000**. Our price is a single all-in rate that needs no subscription.

Note: Compass advertises "from $1.50 / 1,000," which is its base-place price on the **Business** subscription tier (95% discount) and excludes emails, details, reviews, and images. On paid Apify subscription tiers Compass's add-on prices drop and can fall below $7; our actor is a flat rate regardless of plan.

### Proxy Configuration

Works without proxy for small runs. For 100+ results, configure a proxy:

```json
// Apify managed proxy
{"provider": "apify", "group": "RESIDENTIAL"}

// Bright Data
{"provider": "brightdata", "username": "YOUR_USER", "password": "YOUR_PASS", "zone": "residential", "country": "US"}

// Oxylabs
{"provider": "oxylabs", "username": "YOUR_USER", "password": "YOUR_PASS", "proxy_type": "residential", "country": "US"}

// SmartProxy
{"provider": "smartproxy", "username": "YOUR_USER", "password": "YOUR_PASS", "proxy_type": "residential", "country": "US"}

// Any proxy URL
{"provider": "raw_urls", "urls": ["http://user:pass@proxy.example.com:8080"]}
```

### Cost Estimator

| Use case | Config | Est. cost |
|----------|--------|-----------|
| 100 businesses, basic data | default | ~$0.74 |
| 1,000 businesses with emails | `scrapeContacts: true` | ~$7.04 |
| 1,000 businesses + 5 reviews each | `maxReviews: 5` | ~$7.04 |
| 10,000 businesses with emails | + `geo_split: true` | ~$70.04 |

All costs include emails, social links, reviews, and images. No add-ons.

### Error Handling

| Situation | What happens |
|-----------|-------------|
| Proxy fails | Auto-retries without proxy, logs warning |
| Google blocks request | Falls back from HTTP to Playwright browser |
| Place detail page timeout | Skips place, continues with next (60s timeout) |
| Website unreachable (email extraction) | Skips emails for that business, returns other data |
| 0 search results | Returns empty dataset, no charge |
| Google consent screen | Auto-dismissed, scraping continues |

Failed places are logged but don't stop the run. You always get partial results.

### Frequently Asked Questions

**Do I need a proxy to scrape Google Maps?**
No for small runs (under 100 results). For larger scrapes, configure a residential proxy to avoid rate limits. See proxy config above.

**How many Google Maps results can I scrape?**
\~120 per search query. Enable `geo_split: true` to automatically split large areas into a grid and scrape thousands of results.

**Why did I get 0 (or fewer) results than expected?**
Most often a **filter** removed them. `website`, `placeMinimumStars`, and `skipClosedPlaces` are applied to every search and drop places that don't match:

- `website: "withoutWebsite"` keeps **only places that have no website** — businesses that *do* have a website are removed. (Set `website: "allPlaces"` for no filter.)
- `placeMinimumStars` drops anything rated below the threshold (places with no rating are dropped too).
- `skipClosedPlaces: true` drops permanently-closed businesses.

The run log tells you exactly what happened, e.g. `Filter 'website=withoutWebsite' removed 2 place(s)` and, if filters remove everything, a warning naming the active filters. Check the log and relax the filters if you expected results.

**Is this cheaper than Compass / the standard Apify Google Maps scraper?**
On Apify's pay-as-you-go (Free) plan, yes for a scrape that includes emails: Compass charges $4 per 1,000 places + $2 details + $2 company-contacts enrichment ≈ $8 per 1,000, while this actor is a flat $7 per 1,000 with emails, social links, reviews, and images included. Compass's headline "$1.50 / 1,000" is its base-place price on a paid Business subscription and excludes emails. If you run a high-volume paid Apify subscription, Compass's discounted add-ons can drop below $7; this actor stays a flat rate with no subscription needed.

**Why are some emails missing?**
Not all businesses list emails on their website. Service businesses (law firms, dentists, plumbers) typically have better email coverage than restaurants or retail shops.

**How do I extract Google Maps reviews?**
Set `maxReviews` to any number greater than 0. Each review includes author name, star rating, review text, date, and owner response.

**How fast is the Google Maps scraper?**
Basic data: ~1s per query. With email extraction: ~5s per business. With reviews and images: slower (requires browser rendering).

**Can I cache Google Maps data between runs?**
Yes. Set `cache_provider: "apify"` to reuse detail page data across runs. Only places that changed get re-scraped.

### Related Actors

Building a full data pipeline? Pair this actor with our other scrapers — same proxy config format, same Pydantic-validated output.

#### Local business intelligence

- **[Google Maps Reviews Scraper](https://apify.com/herus13/google-maps-reviews-scraper)** — Pull every review for any place — review text + English translation, star rating, photos, owner replies, and reviewer details. 20 fields per review, $0.50 per 1,000 reviews.

#### Lead generation

- **[LinkedIn Profile Scraper](https://apify.com/herus13/linkedin-profile-scraper)** — Scrape LinkedIn profiles via your li\_at cookie. Structured fields, full experience history, optional email/phone/contact enrichment.

#### Lead generation / Hiring

- **[LinkedIn Jobs Scraper](https://apify.com/herus13/linkedin-jobs-scraper)** — Scrape LinkedIn job listings with 30 fields per job — company enrichment, salary, recruiter info, full description. No login required.

#### E-commerce intelligence

- **[TikTok Shop Product Scraper](https://apify.com/herus13/tiktok-shop-scraper)** — Scrape TikTok Shop products across 10 regions (US, GB, VN, TH, PH, MY, SG, JP, MX, BR) — variants, prices, seller info, ratings, sold counts.

# Actor input Schema

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

<p>List of search terms to look up on Google Maps.</p><p>Example: <code>restaurant</code>, <code>plumber</code>, <code>dentist</code></p>
## `locationQuery` (type: `string`):

<p>Location to search in. Example: <code>New York, USA</code>, <code>Austin, TX</code>, <code>London, UK</code></p><p>Leave empty to use the search query itself as location context.</p>
## `maxCrawledPlacesPerSearch` (type: `integer`):

Maximum number of businesses to scrape per search query. Google Maps shows ~120 per viewport; enable geo\_split for more.

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

Language for Google Maps results.

## `scrapeContacts` (type: `boolean`):

<p>Visit each business website to extract email addresses and social media links.</p><p><strong>Included in the base price — no extra charge.</strong></p>
## `scrapePlaceDetailPage` (type: `boolean`):

<p>Visit each place detail page to extract phone, website, hours, reviews, and images.</p><p>Disable for faster runs when you only need name, rating, address, and categories.</p>
## `scrapeSocialMediaProfiles` (type: `object`):

Toggle which social media profiles to extract from business websites.

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

Maximum number of reviews to scrape per business. Set to 0 to skip review scraping.

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

How to sort reviews before scraping.

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

Maximum number of image URLs to extract per business. Set to 0 to skip.

## `placeMinimumStars` (type: `string`):

Only include places with at least this rating. Leave empty for all.

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

Skip permanently closed businesses. Saves you from wasted results.

## `website` (type: `string`):

Filter businesses by whether they have a website listed.

## `geo_split` (type: `boolean`):

<p>Automatically split large areas into a grid to overcome Google's ~120 result limit per viewport.</p><p>Recommended for state/country-level searches.</p>
## `geo_split_max_cells` (type: `integer`):

Maximum number of grid cells for geo\_split. Larger areas auto-increase cell size to stay within this limit.

## `cache_provider` (type: `string`):

<p>Cache detail data (emails, reviews, hours) to speed up repeat runs.</p><p><strong>memory</strong>: within same run only (default). <strong>file</strong>: persists to disk (CLI/local). <strong>apify</strong>: persists across runs via Key-Value Store.</p>
## `cache_ttl_seconds` (type: `integer`):

How long to keep cached data before re-scraping. Default 24 hours (86400 seconds).

## `max_requests_per_minute` (type: `integer`):

Rate limit for Google Maps page loads. Lower values reduce blocking risk.

## `max_concurrency` (type: `integer`):

Number of place detail pages to process at once. Default 1 (sequential, most reliable). Increase to 2-3 for faster runs if you have enough memory.

## `transport` (type: `string`):

<p>HTTP engine for the Maps SERP API and contact pages. <b>Auto</b> uses <code>httpx</code> (verified in production). A browser (Camoufox/Patchright) is always used for JS-heavy SERP rendering regardless of this setting.</p>
## `strategy_mode` (type: `string`):

How the engine orders retry attempts. <code>cost\_first</code> (default) favors the cheapest working path.

## `request_delay` (type: `integer`):

Fixed delay inserted between HTTP-engine requests. 0 = no added delay.

## `proxy` (type: `object`):

<p>Apify Proxy (residential) strongly recommended. Datacenter IPs are blocked by many sites and force slower browser fallback.</p><p>Apify proxy costs are billed separately by the platform.</p>

## Actor input object example

```json
{
  "searchStringsArray": [
    "dentist"
  ],
  "locationQuery": "Austin, TX",
  "maxCrawledPlacesPerSearch": 10,
  "language": "en",
  "scrapeContacts": true,
  "scrapePlaceDetailPage": true,
  "scrapeSocialMediaProfiles": {
    "facebooks": true,
    "instagrams": true,
    "youtubes": true,
    "tiktoks": true,
    "twitters": true,
    "linkedins": true
  },
  "maxReviews": 0,
  "reviewsSort": "newest",
  "maxImages": 0,
  "placeMinimumStars": "",
  "skipClosedPlaces": true,
  "website": "allPlaces",
  "geo_split": false,
  "geo_split_max_cells": 100,
  "cache_provider": "memory",
  "cache_ttl_seconds": 86400,
  "max_requests_per_minute": 60,
  "max_concurrency": 1,
  "transport": "auto",
  "strategy_mode": "cost_first",
  "request_delay": 0,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

List of businesses with contact data, emails, reviews, and social links extracted from Google Maps

# 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": [
        "dentist"
    ],
    "locationQuery": "Austin, TX",
    "maxCrawledPlacesPerSearch": 10,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("herus13/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": ["dentist"],
    "locationQuery": "Austin, TX",
    "maxCrawledPlacesPerSearch": 10,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("herus13/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": [
    "dentist"
  ],
  "locationQuery": "Austin, TX",
  "maxCrawledPlacesPerSearch": 10,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call herus13/google-maps-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps Business & Contact Scraper",
        "description": "Scrape Google Maps businesses with emails, reviews, images & social links. 33% cheaper than alternatives — emails included in base price. Compass-compatible input.",
        "version": "1.1",
        "x-build-id": "d8ekwihQYi8QqYic3"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/herus13~google-maps-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-herus13-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/herus13~google-maps-scraper/runs": {
            "post": {
                "operationId": "runs-sync-herus13-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/herus13~google-maps-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-herus13-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",
                "required": [
                    "searchStringsArray"
                ],
                "properties": {
                    "searchStringsArray": {
                        "title": "Search Queries",
                        "type": "array",
                        "description": "<p>List of search terms to look up on Google Maps.</p><p>Example: <code>restaurant</code>, <code>plumber</code>, <code>dentist</code></p>",
                        "items": {
                            "type": "string"
                        }
                    },
                    "locationQuery": {
                        "title": "Location",
                        "type": "string",
                        "description": "<p>Location to search in. Example: <code>New York, USA</code>, <code>Austin, TX</code>, <code>London, UK</code></p><p>Leave empty to use the search query itself as location context.</p>"
                    },
                    "maxCrawledPlacesPerSearch": {
                        "title": "Max Results Per Search",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of businesses to scrape per search query. Google Maps shows ~120 per viewport; enable geo_split for more.",
                        "default": 100
                    },
                    "language": {
                        "title": "Language",
                        "enum": [
                            "en",
                            "es",
                            "fr",
                            "de",
                            "it",
                            "pt",
                            "ja",
                            "ko",
                            "zh-CN",
                            "zh-TW",
                            "ar",
                            "hi",
                            "ru",
                            "nl",
                            "pl",
                            "tr",
                            "vi",
                            "th",
                            "id"
                        ],
                        "type": "string",
                        "description": "Language for Google Maps results.",
                        "default": "en"
                    },
                    "scrapeContacts": {
                        "title": "Extract Emails & Social Links",
                        "type": "boolean",
                        "description": "<p>Visit each business website to extract email addresses and social media links.</p><p><strong>Included in the base price — no extra charge.</strong></p>",
                        "default": true
                    },
                    "scrapePlaceDetailPage": {
                        "title": "Scrape Place Detail Page",
                        "type": "boolean",
                        "description": "<p>Visit each place detail page to extract phone, website, hours, reviews, and images.</p><p>Disable for faster runs when you only need name, rating, address, and categories.</p>",
                        "default": true
                    },
                    "scrapeSocialMediaProfiles": {
                        "title": "Social Media Profiles",
                        "type": "object",
                        "description": "Toggle which social media profiles to extract from business websites.",
                        "default": {
                            "facebooks": true,
                            "instagrams": true,
                            "youtubes": true,
                            "tiktoks": true,
                            "twitters": true,
                            "linkedins": true
                        }
                    },
                    "maxReviews": {
                        "title": "Max Reviews",
                        "minimum": 0,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of reviews to scrape per business. Set to 0 to skip review scraping.",
                        "default": 0
                    },
                    "reviewsSort": {
                        "title": "Reviews Sort Order",
                        "enum": [
                            "newest",
                            "mostRelevant",
                            "highestRating",
                            "lowestRating"
                        ],
                        "type": "string",
                        "description": "How to sort reviews before scraping.",
                        "default": "newest"
                    },
                    "maxImages": {
                        "title": "Max Images",
                        "minimum": 0,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of image URLs to extract per business. Set to 0 to skip.",
                        "default": 0
                    },
                    "placeMinimumStars": {
                        "title": "Minimum Rating",
                        "enum": [
                            "",
                            "1",
                            "2",
                            "3",
                            "4",
                            "4.5"
                        ],
                        "type": "string",
                        "description": "Only include places with at least this rating. Leave empty for all.",
                        "default": ""
                    },
                    "skipClosedPlaces": {
                        "title": "Skip Closed Places",
                        "type": "boolean",
                        "description": "Skip permanently closed businesses. Saves you from wasted results.",
                        "default": true
                    },
                    "website": {
                        "title": "Website Filter",
                        "enum": [
                            "allPlaces",
                            "withWebsite",
                            "withoutWebsite"
                        ],
                        "type": "string",
                        "description": "Filter businesses by whether they have a website listed.",
                        "default": "allPlaces"
                    },
                    "geo_split": {
                        "title": "Auto Geographic Splitting",
                        "type": "boolean",
                        "description": "<p>Automatically split large areas into a grid to overcome Google's ~120 result limit per viewport.</p><p>Recommended for state/country-level searches.</p>",
                        "default": false
                    },
                    "geo_split_max_cells": {
                        "title": "Max Grid Cells",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of grid cells for geo_split. Larger areas auto-increase cell size to stay within this limit.",
                        "default": 100
                    },
                    "cache_provider": {
                        "title": "Cache Provider",
                        "enum": [
                            "memory",
                            "file",
                            "apify"
                        ],
                        "type": "string",
                        "description": "<p>Cache detail data (emails, reviews, hours) to speed up repeat runs.</p><p><strong>memory</strong>: within same run only (default). <strong>file</strong>: persists to disk (CLI/local). <strong>apify</strong>: persists across runs via Key-Value Store.</p>",
                        "default": "memory"
                    },
                    "cache_ttl_seconds": {
                        "title": "Cache TTL (seconds)",
                        "minimum": 60,
                        "maximum": 604800,
                        "type": "integer",
                        "description": "How long to keep cached data before re-scraping. Default 24 hours (86400 seconds).",
                        "default": 86400
                    },
                    "max_requests_per_minute": {
                        "title": "Max Requests Per Minute",
                        "minimum": 10,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Rate limit for Google Maps page loads. Lower values reduce blocking risk.",
                        "default": 60
                    },
                    "max_concurrency": {
                        "title": "Max Concurrency",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Number of place detail pages to process at once. Default 1 (sequential, most reliable). Increase to 2-3 for faster runs if you have enough memory.",
                        "default": 1
                    },
                    "transport": {
                        "title": "Transport (HTTP engine)",
                        "enum": [
                            "auto",
                            "httpx",
                            "curl_cffi",
                            "primp"
                        ],
                        "type": "string",
                        "description": "<p>HTTP engine for the Maps SERP API and contact pages. <b>Auto</b> uses <code>httpx</code> (verified in production). A browser (Camoufox/Patchright) is always used for JS-heavy SERP rendering regardless of this setting.</p>",
                        "default": "auto"
                    },
                    "strategy_mode": {
                        "title": "Retry Strategy",
                        "enum": [
                            "cost_first",
                            "speed_first",
                            "balanced",
                            "stealth_first"
                        ],
                        "type": "string",
                        "description": "How the engine orders retry attempts. <code>cost_first</code> (default) favors the cheapest working path.",
                        "default": "cost_first"
                    },
                    "request_delay": {
                        "title": "Request Delay (seconds)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Fixed delay inserted between HTTP-engine requests. 0 = no added delay.",
                        "default": 0
                    },
                    "proxy": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "<p>Apify Proxy (residential) strongly recommended. Datacenter IPs are blocked by many sites and force slower browser fallback.</p><p>Apify proxy costs are billed separately by the platform.</p>"
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
