# Uber Eats Menus & Reviews Scraper (`automation-lab/ubereats-menu-reviews-scraper`) Actor

Search Uber Eats restaurants and export menu items, prices, ratings, restaurant details, and public customer review samples as structured data.

- **URL**: https://apify.com/automation-lab/ubereats-menu-reviews-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Uber Eats Menus & Reviews Scraper

Search Uber Eats restaurants and export current restaurant details, full menu items, prices, ratings, and public customer review samples.

Use this Actor to collect structured **Uber Eats data** for menu-price tracking, restaurant-market research, assortment comparisons, and sentiment analysis.

If you are asking **is Uber Eats worth it** for a restaurant category or market, this scraper gives you the menu, rating, and review evidence needed for a repeatable analysis instead of a manual spot check.

### What does Uber Eats Menus & Reviews Scraper do?

The Actor supports two input routes:

1. Search Uber Eats with restaurant, chain, or cuisine queries.
2. Scrape exact public Uber Eats restaurant URLs.

For every accepted restaurant, it saves one structured dataset record containing:

- restaurant identity and URL;
- address and coordinates;
- cuisine labels;
- phone number when public;
- aggregate rating and review count;
- open and orderable status;
- complete menu sections and unique menu items exposed by Uber Eats;
- item descriptions, prices, currency, images, availability, and customization flags;
- a bounded sample of public customer reviews;
- the source query and collection timestamp.

A single restaurant remains one dataset item even when it contains hundreds of menu items and multiple reviews.

That format makes exports easy to join, diff, and archive.

### Who is it for?

#### Restaurant and food-service analysts

Track current menu assortments and compare advertised prices across restaurants.

#### Consumer brands and suppliers

See how products, meal types, or cuisines appear in delivery menus.

#### Agencies and reputation teams

Combine aggregate ratings with the public review samples Uber Eats exposes.

#### Data engineers

Run the Actor through the Apify API and send normalized restaurant records into a warehouse or spreadsheet.

#### Competitive-intelligence teams

Schedule the same inputs and compare snapshots over time.

The Actor collects current snapshots.

It does not calculate historical changes itself.

### Why use this Actor?

- **Search and exact URLs:** discover stores by query or target known restaurant pages.
- **Menu and review context together:** receive prices and sentiment signals in the same restaurant record.
- **No login required:** the supported workflow uses public Uber Eats data surfaces.
- **Stable identifiers:** restaurant, menu-item, and review UUIDs support repeat-run comparisons.
- **Typed JSON output:** no raw HTML or browser-debug objects.
- **Efficient HTTP extraction:** no browser or paid proxy is used in the normal route.
- **Bounded runs:** control restaurant and review volume directly from input.
- **API-ready:** schedule, integrate, export, and automate with standard Apify tools.

### What Uber Eats fields can I extract?

| Field | Meaning |
| --- | --- |
| `restaurantId` | Stable Uber Eats store UUID |
| `name` | Restaurant or store name |
| `url` | Public Uber Eats restaurant URL |
| `slug`, `citySlug` | Source URL and city slugs when exposed |
| `address` | Formatted public restaurant address |
| `latitude`, `longitude` | Restaurant coordinates |
| `phoneNumber` | Public phone number when available |
| `cuisines` | Uber Eats cuisine labels |
| `rating` | Aggregate rating value |
| `reviewCount` | Displayed aggregate review count |
| `priceBucket` | Source price-level label when available |
| `currencyCode` | ISO menu currency |
| `isOpen`, `isOrderable` | Current marketplace status |
| `menuItemCount` | Number of unique included menu items |
| `reviewSampleCount` | Number of included public review samples |
| `menuItems` | Nested menu items with categories and prices |
| `reviews` | Nested public review samples |
| `sourceQuery` | Query that discovered the restaurant |
| `scrapedAt` | Collection timestamp |

Menu-item fields include `id`, `name`, `description`, `price`, `priceFormatted`, `currencyCode`, `category`, `imageUrl`, `isAvailable`, `isSoldOut`, and `hasCustomizations`.

Review fields include `id`, `authorName`, `text`, `createdAt`, `formattedDate`, `timeSinceReview`, and `featured`.

Fields can be `null` when Uber Eats does not expose them for a restaurant.

### How do I scrape Uber Eats menus and reviews?

