# Google Maps Scraper — Extract Business Data at Scale (`fascinating_lentil/google-maps-scraper`) Actor

Scrape Google Maps for business leads — extract name, address, phone, website, rating, reviews, hours, category, and coordinates. Residential proxies included. Pay per result. Export to CSV, JSON, or Excel.

- **URL**: https://apify.com/fascinating\_lentil/google-maps-scraper.md
- **Developed by:** [Md Jakaria Mirza](https://apify.com/fascinating_lentil) (community)
- **Categories:** Automation, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 result scrapeds

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 Data at Scale

Production-grade Apify Actor for scraping public Google Maps business listings worldwide. Enter any keyword and one or more global locations, then export clean business data to JSON, CSV, Excel, XML, or RSS from the Apify Dataset.

This Actor is built with Node.js 20, TypeScript, Apify SDK v3, Crawlee, and Playwright. It uses Apify residential proxies, session rotation, randomized delays, and resilient extraction logic for Google Maps result pages.

### Apify Store Listing

**Title:** Google Maps Scraper - Extract Business Data at Scale

**Short description:** Scrape worldwide Google Maps listings with names, phones, websites, ratings, reviews, categories, hours, and coordinates. Export to CSV, JSON, or Excel.

**Store description:**

Google Maps Scraper - Extract Business Data at Scale helps teams collect structured local business data from Google Maps searches worldwide. Use it to find restaurants in London, dentists in Dubai, hotels in Tokyo, plumbers in Toronto, clinics in Berlin, or any other keyword/location combination. The Actor opens Google Maps in a real browser, scrolls the search feed, visits each business detail panel, and extracts practical B2B data including business name, address, phone, website, category, rating, reviews count, opening hours, coordinates, Google Maps ID, plus code, and Maps URL.

It supports batch scraping by combining multiple keywords with multiple locations in a single run. Locations can be cities, countries, postal codes, neighborhoods, addresses, latitude/longitude pairs, the built-in 169-city `high_demand_markets` preset, or the broader 171-city `world_major_cities` preset. Country targeting is optional: leave `countryCode` empty for worldwide location-text based searches, or set it to bias Google Maps and proxy country for a specific market.

The Actor is monetized with Apify Pay Per Event. Users pay only for rows successfully delivered to the dataset: `result-scraped` at $0.001 per result, or $1 per 1,000 results. Failed searches, empty locations, retries, and blocked pages do not create billable rows.

Built for lead generation, market research, local SEO audits, sales prospecting, and retail site selection, this scraper is designed for repeatable production use and Apify Store publishing.

### What It Extracts

- Business name
- Address (full street address from the place page when `scrapeDetails` is enabled)
- Phone number (from the place page when `scrapeDetails` is enabled)
- Website
- Category
- Rating
- Reviews count
- Opening hours
- Latitude and longitude
- Google Maps ID
- Plus code (from the place page when `scrapeDetails` is enabled)
- Google Maps URL
- Keyword, location, query, and scrape timestamp

### Worldwide Use

This Actor is not limited to Kolkata, India, the United States, or any single country. It works globally because:

- Search locations are free-form strings, e.g. `Paris, France`, `Sao Paulo, Brazil`, `Shibuya, Tokyo, Japan`, `Dubai Marina, UAE`.
- The built-in `high_demand_markets` preset covers 169 commercial cities where lead-generation, agency, local SEO, sales, and enrichment use cases are most likely to convert into paid runs.
- The built-in `world_major_cities` preset covers 171 big and famous cities across North America, Latin America, Europe, the Middle East, Africa, South Asia, East/Southeast Asia, and Oceania.
- `countryCode` is optional and defaults to no `gl` country bias.
- The proxy country is not forced by default.
- If you set `countryCode`, the Actor also uses that country for proxy targeting unless you explicitly override `proxyConfig.apifyProxyCountry`.

For best accuracy, include the country in each location. For example, use `restaurants in Georgia, USA` or `restaurants Tbilisi, Georgia` instead of only `Georgia`.

### Preset Strategy

- `high_demand_markets`: best default for monetization. Focuses on rich metro areas, agency-heavy cities, startup hubs, GCC markets, English-speaking countries, EU business centers, India metros, and fast-growing APAC/LATAM cities where customers commonly buy lead-generation, local SEO, market research, and enrichment data.
- `world_major_cities`: broader global coverage for users who want famous cities across more regions, including tourism, emerging markets, and general business hubs.
- `none`: use only custom locations when the customer already knows the exact target market.

### Use Cases

1. Lead generation: build prospect lists with phones, websites, addresses, and Maps URLs.
2. Market research: compare competitor density, ratings, and categories by city or region.
3. Local SEO audits: check business presence, category choices, and public NAP data.
4. Sales territory planning: collect potential accounts before launching outreach in a new market.
5. Retail and real estate analysis: identify dense commercial clusters and underserved areas.

### Pricing

This Actor uses Apify Pay Per Event pricing.

| Event name | Price per event | 1,000 results | 10,000 results |
| --- | ---: | ---: | ---: |
| `result-scraped` | $0.001 | $1.00 | $10.00 |

The code charges only after a business record is extracted and before it is pushed to the dataset. If the charge budget is exhausted, the Actor stops gracefully. Dataset writes are retried after charging to reduce the risk of paid rows not being stored.

### Input

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `keywords` | array<string> | yes | none | Business types or search terms. |
| `locations` | array<string> | no | none | Custom cities, regions, postal codes, addresses, or `lat,lon` pairs anywhere in the world. Required only when no preset is selected. |
| `locationPreset` | string | no | `none` | Use `high_demand_markets` for 169 commercial hotspots, `world_major_cities` for broad global coverage, or `none` for custom locations only. Custom locations are added on top. |
| `maxResults` | integer | no | 10 | Maximum saved rows per keyword/location pair. Start small for tests; increase for production. Allowed: 1-5000. |
| `maxCrawledPlacesPerQuery` | integer | no | 20 | Maximum detail pages to inspect per query. Set higher than `maxResults` when many listings may be closed or duplicates. |
| `language` | string | no | `en` | Result language code, e.g. `en`, `de`, `es`, `fr`, `ja`. |
| `countryCode` | string | no | none | Optional 2-letter country bias, e.g. `gb`, `de`, `jp`, `ae`. |
| `skipClosedBusinesses` | boolean | no | `true` | Skip listings marked permanently closed. |
| `scrapeDetails` | boolean | no | `true` | Visit each place page when phone or full address is missing from the list view; also captures the plus code. Disable for faster list-only runs. |
| `proxyConfig` | object | no | Residential Apify proxy | Apify proxy configuration. Leave country empty for global runs. |

The Actor removes duplicate keywords and locations. The keyword/location cartesian product is capped at 1,000 queries to prevent accidental huge runs. With either large preset, up to 5 keywords fit under the 1,000-query cap. For first tests, keep `locationPreset` as `none` and use 1-2 custom locations.

When `scrapeDetails` is enabled (default), the Actor performs an extra navigation to each place's individual Google Maps page whenever the list view did not expose a phone number or full address. Each detail page has a 10-second timeout. If the detail page fails, the Actor keeps the list-view data so no record is dropped.

### Example Inputs

#### High-Demand Markets Batch

```json
{
  "keywords": ["coffee shop"],
  "locationPreset": "high_demand_markets",
  "maxResults": 25,
  "maxCrawledPlacesPerQuery": 50,
  "language": "en",
  "skipClosedBusinesses": true,
  "scrapeDetails": true,
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
````

#### Broad World Cities Batch

```json
{
  "keywords": ["restaurant"],
  "locationPreset": "world_major_cities",
  "maxResults": 25,
  "maxCrawledPlacesPerQuery": 50,
  "language": "en",
  "skipClosedBusinesses": true,
  "scrapeDetails": true
}
```

#### Custom Global Batch

```json
{
  "keywords": ["coffee shop", "coworking space"],
  "locations": ["London, UK", "Berlin, Germany", "Tokyo, Japan", "Dubai, UAE"],
  "maxResults": 50,
  "maxCrawledPlacesPerQuery": 100,
  "language": "en",
  "skipClosedBusinesses": true,
  "scrapeDetails": true,
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

#### Country-Biased Run

```json
{
  "keywords": ["dentist"],
  "locations": ["Manchester", "Birmingham", "Leeds"],
  "maxResults": 200,
  "maxCrawledPlacesPerQuery": 300,
  "language": "en",
  "countryCode": "gb",
  "skipClosedBusinesses": true,
  "scrapeDetails": true
}
```

#### Coordinate Search

```json
{
  "keywords": ["hotel"],
  "locations": ["25.2048,55.2708", "48.8566,2.3522"],
  "maxResults": 100,
  "scrapeDetails": true
}
```

#### Fast List-Only Run

```json
{
  "keywords": ["pizza"],
  "locations": ["New York, USA"],
  "maxResults": 200,
  "scrapeDetails": false
}
```

### Sample Output

```json
{
  "title": "Monmouth Coffee Company",
  "address": "2 Park St, London SE1 9AB, United Kingdom",
  "phone": "+44 20 7232 3010",
  "website": "https://www.monmouthcoffee.co.uk/",
  "category": "Coffee shop",
  "rating": 4.5,
  "reviewsCount": 2584,
  "hours": ["Monday: 7:30 AM - 6:00 PM", "Tuesday: 7:30 AM - 6:00 PM"],
  "latitude": 51.5054,
  "longitude": -0.0911,
  "mapsId": "0x487604a9cddf0001:0x9876543210abcdef",
  "plusCode": "7FJW+XV London, United Kingdom",
  "url": "https://www.google.com/maps/place/Monmouth+Coffee+Company/@51.5054,-0.0911,17z",
  "keyword": "coffee shop",
  "location": "London, UK",
  "query": "coffee shop London, UK",
  "scrapedAt": "2026-06-07T09:30:00.000Z"
}
```

```json
{
  "title": "The Barn Cafe",
  "address": "Auguststrasse 58, 10119 Berlin, Germany",
  "phone": "+49 30 12345678",
  "website": "https://thebarn.de/",
  "category": "Cafe",
  "rating": 4.4,
  "reviewsCount": 1760,
  "hours": ["Monday: 8:00 AM - 6:00 PM", "Tuesday: 8:00 AM - 6:00 PM"],
  "latitude": 52.5281,
  "longitude": 13.4022,
  "mapsId": "0x47a851eb00000001:0xabcdef1234567890",
  "plusCode": "4F4V+82 Berlin, Germany",
  "url": "https://www.google.com/maps/place/The+Barn+Cafe/@52.5281,13.4022,17z",
  "keyword": "coffee shop",
  "location": "Berlin, Germany",
  "query": "coffee shop Berlin, Germany",
  "scrapedAt": "2026-06-07T09:31:00.000Z"
}
```

```json
{
  "title": "Streamer Coffee Company Shibuya",
  "address": "1 Chome-20-28 Shibuya, Shibuya City, Tokyo 150-0002, Japan",
  "phone": "+81 3-6427-3705",
  "website": "https://streamer.coffee/",
  "category": "Coffee shop",
  "rating": 4.3,
  "reviewsCount": 2103,
  "hours": ["Monday: 8:00 AM - 7:00 PM", "Tuesday: 8:00 AM - 7:00 PM"],
  "latitude": 35.6614,
  "longitude": 139.7040,
  "mapsId": "0x60188ca900000001:0x1234567890abcdef",
  "plusCode": "8Q7X+4F Shibuya City, Tokyo, Japan",
  "url": "https://www.google.com/maps/place/Streamer+Coffee+Company+Shibuya/@35.6614,139.7040,17z",
  "keyword": "coffee shop",
  "location": "Tokyo, Japan",
  "query": "coffee shop Tokyo, Japan",
  "scrapedAt": "2026-06-07T09:32:00.000Z"
}
```

### API Example

```bash
curl -X POST "https://api.apify.com/v2/acts/YOUR_ACTOR_ID/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["restaurant", "dentist"],
    "locations": ["Dubai, UAE", "Toronto, Canada", "Singapore"],
    "maxResults": 150,
    "language": "en"
  }'
```

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('YOUR_ACTOR_ID').start({
    keywords: ['restaurant', 'dentist'],
    locations: ['Dubai, UAE', 'Toronto, Canada', 'Singapore'],
    maxResults: 150,
    language: 'en',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} businesses`);
```

### How It Works

1. Validates input with clear errors.
2. Builds one Google Maps search URL per keyword/location pair.
3. Adds `hl` language and optional `gl` country bias only when provided.
4. Runs Playwright through Apify residential proxies and Crawlee sessions.
5. Scrolls Google Maps results until enough places are loaded or the feed ends.
6. Opens each listing detail panel and extracts business data.
7. If `scrapeDetails` is enabled and phone or address is still missing, visits the place's individual Google Maps page with a 10-second timeout to retrieve phone, full address, and plus code.
8. Deduplicates records by Maps ID and title.
9. Charges `result-scraped` and writes records to the Apify Dataset.

### Anti-Bot Handling

- Apify residential proxy support.
- Optional country-matched proxy targeting.
- Session pool with limited usage per session.
- Randomized scroll, click, and extraction delays.
- Retry support for transient blocks and navigation failures.
- Graceful field-level fallback to `null` when optional data is unavailable.

### Project Structure

```text
google-maps-scraper/
  .actor/
    actor.json
    Dockerfile
  src/
    main.ts
    routes.ts
    types.ts
  INPUT_SCHEMA.json
  input.json
  package.json
  package-lock.json
  README.md
  tsconfig.json
```

### Local Development

```bash
npm ci
npm run build
npx playwright install chromium
npm start
```

For Apify local runs, put your input in `storage/key_value_stores/default/INPUT.json` or use the included `input.json` as a starting point.

### Suggested Next Updates

- Add live smoke-test fixtures for 3 countries before each release.
- Add optional review scraping as a separate PPE event, e.g. `review-scraped`.
- Add an `includeEmailsFromWebsite` option that visits business websites and extracts public emails.
- Add region presets such as North America, Europe, GCC, APAC, and LATAM.
- Add a per-query summary dataset or key-value output for marketplace-quality reporting.

### Known Limits

- With `scrapeDetails: true` (default), keep `maxCrawledPlacesPerQuery` at 200 or below. Larger values combined with detail-page enrichment can exceed the per-query request handler timeout of 3600 seconds and cause the query to be retried by Crawlee.
- The per-run timeout is 12 hours (`timeoutSecs: 43200` in `.actor/actor.json`). This supports up to ~70 queries with detail scraping enabled, ~100 queries for list-only runs (`scrapeDetails: false`) at typical speed (3-5 seconds per record without detail scraping, 5-8 seconds with detail scraping when phone or full address is missing).
- Detail-page enrichment only fires when phone or full address is missing from the list view, so runs against well-structured queries where the list view already exposes the phone will not pay the extra navigation cost.
- Duplicate detection is based on `mapsId` (or title when `mapsId` is unavailable). Two chain stores with the same business name but different `mapsId` are kept as separate records.

### Legal And Ethical Use

Use this Actor for legitimate business intelligence, lead generation, local SEO, and market research. You are responsible for complying with Google Maps terms, privacy laws, anti-spam rules, GDPR, CAN-SPAM, and local outreach regulations in every country where you use the data.

### License

Apache-2.0. See `LICENSE`.

# Actor input Schema

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

One or more business types or search terms. Each keyword is combined with each location worldwide.

## `locations` (type: `array`):

Optional custom cities, regions, postal codes, addresses, or 'lat,lon' pairs. Include the country for best accuracy, e.g. 'Paris, France' or 'Tokyo, Japan'. You can also use a preset below.

## `locationPreset` (type: `string`):

Optional city preset. Choose 'High-demand commercial markets' for the strongest lead-generation geographies, or 'World major cities' for broad global coverage. Custom locations are added on top.

## `maxResults` (type: `integer`):

Maximum number of businesses to save per keyword/location combination. Start small for tests; increase to 100-5000 for production runs.

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

Two-letter language code for result text, e.g. 'en', 'es', 'de', 'fr', 'ja'.

## `countryCode` (type: `string`):

Optional two-letter country code that biases Google Maps results and proxy country, e.g. 'us', 'gb', 'de', 'jp'. Leave empty for worldwide searches based only on the location text.

## `maxCrawledPlacesPerQuery` (type: `integer`):

Hard cap on detail pages the Actor opens per keyword/location. Set higher than maxResults when many listings may be duplicates, closed, or missing details.

## `skipClosedBusinesses` (type: `boolean`):

If true, businesses marked as 'Permanently closed' are filtered out.

## `scrapeDetails` (type: `boolean`):

If true, when the list view does not include a phone number or full address, the Actor visits the place's individual page to retrieve them along with the plus code. Disable for faster runs when phone and full address are not required.

## `proxyConfig` (type: `object`):

Apify proxy configuration. Residential is strongly recommended for Google Maps. Leave proxy country empty for global runs, or set it to match the target country.

## Actor input object example

```json
{
  "keywords": [
    "restaurant",
    "coffee shop",
    "dentist",
    "real estate agent",
    "auto repair"
  ],
  "locations": [
    "New York, USA",
    "London, UK",
    "Tokyo, Japan",
    "Dubai, UAE",
    "48.8566,2.3522"
  ],
  "locationPreset": "none",
  "maxResults": 10,
  "language": "en",
  "countryCode": "gb",
  "maxCrawledPlacesPerQuery": 20,
  "skipClosedBusinesses": true,
  "scrapeDetails": true,
  "proxyConfig": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "keywords": [
        "restaurant"
    ],
    "locations": [
        "London, UK"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fascinating_lentil/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 = {
    "keywords": ["restaurant"],
    "locations": ["London, UK"],
}

# Run the Actor and wait for it to finish
run = client.actor("fascinating_lentil/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 '{
  "keywords": [
    "restaurant"
  ],
  "locations": [
    "London, UK"
  ]
}' |
apify call fascinating_lentil/google-maps-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps Scraper — Extract Business Data at Scale",
        "description": "Scrape Google Maps for business leads — extract name, address, phone, website, rating, reviews, hours, category, and coordinates. Residential proxies included. Pay per result. Export to CSV, JSON, or Excel.",
        "version": "1.0",
        "x-build-id": "uftrf0OjNA7w6CEKk"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fascinating_lentil~google-maps-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fascinating_lentil-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/fascinating_lentil~google-maps-scraper/runs": {
            "post": {
                "operationId": "runs-sync-fascinating_lentil-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/fascinating_lentil~google-maps-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-fascinating_lentil-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": [
                    "keywords"
                ],
                "properties": {
                    "keywords": {
                        "title": "Search keywords",
                        "minItems": 1,
                        "type": "array",
                        "description": "One or more business types or search terms. Each keyword is combined with each location worldwide.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "locations": {
                        "title": "Custom worldwide locations",
                        "minItems": 1,
                        "type": "array",
                        "description": "Optional custom cities, regions, postal codes, addresses, or 'lat,lon' pairs. Include the country for best accuracy, e.g. 'Paris, France' or 'Tokyo, Japan'. You can also use a preset below.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "locationPreset": {
                        "title": "Location preset",
                        "enum": [
                            "none",
                            "high_demand_markets",
                            "world_major_cities"
                        ],
                        "type": "string",
                        "description": "Optional city preset. Choose 'High-demand commercial markets' for the strongest lead-generation geographies, or 'World major cities' for broad global coverage. Custom locations are added on top.",
                        "default": "none"
                    },
                    "maxResults": {
                        "title": "Max results per query",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Maximum number of businesses to save per keyword/location combination. Start small for tests; increase to 100-5000 for production runs.",
                        "default": 10
                    },
                    "language": {
                        "title": "Result language",
                        "pattern": "^[a-zA-Z]{2,5}$",
                        "minLength": 2,
                        "maxLength": 5,
                        "type": "string",
                        "description": "Two-letter language code for result text, e.g. 'en', 'es', 'de', 'fr', 'ja'.",
                        "default": "en"
                    },
                    "countryCode": {
                        "title": "Optional country bias",
                        "pattern": "^[a-zA-Z]{2}$",
                        "minLength": 2,
                        "maxLength": 2,
                        "type": "string",
                        "description": "Optional two-letter country code that biases Google Maps results and proxy country, e.g. 'us', 'gb', 'de', 'jp'. Leave empty for worldwide searches based only on the location text."
                    },
                    "maxCrawledPlacesPerQuery": {
                        "title": "Max places to visit per query",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Hard cap on detail pages the Actor opens per keyword/location. Set higher than maxResults when many listings may be duplicates, closed, or missing details.",
                        "default": 20
                    },
                    "skipClosedBusinesses": {
                        "title": "Skip permanently closed businesses",
                        "type": "boolean",
                        "description": "If true, businesses marked as 'Permanently closed' are filtered out.",
                        "default": true
                    },
                    "scrapeDetails": {
                        "title": "Visit each place page for phone + full address",
                        "type": "boolean",
                        "description": "If true, when the list view does not include a phone number or full address, the Actor visits the place's individual page to retrieve them along with the plus code. Disable for faster runs when phone and full address are not required.",
                        "default": true
                    },
                    "proxyConfig": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Apify proxy configuration. Residential is strongly recommended for Google Maps. Leave proxy country empty for global runs, or set it to match the target country.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ]
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
