# Google Maps Photos Scraper | Categorized by Menu, Food, Vibe (`solidcode/google-maps-photos-scraper`) Actor

\[💰 $0.5 / 1K] Extract every photo for any Google Maps place — categorized exactly like the Maps website (Menu, Food & drink, Vibe, By owner, and more). Perfect companion to the Google Maps Scraper: paste place URLs, get a complete categorized photo library per place.

- **URL**: https://apify.com/solidcode/google-maps-photos-scraper.md
- **Developed by:** [SolidCode](https://apify.com/solidcode) (community)
- **Categories:** Automation, Developer tools, Travel
- **Stats:** 10 total users, 6 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.50 / 1,000 photos

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 Photos Scraper

Extract **every photo** for any Google Maps place — categorized exactly like the Maps website (Menu, Food & drink, Vibe, By owner, Street View & 360°, Videos, and more). The perfect companion to the [Google Maps Scraper](https://apify.com/solidcode/google-maps-scraper-2-5-per-1-000-results): paste a list of place URLs, get a complete, categorized photo library for each one.

### Why This Scraper?

- **Exhaustive photo coverage** — thousands of photos per place when available, not the random handful most scrapers return. A single popular restaurant can yield 5,000+ photos across every category tab.
- **Google's own category labels** — every photo is tagged `Menu`, `Food & drink`, `Vibe`, `By owner`, `Latest`, `Inside`, `Videos`, or `Street View & 360°` — the exact tabs you see on maps.google.com.
- **Filter by category to cut cost** — only need menu photos for a food-delivery catalog? Pick "Menu" and skip everything else for faster, cheaper runs.
- **Pick your image resolution** — thumbnail, medium, large, or original. One input controls every returned URL.
- **Owner vs. user uploads detected** — each photo carries an `uploadedByOwner` flag so you can separate the business's official shots from customer photos.
- **Per-photo metadata** — image URL, dimensions, upload date, and Google's unique photo ID for deduplication.
- **One record per place** — photos arrive bundled with their place, so joining back to your [Google Maps Scraper](https://apify.com/solidcode/google-maps-scraper-2-5-per-1-000-results) output is a simple merge on place ID or URL.
- **Works at scale** — designed for runs with hundreds of thousands of photos at $0.50 per 1,000 images.

### Use Cases

**Menu Digitization & Food Delivery**
- Pull menu photos for every restaurant in a city to build or enrich a delivery catalog
- OCR menu images into structured dish/price data
- Spot restaurants with outdated or missing menu photos for outreach

**Real Estate & Hospitality**
- Collect interior, exterior, and ambience photos for every hotel, café, or venue in an area
- Compare visual branding across competitors at a glance
- Enrich property or listing databases with authentic location imagery

**Brand Monitoring & Competitive Intelligence**
- Track every image customers and owners post about a brand's locations
- Audit visual presentation consistency across a chain's franchises
- Separate owner-approved photos from user-submitted ones for analysis

**Training Data & Machine Learning**
- Build large, labeled image datasets grouped by place category and photo type
- Collect food imagery tagged by cuisine for ML classifiers
- Pull interior/exterior shots for architectural or streetview models

**Content & Marketing**
- Source location photos for travel guides, blogs, or city directories
- Populate landing pages with fresh Google Maps imagery
- Build photo galleries for aggregator or review sites

### Getting Started

#### Accepted Place URL Formats

The actor needs a URL (or ID) that uniquely identifies a place. Any of these work:

- **Full Google Maps URL from your browser address bar** — after clicking the place pin. The URL must contain a `!1s0x…:0x…` segment (Google's internal place identifier). See the examples below.
- **Share link (shortlink)** — tap the **Share** button on maps.google.com or the mobile app; you get a `maps.app.goo.gl/…` or `goo.gl/maps/…` URL.
- **`place_id:` URL** — a Google Maps `/place/?q=place_id:ChIJ…` URL, handy when you already have `ChIJ…` IDs from the Google Places API.
- **Hex CID only** — pass a raw `0x…:0x…` identifier to `placeIds` instead of `placeUrls`.

Plain coordinate URLs (ones that contain only `@lat,lng,zoom` and no `!1s0x…:0x…` segment) **will not work** — they point to a map view, not a specific place. Click the actual place pin on Google Maps first so the URL updates to include the `!1s` segment before copying.

#### Menu Photos Only (Fastest)

Perfect for food-delivery catalogs — skip everything except menus.

```json
{
    "placeUrls": [
        "https://www.google.com/maps/place/Restaurant+Gordon+Ramsay+High/@51.5144189,-0.7422276,9z/data=!3m1!5s0x48760352a2c5056b:0xd53caca6e8f63804!4m10!1m2!2m1!1sgordon+ramsay!3m6!1s0x48760352b04347ff:0xd0e3c5f99ed75b85!8m2!3d51.5144189!4d-0.0830479"
    ],
    "photoCategories": ["menu"],
    "imageSize": "large"
}
````

#### All Photos for a Place

Get every photo across every Google category, deduplicated.

```json
{
    "placeUrls": [
        "https://www.google.com/maps/place/Restaurant+Gordon+Ramsay/@51.5144189,-0.7422276,9z/data=!4m10!1m2!2m1!1sgordon+ramsay!3m6!1s0x487605f0a8504091:0x95cc2f42ec47f8b4!8m2!3d51.4853968!4d-0.1620078"
    ],
    "photoCategories": ["all"]
}
```

#### Multiple Places with a Cap

Process a list of places and cap photos-per-place to control cost. Full URLs and share-link shortlinks can be mixed freely:

```json
{
    "placeUrls": [
        "https://www.google.com/maps/place/Restaurant+Gordon+Ramsay+High/@51.5144189,-0.7422276,9z/data=!3m1!5s0x48760352a2c5056b:0xd53caca6e8f63804!4m10!1m2!2m1!1sgordon+ramsay!3m6!1s0x48760352b04347ff:0xd0e3c5f99ed75b85!8m2!3d51.5144189!4d-0.0830479",
        "https://www.google.com/maps/place/Restaurant+Gordon+Ramsay/@51.5144189,-0.7422276,9z/data=!4m10!1m2!2m1!1sgordon+ramsay!3m6!1s0x487605f0a8504091:0x95cc2f42ec47f8b4!8m2!3d51.4853968!4d-0.1620078",
        "https://maps.app.goo.gl/7yP7Wq5p7xnSf4yH6"
    ],
    "photoCategories": ["menu", "food_and_drink"],
    "maxPhotosPerPlace": 50,
    "imageSize": "medium"
}
```

#### Using Place IDs Instead of URLs

If you already have Google Maps hex CID identifiers, pass them to `placeIds` directly — no URL parsing needed. Note: the `ChIJ…` format is not a hex CID and must be sent as a `place_id:` URL via `placeUrls` instead.

```json
{
    "placeIds": [
        "0x48760352b04347ff:0xd0e3c5f99ed75b85",
        "0x487605f0a8504091:0x95cc2f42ec47f8b4"
    ],
    "photoCategories": ["food_and_drink"],
    "maxPhotosPerPlace": 30
}
```

#### Pipeline with Google Maps Scraper

Run the [Google Maps Scraper](https://apify.com/solidcode/google-maps-scraper-2-5-per-1-000-results) first to discover places, then feed the `url` column into this actor:

1. Run **[Google Maps Scraper](https://apify.com/solidcode/google-maps-scraper-2-5-per-1-000-results)** with your search query (e.g. `restaurants in Amman`)
2. Export the dataset and grab the `url` column
3. Paste those URLs into `placeUrls` here — done

### Input Reference

#### Places

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `placeUrls` | string\[] | `[]` | Google Maps place URLs. Must contain a place identifier — full URLs with a `!1s0x…:0x…` segment, `place_id:ChIJ…` URLs, or `maps.app.goo.gl` / `goo.gl/maps` shortlinks all work. URLs with only coordinates (`@lat,lng,zoom`) are **not** valid. The `url` field from [Google Maps Scraper](https://apify.com/solidcode/google-maps-scraper-2-5-per-1-000-results) is the easiest source. |
| `placeIds` | string\[] | `[]` | Alternative to URLs — Google Maps place IDs in hex CID format (`0x…:0x…`). `ChIJ…` IDs must be passed as a `place_id:` URL via `placeUrls` instead. |

At least one of `placeUrls` or `placeIds` must be provided.

#### Photos

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `photoCategories` | string\[] | `["all"]` | Which photo categories to collect. `"all"` returns every photo deduplicated across tabs. Valid values: `all`, `latest`, `menu`, `food_and_drink`, `vibe`, `by_owner`, `street_and_360`, `videos`. |
| `maxPhotosPerPlace` | integer | `0` | Cap photos per place. Useful when some places have thousands of photos. `0` = unlimited. |
| `imageSize` | string | `"original"` | Resolution for returned image URLs. Options: `thumbnail` (~150px), `medium` (~800px), `large` (~1600px), `original` (highest available). |

#### Advanced

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `language` | string | `"en"` | Language for category labels and any surfaced metadata (`en`, `nl`, `de`, `fr`, `es`, `it`, `ja`, `ar`, `zh-CN`, and 20+ more). |
| `proxyConfiguration` | object | Apify Proxy | Proxy settings. Defaults to Apify Proxy, which works for most runs. |

### Output

One record per place, with every collected photo bundled into a `photos` array.

```json
{
    "placeId": "0x48760352b04347ff:0xd0e3c5f99ed75b85",
    "placeName": "Restaurant Gordon Ramsay High",
    "url": "https://www.google.com/maps/place/Restaurant+Gordon+Ramsay+High/@51.5144189,-0.7422276,9z/data=!3m1!5s0x48760352a2c5056b:0xd53caca6e8f63804!4m10!1m2!2m1!1sgordon+ramsay!3m6!1s0x48760352b04347ff:0xd0e3c5f99ed75b85!8m2!3d51.5144189!4d-0.0830479",
    "photosCount": 50,
    "photosCountByCategory": {
        "menu": 15,
        "food_and_drink": 20,
        "vibe": 10,
        "by_owner": 5
    },
    "totalPhotosAvailable": 5565,
    "scrapedAt": "2026-04-19T14:32:18Z",
    "photos": [
        {
            "photoId": "AF1QipN_example123",
            "imageUrl": "https://lh3.googleusercontent.com/p/AF1QipN_example123=w1600-h1200-k-no",
            "category": "menu",
            "categoryLabel": "Menu",
            "width": 1600,
            "height": 1200,
            "uploadedByOwner": true,
            "uploadDate": "2024-08-12"
        },
        {
            "photoId": "AF1QipO_example456",
            "imageUrl": "https://lh3.googleusercontent.com/p/AF1QipO_example456=w1600-h1200-k-no",
            "category": "food_and_drink",
            "categoryLabel": "Food & drink",
            "width": 1600,
            "height": 1200,
            "uploadedByOwner": false,
            "uploadDate": "2025-11-03"
        }
    ]
}
```

#### All Available Fields

**Place-level fields**

| Field | Type | Description |
|-------|------|-------------|
| `placeId` | string | Google place ID in hex CID format. |
| `placeName` | string | Display name of the place. |
| `url` | string | Original Google Maps place URL. |
| `photosCount` | number | Total photos returned in this record. |
| `photosCountByCategory` | object | `{category: count}` breakdown across returned photos. |
| `totalPhotosAvailable` | number | Total photos Google reports for the place across all tabs. |
| `scrapedAt` | string | ISO 8601 timestamp of when the place was processed. |
| `photos` | object\[] | Array of photo objects (see below). |

**Fields on each photo**

| Field | Type | Description |
|-------|------|-------------|
| `photoId` | string | Google's unique ID for the photo — safe for deduplication. |
| `imageUrl` | string | Direct image URL at the requested resolution. |
| `category` | string | Category slug (`menu`, `food_and_drink`, `vibe`, `by_owner`, `latest`, `videos`, `street_and_360`, `inside`). |
| `categoryLabel` | string | Human-readable category label in the requested language. |
| `width` | number | Pixel width of the image. |
| `height` | number | Pixel height of the image. |
| `uploadedByOwner` | boolean | `true` if the business owner uploaded the photo, `false` if a visitor did. |
| `uploadDate` | string | ISO date (`YYYY-MM-DD`) when the photo was uploaded, if available. |

### Tips for Best Results

#### Pick Specific Categories Instead of "All" When You Can

Choosing `["menu"]` or `["food_and_drink"]` is faster and cheaper than `["all"]` because the actor can skip the full-category discovery step. Only use `"all"` when you genuinely need the complete photo library.

#### Use `maxPhotosPerPlace` for Cost Control

A popular restaurant can have 5,000+ photos. If you only need a representative sample, cap at 50 or 100 — you'll get the most relevant shots from each category without the long tail.

#### Match Image Size to Your Use Case

- `thumbnail` — fastest to download, ideal for preview grids or quick visual scans
- `medium` — good default for web display (Retina-quality on most screens)
- `large` — high-quality editorial use
- `original` — maximum resolution for archival, ML training, or print

#### Chain with the Google Maps Scraper

Running both actors in a pipeline is the fastest way to go from a search query to a complete categorized photo library. Export the `url` column from your [Google Maps Scraper](https://apify.com/solidcode/google-maps-scraper-2-5-per-1-000-results) run, paste into `placeUrls` here, and you're done.

#### Deduplicate by `photoId`, Not by URL

The same photo can appear under multiple categories (Food & drink and By owner, for example). The actor deduplicates automatically in `"all"` mode, but if you're merging datasets yourself, always dedupe on `photoId` — the image URL changes with resolution.

### Pricing

**$0.50 per 1,000 images** — you only pay for the photos you actually receive.

| Images | Cost |
|--------|------|
| 1,000 | $0.50 |
| 10,000 | $5.00 |
| 100,000 | $50.00 |
| 500,000 | $250.00 |

Platform fees (compute, proxy, storage) are additional and depend on your Apify plan. Filtering by a single category and setting `maxPhotosPerPlace` meaningfully reduces both image count and compute time.

### Integrations

Export data in JSON, CSV, Excel, XML, or RSS. Connect to 1,500+ apps via:

- **Zapier** / **Make** / **n8n** — Workflow automation
- **Google Sheets** — Direct spreadsheet export
- **Slack** / **Email** — Notifications on run completion
- **Webhooks** — Custom API integrations
- **Apify API** — Full programmatic access

### Legal & Ethical Use

This actor is designed for legitimate business intelligence, market research, content enrichment, and ML training workflows. Users are responsible for complying with applicable laws, image copyright, and Google's Terms of Service. Only publicly visible photos are returned. Do not use collected data for spam, harassment, copyright infringement, or any illegal purpose.

# Actor input Schema

## `placeUrls` (type: `array`):

Paste Google Maps place URLs here — one per line. These are the URLs you get from the Google Maps Scraper's 'url' field, or the share link from the Google Maps website. Example: https://www.google.com/maps/place/Katz's+Delicatessen/...

## `placeIds` (type: `array`):

Alternative to URLs — paste Google Maps place IDs or CIDs (hex identifiers) one per line. Useful if you already have IDs from a previous scrape.

## `photoCategories` (type: `array`):

Which categories of photos to collect. Pick 'All' to get every photo (deduplicated), or pick specific categories to cut runtime and cost — for example, just 'Menu' if you only need menu photos.

## `maxPhotosPerPlace` (type: `integer`):

Cap the number of photos returned for each place. Useful when a few places have hundreds of photos and you want to control cost. Set to 0 for unlimited.

## `imageSize` (type: `string`):

Resolution for the returned image URLs. Google serves multiple sizes of the same photo — pick the one that fits your use case.

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

Language for category labels and any surfaced metadata.

## `concurrentPlaces` (type: `integer`):

Process this many places at once. Faster for big lists, but too high may trigger Google rate limits. Default 2 is safe.

## Actor input object example

```json
{
  "placeUrls": [
    "https://www.google.com/maps/place/Katz's+Delicatessen/@40.7223,-73.9874,17z/"
  ],
  "placeIds": [],
  "photoCategories": [
    "all"
  ],
  "maxPhotosPerPlace": 0,
  "imageSize": "original",
  "language": "en",
  "concurrentPlaces": 2
}
```

# Actor output Schema

## `overview` (type: `string`):

Table of places with photo counts per category.

## `photos` (type: `string`):

Flattened gallery view — one row per photo across all places.

# 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 = {
    "placeUrls": [
        "https://www.google.com/maps/place/Katz's+Delicatessen/@40.7223,-73.9874,17z/"
    ],
    "placeIds": [],
    "photoCategories": [
        "all"
    ],
    "maxPhotosPerPlace": 0,
    "imageSize": "original",
    "language": "en",
    "concurrentPlaces": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("solidcode/google-maps-photos-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 = {
    "placeUrls": ["https://www.google.com/maps/place/Katz's+Delicatessen/@40.7223,-73.9874,17z/"],
    "placeIds": [],
    "photoCategories": ["all"],
    "maxPhotosPerPlace": 0,
    "imageSize": "original",
    "language": "en",
    "concurrentPlaces": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("solidcode/google-maps-photos-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 '{
  "placeUrls": [
    "https://www.google.com/maps/place/Katz'\''s+Delicatessen/@40.7223,-73.9874,17z/"
  ],
  "placeIds": [],
  "photoCategories": [
    "all"
  ],
  "maxPhotosPerPlace": 0,
  "imageSize": "original",
  "language": "en",
  "concurrentPlaces": 2
}' |
apify call solidcode/google-maps-photos-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps Photos Scraper | Categorized by Menu, Food, Vibe",
        "description": "[💰 $0.5 / 1K] Extract every photo for any Google Maps place — categorized exactly like the Maps website (Menu, Food & drink, Vibe, By owner, and more). Perfect companion to the Google Maps Scraper: paste place URLs, get a complete categorized photo library per place.",
        "version": "1.0",
        "x-build-id": "irYpJH61JY6B60deS"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/solidcode~google-maps-photos-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-solidcode-google-maps-photos-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/solidcode~google-maps-photos-scraper/runs": {
            "post": {
                "operationId": "runs-sync-solidcode-google-maps-photos-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/solidcode~google-maps-photos-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-solidcode-google-maps-photos-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "placeUrls": {
                        "title": "Google Maps Place URLs",
                        "type": "array",
                        "description": "Paste Google Maps place URLs here — one per line. These are the URLs you get from the Google Maps Scraper's 'url' field, or the share link from the Google Maps website. Example: https://www.google.com/maps/place/Katz's+Delicatessen/...",
                        "items": {
                            "type": "string"
                        }
                    },
                    "placeIds": {
                        "title": "Google Maps Place IDs",
                        "type": "array",
                        "description": "Alternative to URLs — paste Google Maps place IDs or CIDs (hex identifiers) one per line. Useful if you already have IDs from a previous scrape.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "photoCategories": {
                        "title": "Photo Categories",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Which categories of photos to collect. Pick 'All' to get every photo (deduplicated), or pick specific categories to cut runtime and cost — for example, just 'Menu' if you only need menu photos.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "all",
                                "latest",
                                "menu",
                                "food_and_drink",
                                "vibe",
                                "by_owner",
                                "street_and_360",
                                "videos"
                            ],
                            "enumTitles": [
                                "All photos",
                                "Latest",
                                "Menu",
                                "Food & drink",
                                "Vibe",
                                "By owner",
                                "Street View & 360°",
                                "Videos"
                            ]
                        },
                        "default": [
                            "all"
                        ]
                    },
                    "maxPhotosPerPlace": {
                        "title": "Max Photos Per Place",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Cap the number of photos returned for each place. Useful when a few places have hundreds of photos and you want to control cost. Set to 0 for unlimited.",
                        "default": 0
                    },
                    "imageSize": {
                        "title": "Image Resolution",
                        "enum": [
                            "thumbnail",
                            "medium",
                            "large",
                            "original"
                        ],
                        "type": "string",
                        "description": "Resolution for the returned image URLs. Google serves multiple sizes of the same photo — pick the one that fits your use case.",
                        "default": "original"
                    },
                    "language": {
                        "title": "Language",
                        "enum": [
                            "en",
                            "nl",
                            "de",
                            "fr",
                            "es",
                            "it",
                            "pt",
                            "pl",
                            "cs",
                            "da",
                            "sv",
                            "no",
                            "fi",
                            "el",
                            "tr",
                            "ar",
                            "he",
                            "ja",
                            "ko",
                            "zh-CN",
                            "zh-TW",
                            "th",
                            "vi",
                            "id",
                            "ms",
                            "hi",
                            "ru",
                            "uk",
                            "ro",
                            "hu",
                            "hr",
                            "bg",
                            "sk"
                        ],
                        "type": "string",
                        "description": "Language for category labels and any surfaced metadata.",
                        "default": "en"
                    },
                    "concurrentPlaces": {
                        "title": "Concurrent Places",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Process this many places at once. Faster for big lists, but too high may trigger Google rate limits. Default 2 is safe.",
                        "default": 2
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
