# Google Maps Menu Scraper — Allergens, Nutrition, No API Key (`traveleat/google-maps-menu-scraper-managed`) Actor

Turn a Google Maps place URL into structured dishes with translated names, prices, ingredients, dietary types, and AI-estimated EU-14 allergens and nutrition. No API keys. Empty diagnostic runs cost $0; verify dietary and allergen data with the venue.

- **URL**: https://apify.com/traveleat/google-maps-menu-scraper-managed.md
- **Developed by:** [Travel Eat](https://apify.com/traveleat) (community)
- **Categories:** AI, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.10 / 1,000 dish extracteds

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Maps Menu Scraper — Allergens, Nutrition & Prices, No API Key

### Start with one input and output

An Apify account is required. Use your Apify API token when calling the API; Console runs do not need that token pasted into the input. No user API-key field is required by this input schema. none.

Free-tier event rates checked 2026-10-04: `result` $0.0002; `actor-start` $5e-05.

**Cost:** Total = Actor event charges + platform usage if separately billed + any BYO-provider charges. See “Current costs” for your event rates, plan tiers and a calculation. A sample does not promise future billable volume.

Input and output below were read from the same successful run `8pqlb0dMFPYL4IMZZ` (2026-09-07, immutable build `Zi3eqnyTuLl1Nc5FS`). This is an observed example, not a guarantee that repeating it returns this row. It used an earlier build; current-build execution has not been proved by this example.

**Input JSON**

```json
{
  "placeUrls": [
    "https://maps.app.goo.gl/9bCni21Ld4s756ja7"
  ],
  "geminiModel": "gemini-2.5-flash",
  "language": "en",
  "maxMenuPhotos": 1
}
```

**Matching output excerpt**

Long strings and arrays are shortened for display; this is not a complete dataset fixture.

```json
{
  "recordType": "DISH",
  "name": "Butter Chicken",
  "originalName": "Butter Chicken / Pollo a la Mantequilla",
  "category": "House Specials",
  "price": "11,49€",
  "composition": "Boneless tandoori chicken cooked with tomato sauce, butter, and fresh cream.",
  "description": "Tender boneless chicken pieces in a rich, creamy, and mildly spiced tomato-based sauce.",
  "ingredients": [
    {
      "name": "chicken",
      "display_name": "Chicken",
      "explanation": null
    },
    {
      "name": "tomato",
      "display_name": "Tomato",
      "explanation": null
    }
  ],
  "dietaryType": "Other",
  "dietaryTypeExplanation": "This dish contains chicken and dairy products (butter, cream, yogurt).",
  "allergens": "Milk, Celery, Mustard",
  "type": "dish",
  "isAlcoholic": false,
  "story": "Butter Chicken (Murgh Makhani) is a classic Indian dish originating from Delhi, known for its rich, creamy tomato sauce. It was created in the 1950s by Kundan Lal Gujral at Moti Mahal restaurant.",
  "nutritionInfo": {
    "serving_size_grams": "300-400g",
    "calories": "500-700 kcal",
    "protein": "30-40g",
    "fat": "35-50g",
    "carbs": "20-30g"
  },
  "place": "https://maps.app.goo.gl/9bCni21Ld4s756ja7",
  "resolvedPlaceUrl": "https://www.google.com/maps/place/Swad+Restaurante/@43.2628755,-2.9229553,19.11z/data=!4m6!3m5!1s0xd4e4f4fc588850f:0xbe1640216acaafec!8m2!3d43.2627726!4d-2.9227844!16s%2Fg%2F11vpwsg8pv?entry=tts&g_ep=EgoyMDI2MDkwMi4wIPu8ASoASAFQAw%3D%3D&skid=1adbdbed-c8a5-4d03-883f-dc661808542c",
  "menuPhotoUrls": [
    "https://lh3.googleusercontent.com/gps-cs-s/AHRPTWksBqemBz7yqLisTARVUEwpCdJxSlT3cZCeWx70ZITLunxZxM4nO4JFGAcc4Ifn_zz8eNVq2-s8Qd2O6CfZIWbNHh-8uaJABMY9f0wb7fZaYcq_uAPANXua__epCRjR9VDJlZo=w2048-h2048-k-no"
  ],
  "menuPhotosFound": 4,
  "menuSource": "maps"
}
```

Give it a Google Maps place URL, place ID, or just a place name and get back
the restaurant's **menu as structured data** with no API keys. The actor first
collects the place's **Menu** photos; if none are available, it checks the
restaurant website for menu images or PDFs, then AI-parses the menu into one
record per dish:

- `name` (translated to your language) + `originalName` (as printed)
- `category`, `price` (with currency, as shown)
- `ingredients` — AI-inferred base ingredients, each with an English database
  name, translated display name, and **estimated EU-14 allergens with confidence**
  (gluten, crustaceans, eggs, fish, peanuts, soy, milk, nuts, celery,
  mustard, sesame, sulfites, lupin, molluscs)
- `dietaryType` — Vegan / Vegetarian / Pescetarian / Other, with explanation
- `nutritionInfo` — estimated serving size, calories, protein, fat, carbs
- `story` — well-established cultural context when confident, otherwise `null`
- `isAlcoholic` for beverages

Cheaper Google Maps menu scrapers often return plain OCR text: an item name
and perhaps a price. This actor adds AI-inferred ingredients, allergen flags,
dietary classification, nutrition ranges, and translations. These enriched
fields are estimates, not verified restaurant disclosures.

### Fair, transparent pricing

- Check this Actor’s **Pricing** tab for the current charges for your Apify plan. Actor-start and per-dish events apply to live output.
- On your first successful live run, up to 10 dish charges are waived; the actor-start charge still applies. The untouched default is a clearly marked deterministic demo and costs $0.
- **You only pay when dishes are extracted.** A run that produces only
  diagnostic rows costs $0 in Actor charges. Dishes are saved before any
  Actor charge is attempted.
- Photo fetching and AI parsing run on **our managed keys** and their cost
  is already included in the per-dish price. No Google AI Studio signup, no
  Outscraper account, no proxy configuration — paste a place, get a menu.
- Duplicate menu pages are deduplicated **before** billing, and extraction
  runs at temperature 0 for more consistent output.
- **On a budget?** The
  [Google Maps Menu Scraper (BYO keys)](https://apify.com/traveleat/google-maps-menu-scraper)
  twin lets you supply your own Gemini and Outscraper keys. Compare its
  Pricing tab and your provider charges before choosing.

### Why this actor

Generic Google Maps scrapers focus on reviews and opening hours. Basic menu
OCR gives you raw item names. This actor turns published menus into a richer,
structured research dataset with AI-estimated ingredient and dietary fields,
allergen confidence scores, nutrition ranges, and dish-name translation in
15 languages.

### Use cases

- **Food & dietary apps** — build allergen-aware and vegan/vegetarian
  discovery workflows at the dish level, not the venue level.
- **Delivery & ordering platforms** — draft structured dishes, prices, and
  estimated allergen annotations for subsequent venue verification.
- **Hospitality research** — review how a venue's published menu may map to
  the EU-14 list before obtaining verified information from the venue.
- **Market research** — compare dish pricing and menu composition across a
  city or cuisine, in one language.
- **Travel products** — show travellers what a place serves, translated,
  with cultural context per dish.

### Input example

```json
{
  "placeUrls": ["https://www.google.com/maps/place/Katz's+Delicatessen,+205+E+Houston+St,+New+York"],
  "language": "en",
  "maxMenuPhotos": 8
}
```

Bare place IDs (`ChIJ…`) and plain place names (`Katz's Delicatessen New
York`) work too. Output language covers en, es, fr, de, it, pt, ru, zh, ja,
ko, ar, hi, uk, ka and eu.

### FAQ

**How is this different from actors advertising "dietary tags"?**
Those tags are keyword-matched from the menu's description text — if the
menu doesn't literally say "vegan", the tag is missing; if it says "vegan
option available", everything gets tagged. This actor uses menu text and
typical recipe knowledge to infer ingredients, then reports **estimated
per-ingredient EU-14 allergens with a confidence score**, plus an explanation
of the dietary classification. Verify critical fields with the venue.

**What if the place has no menu photos on Google Maps?**
The actor falls back to the menu published on the place's own website
(including PDF menus). If neither exists, you get a free diagnostic row —
never a per-dish charge.

### Notes

- The untouched Console defaults return one deterministic row labelled
  `recordType: "DEMO"` / `isDemo: true`. No live source or model call occurs,
  and the run has $0 in Actor charges. Change any input for a live run.
- Places with no menu photos and no website menu yield a non-billed
  diagnostic row explaining why.
- `maps.app.goo.gl` short links are resolved to a trusted Google Maps URL.
  Output keeps the original `place` and exposes the canonical URL as
  `resolvedPlaceUrl` when resolution was needed.
- Ingredient, allergen, dietary, and nutrition fields are AI estimates from
  the published menu and typical recipes. Verify them with the restaurant or
  product label before making allergy, medical, or compliance decisions.
- Already have menu photo URLs? Use the companion **AI Restaurant Menu
  Parser** actor. Want the place's food photos matched to these dishes?
  Chain the **Restaurant Dish Photo Matcher** actor.
- Prefer to pay Google and Outscraper directly and control your own quota?
  The **Google Maps Menu Scraper (BYO keys)** Actor lets you supply
  `geminiApiKey` / `outscraperApiKey`. Compare its Pricing tab and your
  provider charges before choosing.

### Support & links

- Questions, bug reports and FAQ:
  [github.com/Exdenta/traveleat-support](https://github.com/Exdenta/traveleat-support)
- This actor runs the same menu pipeline as [Travel Eat](https://traveleat.app) —
  scan a menu, get allergens, ingredients and dietary filters in 36 languages.

### Product guides and related tools

- [Product overview and public links](https://jobatlas.dev/actors/directory/menus-and-photos#nomad-agent-google-maps-menu-scraper-managed)
- [Public setup guide](https://github.com/Exdenta/jobatlas/blob/main/docs/public-actors-setup.md)
- [Travel Eat menu API guide](https://traveleat.app/blog/ai-menu-parser-api)
- [Menu API documentation and support](https://github.com/Exdenta/traveleat-support)
- [AI Restaurant Menu Parser — Dishes & Allergens, No API Key](https://apify.com/traveleat/ai-menu-parser-managed)
- [Dish Photo Matcher — Google Maps Food Photos to Menu Items](https://apify.com/traveleat/dish-photo-matcher-managed)

### Current costs

Current Actor event rates, checked 2026-10-04. USD; use the **Pricing** tab for your plan and later changes.

| Event | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---:|---:|---:|---:|---:|---:|
| Dish extracted (`result`) | $0.0002 | $0.0002 | $0.0002 | $0.0002 | $0.0002 | $0.0002 |
| Actor start (`actor-start`) | $5e-05 | $5e-05 | $5e-05 | $5e-05 | $5e-05 | $5e-05 |

For example, 100 × `result`, 1 × `actor-start` totals **$0.02005 in Actor event charges on Free**. This is an arithmetic example, before any waiver; actual charged events depend on the run and selected options. It is not a promise of output or a charge for simply setting an item cap.

Your total is the charged Actor events, plus platform usage **only if this Actor’s Pricing tab bills it separately**, plus any external provider you use with your own key. Do not add platform usage twice when it is included. Apify credits and plan discounts affect your invoice. Set a run cost limit in Console before starting.

As documented, the first successful live run waives up to ten per-dish events; the actor-start event still applies. The untouched prefilled sample is a marked demo, not a live parse. Empty/failed diagnostic output creates no Actor billing events.

### Agent setup skill

Use the maintained [SKILL.md](https://github.com/Exdenta/jobatlas/blob/main/.agents/skills/public-apify-actors/SKILL.md) to configure the documented inputs, select `latest`, record the immutable build and distinguish source results from preview or diagnostic rows. Check the current Pricing tab before starting a run.

# Actor input Schema

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

Paste one or more full Google Maps place URLs. maps.app.goo.gl short links are resolved automatically; bare place IDs and names are also accepted. The untouched default returns one clearly marked, $0 demo row.

## `geminiModel` (type: `string`):

Model used to read the menu photos. The AI cost is included in the price either way.

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

Language for dish names, descriptions, stories and allergen summaries (ingredient database names stay English).

## `maxMenuPhotos` (type: `integer`):

How many of the place's menu photos are sent to the AI. 8 covers most menus; lower it for a cheaper, faster test.

## Actor input object example

```json
{
  "placeUrls": [
    "https://www.google.com/maps/place/Katz's+Delicatessen,+205+E+Houston+St,+New+York"
  ],
  "geminiModel": "gemini-2.5-flash",
  "language": "en",
  "maxMenuPhotos": 8
}
```

# Actor output Schema

## `items` (type: `string`):

The run's dataset items (see the dataset schema for the field-by-field structure).

# 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,+205+E+Houston+St,+New+York"
    ],
    "maxMenuPhotos": 8
};

// Run the Actor and wait for it to finish
const run = await client.actor("traveleat/google-maps-menu-scraper-managed").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,+205+E+Houston+St,+New+York"],
    "maxMenuPhotos": 8,
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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,+205+E+Houston+St,+New+York"
  ],
  "maxMenuPhotos": 8
}' |
apify call traveleat/google-maps-menu-scraper-managed --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,traveleat/google-maps-menu-scraper-managed"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Z7bbXExntcMPq9tFH/builds/kqRFyHs9VbbleNHi4/openapi.json