1. Open the Actor input page.
2. Enter one or more restaurant or cuisine names in `searchQueries`.
3. Optionally add exact restaurant pages in `startUrls`.
4. Set `maxRestaurants` to the maximum records you need.
5. Keep `includeMenu` enabled to collect menu items and prices.
6. Keep `includeReviews` enabled to collect public review samples.
7. Set `maxReviewsPerRestaurant` to bound review arrays.
8. Click **Start**.
9. Open the **Restaurants** dataset view.
10. Export JSON, CSV, Excel, XML, or another supported format.

The default input searches for McDonald's and is intentionally small enough for a first run.

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `searchQueries` | string array | `['McDonald\'s']` | Restaurant, chain, or cuisine searches; maximum 20 |
| `startUrls` | request list | empty | Exact public Uber Eats restaurant URLs; maximum 100 |
| `locale` | string | `us` | Uber Eats locale code, such as `us`, `gb`, `ca`, or `au` |
| `maxRestaurants` | integer | `10` | Maximum unique restaurant records; 1–100 |
| `includeMenu` | boolean | `true` | Include menu items and prices |
| `includeReviews` | boolean | `true` | Include public review samples |
| `maxReviewsPerRestaurant` | integer | `20` | Review-sample limit per restaurant; 0–200 |

Provide at least one search query or URL.

The schema's default search is applied when you start the Actor with an empty input in Apify Console.

Search follows Uber Eats' public marketplace context.

Use exact restaurant URLs when location precision is required.

### Example inputs

#### Search a restaurant chain

```json
{
  "searchQueries": ["McDonald's"],
  "maxRestaurants": 2,
  "includeMenu": true,
  "includeReviews": true,
  "maxReviewsPerRestaurant": 10
}
```

#### Scrape one exact restaurant

```json
{
  "startUrls": [
    {
      "url": "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ"
    }
  ],
  "maxRestaurants": 1,
  "includeMenu": true,
  "includeReviews": true,
  "maxReviewsPerRestaurant": 20
}
```

#### Monitor two food categories

```json
{
  "searchQueries": ["burgers", "pizza"],
  "maxRestaurants": 4,
  "includeMenu": true,
  "includeReviews": true,
  "maxReviewsPerRestaurant": 10
}
```

### Example output

This shortened record reflects the current output shape:

```json
{
  "type": "restaurant",
  "restaurantId": "3f6d47fc-b7f7-49ed-b04a-68c61dfa0571",
  "name": "McDonald's® (Fillmore)",
  "url": "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ",
  "address": "1100 Fillmore St, SAN FRANCISCO, CA 94115",
  "latitude": 37.7798997,
  "longitude": -122.4318414,
  "cuisines": ["American"],
  "rating": 4.5,
  "reviewCount": "15000+",
  "currencyCode": "USD",
  "menuItemCount": 208,
  "reviewSampleCount": 20,
  "menuItems": [
    {
      "id": "5daade04-ed06-56a2-a121-6d69572a8520",
      "name": "Medium French Fries",
      "price": 5.69,
      "priceFormatted": "$5.69",
      "category": "Featured items",
      "isAvailable": true,
      "isSoldOut": false
    }
  ],
  "reviews": [
    {
      "id": "dcece822-dbaf-4bc3-957a-1ac5c1bae20f",
      "authorName": "Carolyn C.",
      "text": "Ordered a large decaf coffee & large Diet Coke with extra ice...",
      "createdAt": "2025-08-13T00:00:00Z",
      "featured": true
    }
  ],
  "sourceQuery": null,
  "scrapedAt": "2026-08-11T14:15:00.000Z"
}
```

The complete dataset item contains every menu item and requested review sample returned for that restaurant.

### How much does it cost to scrape Uber Eats restaurant menus?

The Actor uses pay-per-event pricing:

- a one-time **Start** event per run;
- one **Restaurant** event per saved restaurant record;
- menu items and review samples inside that restaurant record have no separate charge event.

At the BRONZE rate of **$0.00264 per restaurant** plus a **$0.005 start fee**:

The run total is the active start rate plus the active restaurant rate multiplied by the number of saved restaurant records.

For example, a one-record run has one Start event and one Restaurant event; a ten-record run has one Start event and ten Restaurant events.

Apify subscription tiers receive the discounts shown in the Actor pricing tab.

Actual platform billing uses the active tier assigned to your Apify plan.

Choose a smaller restaurant limit for a smaller run.

### Schedule menu-price and sentiment monitoring

Apify schedules make recurring snapshots straightforward:

