# AI Menu Parser (Flat Price per Menu) + Allergens (`traveleat/ai-menu-parser-flat`) Actor

$20/1K menus | Parse a menu (up to 10 photos) into dish JSON for one flat price per menu, however many dishes it has: translated names, prices, ingredients and AI-estimated allergens in 15 languages. No API key.

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

## Pricing

from $10.00 / 1,000 menu parseds

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

## AI Menu Parser (Flat Price per Menu) + Allergens

$20/1K menus | Parse a menu (up to 10 photos) into dish JSON for one flat price per menu, however many dishes it has: translated names, prices, ingredients and AI-estimated allergens in 15 languages. No API key. Independent, unofficial tool.

### AI Menu Photo to Dish JSON, Flat Price per Menu

Our parser reads up to 10 photos of one restaurant menu and returns one JSON record per dish, for **one flat charge per successfully parsed menu**: a 12-dish café card and a 60-dish dinner board cost the same. **No Gemini or other AI key is needed**; the AI cost is included. It is ideal for dietary-restriction apps, menu databases and menu translation.

- Small menus or many single photos? [AI Restaurant Menu Parser (No API Key) + Allergens](https://apify.com/traveleat/ai-menu-parser-managed) charges $0.20 per 1,000 dishes (a 12-dish menu cost $0.00245), so it is cheaper below about 100 dishes per menu.
- Prefer your own key? [AI Restaurant Menu Parser (No AI Markup) + Allergens](https://apify.com/traveleat/ai-menu-parser) costs $0.10 per 1,000 dishes plus your Gemini usage.
- Have the menu and want dish photos? [Dish Photo Matcher (No API Key): Food Photos to Menu Items](https://apify.com/traveleat/dish-photo-matcher-managed) matches guest photos to your menu items.
- Browse all our scrapers: https://apify.com/traveleat

#### Key Benefits

- No API key: nothing to sign up for, the AI cost is included.
- Flat pricing: $20 per 1,000 menus ($0.02 per parsed menu), whatever the number of dishes. You know the cost before you run.
- Free to try: Start on the prefilled form returns a clearly marked DEMO row at no charge.
- Charged only on success: empty, unreadable or failed parses return a diagnostic row and no charge.
- Rich output: ingredients, EU-14 allergens, dietary type and estimated nutrition in 15 output languages.

### How It Works

1. Add the photos of one menu: upload JPEG, PNG or WebP files in the Console, or pass image URLs (API callers can also send base64). Up to 10 photos per run, each up to 10 MiB, are parsed together as one menu.
2. Pick the output language.
3. Run the Actor. You get one dataset row per dish, and one `menu-parsed` charge. In our test, a one-photo menu with 12 dishes finished in about 78 seconds and was charged once.

One run is one menu: for several restaurants, start one run each.

The prefilled form (the sample menu photo, unchanged) is a deterministic preview: it returns one DEMO row, calls no model and bills nothing. Change the photo or the language for a live parse.

Limits: PDFs are not read, so convert menu pages to images first. Unreadable items are skipped rather than guessed, and AI output can be wrong on stylised or low-resolution menus.

**Allergens, dietary type, ingredients and nutrition are AI estimates.** They can be wrong and do not reliably account for substitutions or kitchen cross-contact. Verify critical information with the restaurant, and never use this output as the only safeguard for a severe allergy.

#### Data You'll Receive

- Dish basics: `name` translated to your language, `originalName` as printed, `category`, `price` with currency as shown, `composition`, `description`.
- Ingredients: atomic base ingredients, each with an English database name, a translated display name and EU-14 allergens with a confidence level (AI estimates).
- Diet and nutrition: `dietaryType` (Vegan, Vegetarian, Pescetarian or Other) with an explanation, estimated serving size, calories, protein, fat and carbs, `isAlcoholic` for drinks.
- Story: an origin or cultural note on some dishes (11 of 12 in our test menu).
- Source: `sourceImageUrls` and `sourceImageRefs` point back to the photo each dish came from.

#### Sample output data

Here is an example dish from a live run of this Actor (language `es`; ingredients shortened to two):

```json
{
  "recordType": "DISH",
  "name": "Desayuno estilo Cracovia",
  "originalName": "KRAKOWSKIE / CRACOW - STYLE BREAKFAST",
  "category": "Desayunos",
  "price": "34 zł",
  "composition": "Obwarzanek, pasta de huevo con cebollino, requesón con atún, hummus",
  "description": "Un desayuno variado que incluye un pan tradicional polaco, pasta de huevo, requesón con atún y hummus cremoso.",
  "ingredients": [
    {
      "name": "wheat flour",
      "display_name": "Harina de trigo",
      "explanation": null,
      "allergens": [
        {
          "name": "gluten",
          "confidence": "high"
        }
      ]
    },
    {
      "name": "egg",
      "display_name": "Huevo",
      "explanation": null,
      "allergens": [
        {
          "name": "eggs",
          "confidence": "high"
        }
      ]
    }
  ],
  "dietaryType": "Pescetarian",
  "dietaryTypeExplanation": "Este plato contiene atún, lo que lo clasifica como pescetariano. También incluye lácteos y huevos.",
  "allergens": "Gluten, Huevos, Leche, Pescado, Sésamo",
  "type": "dish",
  "isAlcoholic": false,
  "story": "El obwarzanek es un pan tradicional polaco, similar a un pretzel, originario de Cracovia y reconocido como producto regional protegido.",
  "nutritionInfo": {
    "serving_size_grams": "300g",
    "calories": "450-550 kcal",
    "protein": "25-35g",
    "fat": "15-25g",
    "carbs": "40-50g"
  },
  "sourceImageUrls": [
    "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
  ],
  "sourceImageRefs": [
    "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
  ]
}
```

### Menu Parser API

Results are stored in a dataset that you can export as CSV, JSON or Excel, or read on demand through the Apify API.

#### Support and Feedback

We improve these Actors from your feedback. If something breaks or you need a field:

- Open an issue on the Actor's Issues tab
- If this Actor saved you time, a short review on the Store helps other users find it.

### Run evidence

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

Free-tier event rates checked 2026-10-08: `menu-parsed` $0.02.

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

This matching input/output pair is a **marked DEMO preview**, observed in run `WS8xz5CbeRgpueQ7V` (immutable build `Iimq0n8JsI7rfTXLd`). It demonstrates the output shape and makes no live source or AI-provider call. It does not verify a live parse or synchronization. Keep the preview unchanged; customize it and supply the documented credentials for live work.

**Input JSON**

```json
{
  "imageUrls": [
    "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
  ],
  "language": "en"
}
```

**Matching output excerpt**

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

```json
{
  "recordType": "DEMO",
  "isDemo": true,
  "demoSource": "owned-default-prefill",
  "demoNote": "Deterministic preview only: no live source, photo scrape, or Gemini call occurred, and the row was not billed. Customize the input for live output; BYOK listings also require their provider credentials.",
  "name": "DEMO SAMPLE — Margherita Pizza",
  "originalName": "Margherita Pizza",
  "category": "Pizza",
  "price": "$18.00",
  "composition": "Tomato, mozzarella and basil",
  "description": "Example structured menu record; not a live extraction.",
  "ingredients": [],
  "dietaryType": "Vegetarian",
  "dietaryTypeExplanation": "Example classification for preview only.",
  "allergens": "Milk (preview example)",
  "type": "dish",
  "isAlcoholic": false,
  "story": null,
  "nutritionInfo": null,
  "sourceImageUrls": [
    "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
  ],
  "sourceImageRefs": [
    "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
  ]
}
```

**One flat charge per menu. Charged only when parsing succeeds. No API key.**

Upload up to 10 photos of a menu (or send URLs/base64 through JSON), get the
whole menu back as **structured JSON** — one record per dish, however many
dishes it has. A 12-dish café card and a 60-dish restaurant board cost exactly
the same.

Each dish record includes:

- `name` (translated to your language) + `originalName` (as printed)
- `category`, `price` (with currency, as shown)
- `ingredients` — atomic base ingredients, each with an English database
  name, translated display name, and **EU-14 allergens with confidence**
- `dietaryType` — Vegan / Vegetarian / Pescetarian / Other, with explanation
- `nutritionInfo` — estimated serving size, calories, protein, fat, carbs
- `story` — origin story / cultural significance
- `isAlcoholic` for beverages

15 output languages. The prompt is the production pipeline of a
dietary-restrictions travel app — battle-tested on real menus worldwide.

#### Why flat pricing

You know the cost before you run: one menu, one price. No per-dish
metering, no bill surprises on dense menus. If the parse fails or the
photos are unreadable, you are not charged — a non-billed diagnostic row
explains what went wrong instead.

Check this Actor’s **Pricing** tab for the current charges for your Apify plan. The charge is per successfully parsed custom menu.
The untouched prefilled sample is a clearly marked DEMO preview, makes no Gemini
call and creates no Actor billing events; check Pricing for separately billed platform usage. Empty and failed parses return
`diagnostic: true` with a human-readable `message` and are not charged.

Parsing a small or medium menu? The per-dish
[ai-menu-parser-managed](https://apify.com/traveleat/ai-menu-parser-managed)
(no key) usually costs less than this flat fee; compare both Pricing tabs. The
same parser with your own Gemini key is
[ai-menu-parser](https://apify.com/traveleat/ai-menu-parser).

#### Input example

```json
{
  "imageUrls": ["https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"],
  "language": "en"
}
```

#### Notes

- The Console accepts local JPEG, PNG, or WebP uploads directly. API callers
  may use HTTP(S) URLs, base64 data URIs, or raw base64 in `imageUrls`.
- Each decoded image is limited to 10 MiB. Inline payloads and signed URL
  credentials are replaced with safe references in output records and logs.
- Up to 10 images per run, parsed together as **one** menu. One run = one
  menu — for several restaurants, start one run each.
- Unreadable items are skipped rather than guessed; empty results produce a
  non-billed diagnostic row explaining why.

#### Safety

Allergen, dietary, ingredient and nutrition fields are AI-generated estimates.
They can be wrong and do not account reliably for substitutions or kitchen
cross-contact. Verify critical information with the restaurant; do not rely on
this output as medical advice or as the sole safeguard for a severe allergy.

#### 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-ai-menu-parser-flat)
- [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)
- [Dish Photo Matcher (No API Key): Food Photos to Menu Items](https://apify.com/traveleat/dish-photo-matcher-managed)

#### Current costs

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

| Event | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---:|---:|---:|---:|---:|---:|
| Menu parsed (`menu-parsed`) | $0.02 | $0.02 | $0.02 | $0.02 | $0.02 | $0.02 |

For example, 1 × `menu-parsed` totals **$0.02 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.

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

***

**Independent tool.** We built and run this Actor ourselves. Google does not operate, sponsor or endorse it, and its name is used only to say which service the data is processed with. We are not affiliated with Google.

# Actor input Schema

## `imageUrls` (type: `array`):

Upload menu photos or provide direct image URLs (JPEG/PNG/WebP, 10 MiB per image). API/JSON callers may also pass base64 data URIs or raw base64 strings in imageUrls. All images are parsed as one menu — up to 10 per run. The untouched owned sample returns a free, clearly marked DEMO preview; replace it with your own images for a live paid parse (see the Pricing tab).

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

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

## Actor input object example

```json
{
  "imageUrls": [
    "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
  ],
  "language": "en"
}
```

# 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 = {
    "imageUrls": [
        "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("traveleat/ai-menu-parser-flat").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 = { "imageUrls": ["https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"] }

# Run the Actor and wait for it to finish
run = client.actor("traveleat/ai-menu-parser-flat").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 '{
  "imageUrls": [
    "https://raw.githubusercontent.com/Exdenta/traveleat-support/main/docs/assets/menu-demo-small.jpg"
  ]
}' |
apify call traveleat/ai-menu-parser-flat --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,traveleat/ai-menu-parser-flat"
        }
    }
}
```

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/e1XbntV3sj0P6EzST/builds/ZbNRVYMhRgih7Vhes/openapi.json
