# Google Maps Scraper — Emails, Reviews, Leads & Photos (`sian.agency/local-business-data-scraper`) Actor

Scrape Google Maps into clean datasets: business listings with emails, phone numbers and social links, plus reviews, photos, owner posts and AI review keywords. 12 operations — search, search-in-area, nearby, details, reviews, photos, posts, autocomplete. Pay per result.

- **URL**: https://apify.com/sian.agency/local-business-data-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Lead generation, Business, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 business search results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

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

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

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

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

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

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

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

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

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

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


# README

## Google Maps Scraper — Emails, Reviews, Leads & Photos 🗺️

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Property Skip Tracing](https://img.shields.io/badge/Store-Property%20Skip%20Tracing-1AE392)](https://apify.com/sian.agency/property-skip-tracing?fpr=sian) [![Uber Eats Menu Scraper](https://img.shields.io/badge/Store-Uber%20Eats%20Menu%20Scraper-06C167)](https://apify.com/sian.agency/uber-eats-menu-scraper?fpr=sian) [![Instagram AI Transcript](https://img.shields.io/badge/Store-Instagram%20AI%20Transcript-E4405F)](https://apify.com/sian.agency/instagram-ai-transcript-extractor?fpr=sian)

#### 🎉 The only all-in-one Google Maps scraper — listings **with emails, social links, reviews, photos AND owner posts** in one run
##### For lead-gen teams, agencies and local-SEO marketers who are tired of stitching three scrapers together

---

### 📋 Overview

**Scrape Google Maps the complete way** — pull business listings already enriched with emails, phone numbers and a full social graph, then drill into reviews, photos, owner posts and AI review keywords from the same actor.

**Why thousands of professionals choose us:**
- ✅ **All-in-one, 12 operations**: search, search-in-area, nearby, details, reviews, photos, posts, review/photo details, reverse-geocoding and autocomplete — one actor, one dataset.
- ⚡ **Emails & contacts inline**: every search row can carry `emails`, `phoneNumbers` and 11 social links (Facebook, Instagram, LinkedIn, Twitter/X, YouTube, TikTok, Snapchat, Pinterest, GitHub, Yelp) — no second email-extractor needed.
- 🎯 **Up to 500 businesses per search** with clean camelCase JSON — addresses, coordinates, hours, ratings, price level, verified status and more.
- 💰 **Pay-per-result pricing**: only charged for rows you actually receive, with a generous FREE tier and bulk per-row pricing that undercuts the market.
- 💎 **AI review keywords (exclusive)**: Business Details Plus returns `keywordsMentionedInReviews` — the sentiment topics surfaced across a business's reviews. No competitor ships this column.
- ✨ **Owner posts**: the "From the owner" section most Maps scrapers drop entirely.

---

### ✨ Features

- 🔍 **Multi-mode search**: by keyword + location, inside a map viewport, or around a coordinate point.
- 📧 **Email & social extraction**: turn Maps listings into Apollo-style B2B leads with one toggle.
- ⭐ **Full review history**: paginate every review with rating, owner replies, photos and reviews-per-star breakdown.
- 🖼️ **Photo gallery mining**: pull business photos with captions and uploader details.
- 📣 **Owner posts**: capture announcements, offers and updates businesses publish on Maps.
- 🧠 **AI keywords in reviews**: see what customers mention most — surfaced as structured keyword + count pairs.
- 🧭 **Reverse geocoding & autocomplete**: "What's here?" lookups and place predictions — free utilities.
- 🌍 **Region & language control**: localize results with ISO region and language codes.

---

### 🎬 Quick Start

Pick an operation, give it a query or a Business ID, and run. Search returns up to 500 businesses with contacts; the enrich operations drill into any business by its ID.

```bash
curl -X POST https://api.apify.com/v2/acts/sian.agency~local-business-data-scraper/runs?token=YOUR_TOKEN \
-H 'Content-Type: application/json' \
-d '{"operation": "search", "query": "restaurants in Austin", "limit": 20, "extractEmailsAndContacts": true}'
````

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Choose an operation

Start with **Search** to find businesses by keyword + location.

#### Step 2: Set your inputs

Add your `query` and `limit` (up to 500), and keep **Extract emails & contacts** on for lead data.

#### Step 3: Run and collect

Run the actor and export the dataset. Copy any `businessId` to drill into **Reviews**, **Photos**, **Details Plus** or **Posts**.

**That's it! In under a minute, you'll have:**

- A clean list of businesses with emails, phones and social links
- Ratings, addresses, coordinates and hours
- The `businessId` values to enrich any place further

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | string | Yes | Which mode to run (search, businessDetails, businessReviews, …) |
| query | string | For search ops | What you'd type into the Maps search box |
| extractEmailsAndContacts | boolean | No | Include emails + social links on search/details rows (default: on) |
| limit | integer | No | Businesses per search, 1–500 (default: 20) |
| lat / lng | string | For area / nearby / reverse-geo | Center coordinates |
| zoom | string | For search-in-area | Map zoom level (3–21) |
| businessId | string | For enrich ops | Business ID from a search row (batch up to 20 for details/photo-details) |
| sortBy | string | No | Review order: most\_relevant / newest / highest\_ranking / lowest\_ranking |
| region / language | string | No | ISO region (`us`) and language (`en`) codes |
| maxPages | integer | No | Pages for paginated reviews/photos/posts (1–20) |

**Example — search with contacts:**

```json
{
  "operation": "search",
  "query": "dentist in Chicago",
  "limit": 100,
  "extractEmailsAndContacts": true,
  "region": "us"
}
```

**Example — AI review keywords:**

```json
{
  "operation": "businessDetailsPlus",
  "businessId": "0x808fba02425dad8f:0x6c296c66619367e0"
}
```

***

### 📤 Output

Results are saved to the Apify dataset with **60+ fields** including:

| Field | Type | Description |
|-------|------|-------------|
| name | string | Business name |
| fullAddress | string | Complete formatted address |
| phoneNumber | string | Primary phone |
| rating / reviewCount | number | Star rating and total reviews |
| website | string | Business website |
| emails | array | Emails extracted from the website |
| facebook / instagram / linkedin / … | string | Social profile links |
| keywordsMentionedInReviews | array | AI keyword + count pairs (Details Plus) |
| reviewText / reviewRating / authorName | mixed | Per-review fields (Reviews ops) |
| photoUrl / caption / photoOwnerName | mixed | Per-photo fields (Photos ops) |
| businessId | string | Use this to enrich the place further |

**Example row:**

```json
{
  "name": "Mozart's Coffee Roasters",
  "fullAddress": "3825 Lake Austin Blvd, Austin, TX 78703",
  "phoneNumber": "+15124772900",
  "website": "https://mozartscoffee.com",
  "emails": ["info@mozartscoffee.com"],
  "facebook": "https://www.facebook.com/MozartsCoffeeRoasters",
  "rating": 4.5,
  "reviewCount": 10648,
  "businessId": "0x8644b5554461664d:0xbc4ff333ec9ad1ad",
  "status": "success"
}
```

***

### 💼 Use Cases & Examples

#### 1. B2B Lead Generation with Emails

**Sales teams building outreach lists without a second email-extractor.**

**Input:** `search` + a category and city + emails toggle on
**Output:** Businesses with emails, phones and social links
**Use:** Import straight into your CRM or cold-email tool.

#### 2. Local SEO & Reputation Monitoring

**Agencies tracking client review sentiment over time.**

**Input:** `businessReviews` or `businessDetailsPlus` by Business ID
**Output:** Full review history + AI keyword themes
**Use:** Benchmark competitors and report on reputation trends.

#### 3. Map Data & Place Intelligence

**Analysts mapping competitive density in a metro.**

**Input:** `searchInArea` across neighbourhoods
**Output:** Coordinates, hours, price level, verified status
**Use:** Power store-locator apps and territory planning.

#### 4. Review & Photo Mining

**Researchers studying customer sentiment and UGC.**

**Input:** `businessReviews` + `businessPhotos`
**Output:** Review text with ratings + photo gallery with captions
**Use:** Feed sentiment models and surface user imagery.

#### 5. Sales Territory & Outreach Lists

**Field-sales managers routing reps by area.**

**Input:** `searchNearby` around target coordinates
**Output:** Deduped business list with contact details
**Use:** Build geo-segmented prospecting lists.

***

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/local-business-data-scraper').call({
  operation: 'search',
  query: 'restaurants in Austin',
  limit: 50,
  extractEmailsAndContacts: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/local-business-data-scraper').call(
    run_input={'operation': 'search', 'query': 'restaurants in Austin', 'limit': 50}
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~local-business-data-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"operation": "search", "query": "restaurants in Austin"}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: Schedule or webhook
2. **HTTP Request**: Call the actor API
3. **Process**: Handle the JSON results
4. **Action**: Save to CRM, notify, or enrich

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- Real businesses with emails and contacts per run — full feature access, same quality
- No credit card required
- Perfect for testing and small lead lists

#### PAID Tier (Production Ready)

- **Unlimited** businesses, reviews, photos and posts per run
- Fast, deduped results straight from Maps
- Pay-per-result: only charged for rows you actually receive

💰 **Bulk per-row pricing that undercuts the market** — richer rows than the "$1/1k leads" tools, because every row can carry reviews-per-rating, a photos sample, owner posts and a full social graph.

🔗 [View current pricing](https://apify.com/sian.agency/local-business-data-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: How many businesses can I get per run?**
A: Up to 500 per search call. Reviews, photos and posts paginate up to 20 pages.

**Q: Where do the emails come from?**
A: When **Extract emails & contacts** is on, the website behind each listing is parsed for emails, phone numbers and social links.

**Q: What are AI review keywords?**
A: Business Details Plus returns the keywords most frequently mentioned across a business's reviews, each with a count — a fast read on what customers care about.

**Q: What output formats are available?**
A: JSON, CSV, Excel — export directly from the Apify dataset.

**Q: Does it work with any country?**
A: Yes — set `region` and `language` to localize results (e.g. `gb`/`en`, `de`/`de`).

**Q: Is this legal?**
A: We only extract publicly available business information. See the legal section below.

***

### 🐛 Troubleshooting

**Search returns no emails**

- Make sure **Extract emails & contacts** is enabled.
- Some businesses have no website, so no contacts can be parsed.

**An enrich operation returns a "paid plan required" notice**

- Business details, reviews, photos and posts are paid features — upgrade to unlock them.

**A Business ID is "not found"**

- IDs change if a listing is removed or merged. Re-run Search to get a fresh ID.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as personal email addresses, gender, or location of individuals. They only extract what businesses and users have chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

***

### ⚠️ Trademark Disclaimer

Google Maps™ and Google™ are trademarks of Google LLC. This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Google LLC**. It accesses only publicly available business information. All product names, logos, and brands are property of their respective owners and are used for identification purposes only.

***

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue in the actor's Console Issues tab
- Check the [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `operation` (type: `string`):

🎯 **PICK ONE OPERATION PER RUN.** Each run produces one clean dataset matching the chosen mode.

**🔍 Find businesses**

- **Search** — search Google Maps by keyword + location (emails & contacts on by default)
- **Search In Area** — search inside a map viewport (center lat/lng + zoom)
- **Search Nearby** — search around a specific coordinate point

**🏢 Enrich a business** (Business ID from a search row)

- **Business Details** — full details + emails & social contacts (batch up to 20 IDs)
- **Business Details Plus** — details + AI keywords mentioned in reviews ✨
- **Business Reviews** — paginate all reviews with ratings & owner replies
- **Review Details** — one review by author ID
- **Business Photos** — paginate the photo gallery
- **Photo Details** — caption + uploader for a photo (batch up to 20)
- **Business Posts** — owner posts ("From the owner")

**🛠️ Utilities** (free)

- **Reverse Geocoding** — "What's here?" by lat/lng
- **Autocomplete** — place / query predictions

💡 **TIP:** Run Search first to collect Business IDs, then drill into Details / Reviews / Photos.

## `query` (type: `string`):

🔍 **Required for Search / Search In Area / Search Nearby / Autocomplete.**

What you would type into the Google Maps search box.

- `restaurants in Austin`
- `dentist`
- `coffee shop near times square`

💡 **TIP:** For Search In Area / Nearby, keep the keyword broad (e.g. `dentist`) and let the coordinates scope the area.

⚠️ **Ignored** for the enrich / utility operations.

## `extractEmailsAndContacts` (type: `boolean`):

📧 **The lead-gen wedge.** When enabled (default), Search and Business Details rows include `emails`, `phoneNumbers` and a full social graph (Facebook, Instagram, LinkedIn, Twitter, YouTube, TikTok, Snapchat, Pinterest, GitHub, Yelp) extracted from each business website.

💡 Turn OFF for faster, listings-only runs when you don't need contacts.

## `limit` (type: `integer`):

🔢 **Search / Search In Area / Search Nearby only.** How many businesses to return in one run (1–500). Each search is a single upstream request that returns up to this many rows.

💡 **TIP:** Start with 20 to preview, then scale up to 500 for full sweeps.

## `lat` (type: `string`):

🧭 **Required for Search In Area, Search Nearby and Reverse Geocoding.** Center latitude.

- Example: `30.2672` (Austin)

Also used as a soft location bias for Search.

## `lng` (type: `string`):

🧭 **Required for Search In Area, Search Nearby and Reverse Geocoding.** Center longitude.

- Example: `-97.7431` (Austin)

## `zoom` (type: `string`):

🔍 **Required for Search In Area** (3–21). Higher = tighter area. Maps default ≈ `13`.

## `businessId` (type: `string`):

🏢 **Required for Business Details, Business Details Plus, Business Reviews, Review Details, Business Photos, Photo Details, Business Posts.**

The `businessId` from a Search result row (e.g. `0x89b7c63b3f02adc5:0x3f...`).

💡 **Batch:** Business Details, Business Details Plus and Photo Details accept up to 20 comma-separated IDs in one run.

⚠️ **Ignored** for Search and Autocomplete.

## `reviewAuthorId` (type: `string`):

🔎 **Required for Review Details.** The `authorId` from a Business Reviews row, combined with `businessId`, returns one review's full detail.

⚠️ **Ignored** for all other operations.

## `photoId` (type: `string`):

🖼️ **Required for Photo Details.** The `photoId` from a Business Photos row. Accepts up to 20 comma-separated IDs.

⚠️ **Ignored** for all other operations.

## `sortBy` (type: `string`):

↕️ **Business Reviews only.** Order of returned reviews.

## `reviewsQuery` (type: `string`):

🔤 **Business Reviews only.** Optional keyword to filter reviews (e.g. `parking`, `staff`). Leave blank to return all reviews.

## `translateReviews` (type: `boolean`):

🌐 **Business Reviews only.** Translate non-English review text into the requested language.

## `isVideo` (type: `boolean`):

🎬 **Business Photos only.** Return only video media instead of photos.

## `region` (type: `string`):

🌍 ISO 3166-1 alpha-2 region code (e.g. `us`, `gb`, `ca`, `de`, `au`). Default `us`.

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

🗣️ ISO 639-1 language code for results (e.g. `en`, `es`, `de`, `fr`). Default `en`.

## `maxPages` (type: `integer`):

📄 **Applies to Business Reviews, Business Photos and Business Posts** (the paginated enrich ops). Reviews ~10/page, photos ~20/page.

💡 **TIP:** Start small (1–3) to preview. Pagination stops automatically when Google Maps reports no more results.

⚠️ Hard cap: 20 pages to prevent runaway runs. Ignored for Search (use `limit`) and single-record operations.

## Actor input object example

```json
{
  "operation": "search",
  "query": "restaurants in Austin",
  "extractEmailsAndContacts": true,
  "limit": 20,
  "lat": "30.2672",
  "lng": "-97.7431",
  "zoom": "13",
  "businessId": "0x808fba02425dad8f:0x6c296c66619367e0",
  "sortBy": "most_relevant",
  "translateReviews": false,
  "isVideo": false,
  "region": "us",
  "language": "en",
  "maxPages": 3
}
```

# Actor output Schema

## `output` (type: `string`):

Per-row results — one flat camelCase row per business, review, photo, owner post or prediction (name, fullAddress, phoneNumber, emails, facebook, instagram, linkedin, rating, reviewCount, keywordsMentionedInReviews, …).

## `report` (type: `string`):

HTML report with run status, success/error row counts, success rate, pages fetched, duration, and the inputs used — written even on fatal crash.

# 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 = {
    "query": "restaurants in Austin",
    "lat": "30.2672",
    "lng": "-97.7431",
    "zoom": "13",
    "businessId": "",
    "reviewAuthorId": "",
    "photoId": "",
    "reviewsQuery": "",
    "region": "us",
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/local-business-data-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 = {
    "query": "restaurants in Austin",
    "lat": "30.2672",
    "lng": "-97.7431",
    "zoom": "13",
    "businessId": "",
    "reviewAuthorId": "",
    "photoId": "",
    "reviewsQuery": "",
    "region": "us",
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/local-business-data-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 '{
  "query": "restaurants in Austin",
  "lat": "30.2672",
  "lng": "-97.7431",
  "zoom": "13",
  "businessId": "",
  "reviewAuthorId": "",
  "photoId": "",
  "reviewsQuery": "",
  "region": "us",
  "language": "en"
}' |
apify call sian.agency/local-business-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sian.agency/local-business-data-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps Scraper — Emails, Reviews, Leads & Photos",
        "description": "Scrape Google Maps into clean datasets: business listings with emails, phone numbers and social links, plus reviews, photos, owner posts and AI review keywords. 12 operations — search, search-in-area, nearby, details, reviews, photos, posts, autocomplete. Pay per result.",
        "version": "1.0",
        "x-build-id": "eeZ1ENW0S4jH7Unce"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~local-business-data-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-local-business-data-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/sian.agency~local-business-data-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-local-business-data-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/sian.agency~local-business-data-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-local-business-data-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": [
                    "operation"
                ],
                "properties": {
                    "operation": {
                        "title": "🎯 Operation — what do you want to scrape?",
                        "enum": [
                            "search",
                            "searchInArea",
                            "searchNearby",
                            "businessDetails",
                            "businessDetailsPlus",
                            "businessReviews",
                            "reviewDetails",
                            "businessPhotos",
                            "photoDetails",
                            "businessPosts",
                            "reverseGeocoding",
                            "autocomplete"
                        ],
                        "type": "string",
                        "description": "🎯 **PICK ONE OPERATION PER RUN.** Each run produces one clean dataset matching the chosen mode.\n\n**🔍 Find businesses**\n- **Search** — search Google Maps by keyword + location (emails & contacts on by default)\n- **Search In Area** — search inside a map viewport (center lat/lng + zoom)\n- **Search Nearby** — search around a specific coordinate point\n\n**🏢 Enrich a business** (Business ID from a search row)\n- **Business Details** — full details + emails & social contacts (batch up to 20 IDs)\n- **Business Details Plus** — details + AI keywords mentioned in reviews ✨\n- **Business Reviews** — paginate all reviews with ratings & owner replies\n- **Review Details** — one review by author ID\n- **Business Photos** — paginate the photo gallery\n- **Photo Details** — caption + uploader for a photo (batch up to 20)\n- **Business Posts** — owner posts (\"From the owner\")\n\n**🛠️ Utilities** (free)\n- **Reverse Geocoding** — \"What's here?\" by lat/lng\n- **Autocomplete** — place / query predictions\n\n💡 **TIP:** Run Search first to collect Business IDs, then drill into Details / Reviews / Photos.",
                        "default": "search"
                    },
                    "query": {
                        "title": "🔍 Search Query",
                        "type": "string",
                        "description": "🔍 **Required for Search / Search In Area / Search Nearby / Autocomplete.**\n\nWhat you would type into the Google Maps search box.\n- `restaurants in Austin`\n- `dentist`\n- `coffee shop near times square`\n\n💡 **TIP:** For Search In Area / Nearby, keep the keyword broad (e.g. `dentist`) and let the coordinates scope the area.\n\n⚠️ **Ignored** for the enrich / utility operations."
                    },
                    "extractEmailsAndContacts": {
                        "title": "📧 Extract emails & contacts",
                        "type": "boolean",
                        "description": "📧 **The lead-gen wedge.** When enabled (default), Search and Business Details rows include `emails`, `phoneNumbers` and a full social graph (Facebook, Instagram, LinkedIn, Twitter, YouTube, TikTok, Snapchat, Pinterest, GitHub, Yelp) extracted from each business website.\n\n💡 Turn OFF for faster, listings-only runs when you don't need contacts.",
                        "default": true
                    },
                    "limit": {
                        "title": "🔢 Max businesses (Search)",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "🔢 **Search / Search In Area / Search Nearby only.** How many businesses to return in one run (1–500). Each search is a single upstream request that returns up to this many rows.\n\n💡 **TIP:** Start with 20 to preview, then scale up to 500 for full sweeps.",
                        "default": 20
                    },
                    "lat": {
                        "title": "🧭 Latitude",
                        "type": "string",
                        "description": "🧭 **Required for Search In Area, Search Nearby and Reverse Geocoding.** Center latitude.\n- Example: `30.2672` (Austin)\n\nAlso used as a soft location bias for Search."
                    },
                    "lng": {
                        "title": "🧭 Longitude",
                        "type": "string",
                        "description": "🧭 **Required for Search In Area, Search Nearby and Reverse Geocoding.** Center longitude.\n- Example: `-97.7431` (Austin)"
                    },
                    "zoom": {
                        "title": "🔍 Zoom level (Search In Area)",
                        "type": "string",
                        "description": "🔍 **Required for Search In Area** (3–21). Higher = tighter area. Maps default ≈ `13`."
                    },
                    "businessId": {
                        "title": "🏢 Business ID",
                        "type": "string",
                        "description": "🏢 **Required for Business Details, Business Details Plus, Business Reviews, Review Details, Business Photos, Photo Details, Business Posts.**\n\nThe `businessId` from a Search result row (e.g. `0x89b7c63b3f02adc5:0x3f...`).\n\n💡 **Batch:** Business Details, Business Details Plus and Photo Details accept up to 20 comma-separated IDs in one run.\n\n⚠️ **Ignored** for Search and Autocomplete."
                    },
                    "reviewAuthorId": {
                        "title": "🔎 Review Author ID (Review Details)",
                        "type": "string",
                        "description": "🔎 **Required for Review Details.** The `authorId` from a Business Reviews row, combined with `businessId`, returns one review's full detail.\n\n⚠️ **Ignored** for all other operations."
                    },
                    "photoId": {
                        "title": "🖼️ Photo ID (Photo Details)",
                        "type": "string",
                        "description": "🖼️ **Required for Photo Details.** The `photoId` from a Business Photos row. Accepts up to 20 comma-separated IDs.\n\n⚠️ **Ignored** for all other operations."
                    },
                    "sortBy": {
                        "title": "↕️ Sort reviews by",
                        "enum": [
                            "most_relevant",
                            "newest",
                            "highest_ranking",
                            "lowest_ranking"
                        ],
                        "type": "string",
                        "description": "↕️ **Business Reviews only.** Order of returned reviews.",
                        "default": "most_relevant"
                    },
                    "reviewsQuery": {
                        "title": "🔤 Filter reviews by keyword (Business Reviews)",
                        "type": "string",
                        "description": "🔤 **Business Reviews only.** Optional keyword to filter reviews (e.g. `parking`, `staff`). Leave blank to return all reviews."
                    },
                    "translateReviews": {
                        "title": "🌐 Translate reviews (Business Reviews)",
                        "type": "boolean",
                        "description": "🌐 **Business Reviews only.** Translate non-English review text into the requested language.",
                        "default": false
                    },
                    "isVideo": {
                        "title": "🎬 Videos only (Business Photos)",
                        "type": "boolean",
                        "description": "🎬 **Business Photos only.** Return only video media instead of photos.",
                        "default": false
                    },
                    "region": {
                        "title": "🌍 Region",
                        "type": "string",
                        "description": "🌍 ISO 3166-1 alpha-2 region code (e.g. `us`, `gb`, `ca`, `de`, `au`). Default `us`."
                    },
                    "language": {
                        "title": "🗣️ Language",
                        "type": "string",
                        "description": "🗣️ ISO 639-1 language code for results (e.g. `en`, `es`, `de`, `fr`). Default `en`."
                    },
                    "maxPages": {
                        "title": "📄 Max pages to fetch",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "📄 **Applies to Business Reviews, Business Photos and Business Posts** (the paginated enrich ops). Reviews ~10/page, photos ~20/page.\n\n💡 **TIP:** Start small (1–3) to preview. Pagination stops automatically when Google Maps reports no more results.\n\n⚠️ Hard cap: 20 pages to prevent runaway runs. Ignored for Search (use `limit`) and single-record operations.",
                        "default": 3
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