1. Save a Task with exact restaurant URLs or stable search queries.
2. Run it daily, weekly, or monthly.
3. Export each dataset to your storage destination.
4. Join records by `restaurantId`.
5. Join menu entries by their menu-item `id`.
6. Compare `price`, `isAvailable`, `rating`, and `reviewCount` between snapshots.

For review monitoring, compare review `id` values to identify samples not present in an earlier run.

Uber Eats can rotate which public samples it exposes, so do not treat sample absence as deletion.

### Export to spreadsheets and data pipelines

The default dataset can be downloaded as JSON, CSV, Excel, XML, RSS, or HTML through Apify.

Nested menu and review arrays are best preserved in JSON.

For a relational warehouse, flatten the output into:

- a restaurant table keyed by `restaurantId`;
- a menu table keyed by `restaurantId` plus menu-item `id`;
- a review table keyed by `restaurantId` plus review `id`.

Useful destinations include:

- Google Sheets through an Apify integration;
- Airtable;
- Make;
- Zapier;
- webhooks;
- Amazon S3;
- a database or warehouse through the Apify API.

### Use the Apify API

Replace `YOUR_TOKEN` with an Apify API token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~ubereats-menu-reviews-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["pizza"],"maxRestaurants":4}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/ubereats-menu-reviews-scraper').call({
    searchQueries: ['pizza'],
    maxRestaurants: 4,
    includeMenu: true,
    includeReviews: true,
});

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

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation-lab/ubereats-menu-reviews-scraper").call(
    run_input={
        "searchQueries": ["pizza"],
        "maxRestaurants": 4,
        "includeMenu": True,
        "includeReviews": True,
    }
)

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

Wait for the run to finish before reading its dataset.

### Use Uber Eats data through MCP

#### Claude Code setup

Add the Apify MCP server to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/ubereats-menu-reviews-scraper"
```

#### Claude Desktop setup

Add this server entry to the Claude Desktop MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/ubereats-menu-reviews-scraper"
    }
  }
}
```

#### Cursor setup

Add the same JSON server entry in **Cursor Settings → MCP**.

#### VS Code setup

Add the same HTTP MCP server in your VS Code MCP configuration or through the MCP extension you use.

#### Example prompts

- “Search Uber Eats for pizza restaurants and return four menus with prices.”
- “Scrape this Uber Eats restaurant URL and summarize its menu categories.”
- “Collect public review samples and identify recurring positive and negative themes.”

The MCP client still uses your Apify account and the Actor's active pricing.

### Limits and data availability

- Search results depend on Uber Eats' current public marketplace context.
- Use exact URLs for a precise restaurant or delivery market.
- The Actor does not accept an arbitrary street address or guarantee global search coverage.
- Uber Eats may expose only a sample of customer reviews, not complete review history.
- Some restaurants expose no written reviews even when an aggregate rating exists.
- Menus, prices, availability, hours, ratings, and review samples can change at any time.
- Closed or out-of-range restaurants can still have useful menu data.
- `isOrderable` reflects the request context and is not a universal availability promise.
- Modifier trees are represented only by `hasCustomizations`; nested option pricing is not expanded.
- Duplicate menu items are removed by stable menu-item UUID.
- The normal implementation does not use a browser or an automatic paid residential proxy fallback.
- Upstream schema or anti-bot changes can cause an explicit failed run rather than misleading empty data.

### Responsible use and legality

This Actor extracts publicly exposed Uber Eats restaurant information.

You are responsible for using the data lawfully and for complying with applicable terms, privacy rules, database rights, and local regulations.

Do not use review author names to identify, profile, harass, or contact individuals.

Collect only the volume you need.

Store personal data for no longer than necessary.

Do not use the Actor to overload Uber Eats or interfere with normal service.

This Actor is not affiliated with, endorsed by, or sponsored by Uber or Uber Eats.

Uber Eats is a trademark of its respective owner.

### Troubleshooting

#### The run found no restaurants

Check the spelling and try a broader restaurant or cuisine query.

Search suggestions vary by Uber Eats marketplace context.

For an exact target, paste its public restaurant URL into `startUrls`.

#### A restaurant URL is rejected

Use a public `https://www.ubereats.com/store/...` URL.

Short links, checkout links, account pages, and non-Uber Eats domains are not supported.

#### A restaurant has zero reviews

Uber Eats does not expose written samples for every store.

Check `rating` and `reviewCount` for aggregate sentiment signals.

#### A menu item has a null price

Some source entries are informational, unavailable, or represented without a standalone price.

Keep null handling in your downstream pipeline.

#### The run fails after retries

Inspect the run log for the endpoint and status.

Retry later if Uber Eats returned a transient network, rate-limit, or server error.

Do not blindly repeat challenged runs.

### Related restaurant data Actors

- [Grubhub Restaurant Menus Scraper](https://apify.com/automation-lab/grubhub-restaurant-menus-scraper) — collect Grubhub restaurant and menu records for US delivery-market comparisons.
- [Zomato Restaurant Search Scraper](https://apify.com/automation-lab/zomato-restaurant-search-scraper) — collect Zomato restaurant search records.
- [Talabat Restaurant Listings Scraper](https://apify.com/automation-lab/talabat-restaurant-listings-scraper) — collect Talabat country restaurant listings.

Choose the source that matches the marketplace your buyers and restaurants actually use.

### FAQ

#### Is Uber Eats worth it for menu and restaurant research?

This Actor cannot answer that business question automatically, but it supplies current menu prices, assortment, ratings, and public review evidence for a repeatable analysis.

#### Does this Actor provide an official Uber Eats API?

No.

It is an Apify Actor that returns structured public Uber Eats data through the Apify API.

It is not an official Uber Eats API product.

#### Can I scrape multiple restaurants in one run?

Yes.

Combine multiple search queries and restaurant URLs, then set `maxRestaurants` to the total limit.

#### Does it return every Uber Eats review?

No.

It returns only the public review samples Uber Eats exposes for each restaurant at run time.

#### Does it return full menus?

It returns all unique standard catalog items exposed by the supported store endpoint at run time.

Modifier-option trees are not expanded.

#### Can I monitor menu changes?

Yes.

Schedule repeated runs and compare restaurant and menu-item IDs, prices, descriptions, and availability in your own storage or workflow.

#### Can I use the data commercially?

Your permitted use depends on the source terms, the data involved, and applicable law.

Obtain legal advice for your specific use case when needed.

#### Where are results stored?

Primary results are stored in the run's default Apify dataset, one record per restaurant.

# Actor input Schema

## `searchQueries` (type: `array`):

Restaurant names, chains, or cuisines to search on Uber Eats. Search availability follows Uber Eats' public marketplace context; use restaurant URLs for exact locations.

## `startUrls` (type: `array`):

Specific public restaurant pages to scrape. You can combine URLs with search queries.

## `locale` (type: `string`):

Locale passed to Uber Eats, such as us, gb, ca, or au.

## `maxRestaurants` (type: `integer`):

Maximum restaurant records to save across all searches and URLs.

## `includeMenu` (type: `boolean`):

Include available menu sections, items, descriptions, prices, and availability in each restaurant record.

## `includeReviews` (type: `boolean`):

Include public customer review samples exposed by Uber Eats.

## `maxReviewsPerRestaurant` (type: `integer`):

Maximum public review samples included in each restaurant record. Uber Eats does not expose complete review history for every restaurant.

## Actor input object example

```json
{
  "searchQueries": [
    "McDonald's"
  ],
  "startUrls": [
    {
      "url": "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ"
    }
  ],
  "locale": "us",
  "maxRestaurants": 10,
  "includeMenu": true,
  "includeReviews": true,
  "maxReviewsPerRestaurant": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Default dataset containing all scraped Uber Eats restaurant records.

# 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 = {
    "searchQueries": [
        "McDonald's"
    ],
    "startUrls": [
        {
            "url": "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ"
        }
    ],
    "locale": "us",
    "maxRestaurants": 10,
    "maxReviewsPerRestaurant": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/ubereats-menu-reviews-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 = {
    "searchQueries": ["McDonald's"],
    "startUrls": [{ "url": "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ" }],
    "locale": "us",
    "maxRestaurants": 10,
    "maxReviewsPerRestaurant": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/ubereats-menu-reviews-scraper").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 '{
  "searchQueries": [
    "McDonald'\''s"
  ],
  "startUrls": [
    {
      "url": "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ"
    }
  ],
  "locale": "us",
  "maxRestaurants": 10,
  "maxReviewsPerRestaurant": 20
}' |
apify call automation-lab/ubereats-menu-reviews-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/ubereats-menu-reviews-scraper"
        }
    }
}

```

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/KKsksISOe4Q4I5g2v/builds/e3dSm6mklUOl5jj9P/openapi.json
