Uber Eats Scraper: Stores, Menus and Prices avatar

Uber Eats Scraper: Stores, Menus and Prices

Pricing

from $5.00 / 1,000 stores

Go to Apify Store
Uber Eats Scraper: Stores, Menus and Prices

Uber Eats Scraper: Stores, Menus and Prices

Extract Uber Eats stores and flat menu items by store URL, city and cuisine, or search near a delivery address. Get store coordinates, ratings, opening hours, menu prices, currencies and availability.

Pricing

from $5.00 / 1,000 stores

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Share

This Uber Eats scraper extracts store details and flat menu items for restaurant research, menu price comparisons and delivery dashboards. Start with store URLs, discover restaurants in a city and cuisine, or search near a delivery address. Each store and menu item has a stable identity, so the resulting rows can be joined in a spreadsheet or database.

What the Uber Eats scraper returns

The dataset contains two record types. A place row describes a store, including its name, address, coordinates, rating, available rating count, telephone number, opening hours and supported dining modes. A menu_item row describes one unique item from that store, including its name, description, menu section, price, currency, image and availability.

Both types include _type, row_type, row_id, source, platform, place_id and fetched_at. The store UUID is the shared place_id. Menu items also include their own item_id, the store name and the store URL. Filter on row_type to build separate restaurant and menu tables, then join them on place_id.

Useful applications include comparing menu prices between branches, collecting restaurant locations for a dashboard, tracking public item availability, studying cuisine coverage by city and building a catalogue of a chain's delivery menus. Prices describe the menu shown at collection time. They do not include a customer's final checkout total, taxes added later, optional toppings or personalised discounts.

Input

Provide at least one of these starting points:

  • store_urls: an array of Uber Eats store URLs or store UUIDs. Country and language prefixes in store URLs are supported. Repeated references to the same store are collected once.
  • city: a city name or its Uber Eats city slug. Add cuisine, such as pizza, to narrow discovery. An empty cuisine discovers stores across the city.
  • search_query: a search term together with a delivery address, or both latitude and longitude.

For example, the following input discovers up to ten pizza stores in New York City:

{
"city": "new-york-city",
"cuisine": "pizza",
"max_stores": 10,
"include_menu": true
}

You can combine starting points. Explicit stores are processed first, followed by city discovery and then address search. A store found through several starting points still appears once. An invalid URL in a mixed list is skipped with a warning. If the input has no usable starting point, the run returns an input error with no result charges.

Set locale to a language and country, such as en-US, nl-NL, fr-FR or ja-JP. The default is en-US. Locale affects displayed text; it does not change the store's actual menu currency. country is an optional two-letter country setting and defaults to the country in the locale.

The max_stores default is 20, with a maximum of 1,000 unique stores. Closed stores count toward that discovery limit. max_items_per_store defaults to zero, meaning all menu items shown by the source. Set a positive value to limit each menu. Set include_menu to false when you only need restaurant details; this produces no menu item rows or menu item charges.

Output

Store rows include price_level as the number of displayed price symbols, currency, opening_hours, is_open, is_orderable, closed_message, menu_items_count and menu_is_partial. Opening times use minutes after midnight in the store's local time. An end time earlier than its start time indicates a period crossing midnight.

Ratings are included where the source provides them. A displayed count such as 1000+ is retained as reviews_count_text, while the exact numeric reviews_count remains null. Missing values remain null rather than becoming estimates. A source availability message alone does not mean that the store is closed.

Menu prices are numeric amounts in currency. Japanese yen prices are returned in yen units too. A zero price can represent a free item or an item whose price depends on add-ons. Sold-out items retain their displayed price and have is_available: false. Item customisation details and customer review text are outside this version's output.

For delivery estimates, supply an address or coordinates. eta_text is omitted as a value when no delivery location is supplied. An address is resolved to its first matching location, so use a complete street address when possible. Delivery fee text and a numeric amount are returned where available; promotional fee text is kept as text and is not converted into an ordinary delivery fee.

Restaurant menus are collected across available menu pages. Some convenience and grocery stores only expose a selection of items in each category. These stores carry menu_is_partial: true; the output does not claim to include products that were never shown. A requested item cap also marks the menu partial. The run summary and warnings describe collection limits or skipped stores.

Example output of the Uber Eats scraper

This is a real result for one store URL (Aunt Jake's in New York), shortened to the main fields. Every row also carries _type, source, platform and row_id.

{
"row_type": "place",
"place_id": "adacf6aa-fb63-4667-a927-9079b932d3db",
"name": "Aunt Jake's - Upper East Side",
"address": "1555 2nd Avenue, New York, NY 10075",
"lat": 40.7745425,
"lng": -73.954377,
"category": "Italian",
"rating": 4.6,
"reviews_count_text": "1000+",
"price_level": 1,
"currency": "USD",
"is_open": true,
"is_orderable": true,
"menu_items_count": 31,
"menu_is_partial": false,
"billable": true,
"charge_event": "store"
}
{
"row_type": "menu_item",
"item_id": "e6516ae5-d58a-5a80-8d4d-0d8336cc88d5",
"place_id": "adacf6aa-fb63-4667-a927-9079b932d3db",
"place_name": "Aunt Jake's - Upper East Side",
"name": "Kale Caesar Salad (CGF)",
"description": "Romaine, Classic Caesar Dressing",
"section": "Starters",
"price": 15,
"currency": "USD",
"price_text": "$15.00",
"is_available": true,
"is_sold_out": false,
"has_customizations": true,
"billable": true,
"charge_event": "menu_item"
}

Use cases for Uber Eats store and menu data

  • Restaurant chains compare their own delivery menu prices between branches and against nearby competitors.
  • Foodtech analysts build a catalogue of restaurants and dishes per city and cuisine, and follow how it changes between runs.
  • Price researchers track item prices and availability over time, using fetched_at to compare observations.
  • Delivery dashboards need store locations, ratings and opening hours as rows they can load into a database.
  • Developers looking for an Uber Eats API get the same public store and menu data as JSON through the Apify API, without building their own collector.

How this Uber Eats scraper compares with other options

Many Uber Eats scrapers on the Store return one mixed row type or charge a start fee on every run. This actor separates the two record types, so a store table and a menu table load cleanly and join on place_id. It has no start fee, empty results and closed stores are free, and include_menu: false gives you stores only. Menus that are only partly shown by the source are marked menu_is_partial instead of being presented as complete. Customisation options and customer review text are not included; use a dedicated reviews actor for review text.

Pricing

Result charges use two events: one store event per delivered open, orderable store with menu items, and one menu_item event per delivered unique menu item. Consult the actor's current Pricing tab for the event amounts. The two record types are billed separately, so include_menu: false is useful when you only need store details.

Closed or empty stores are returned as store rows with billable: false and are free. They produce no menu item rows. Empty results have no result charges, and this actor has no result-event start fee. Available and sold-out items on an otherwise orderable menu both count as delivered menu records.

Users without a paid Apify plan receive at most ten dataset rows per run, including both store and menu rows. Their menu limit is nine items per store. This is a delivery limit; ordinary result charges still apply to delivered billable rows. Paid users retain their requested limits.

FAQ

Can I collect an entire restaurant chain?

Supply known branch URLs or discover branches through city and cuisine searches. The actor collects public stores from those starting points. It does not infer missing branches or guarantee that a city list contains every branch operated by a chain. Store and chain identifiers, where available, help you group the collected locations.

Does this return the full menu?

It returns unique items shown by each restaurant's available menu pages. Convenience and grocery category carousels can show a limited selection; those menus are explicitly marked partial. A positive max_items_per_store also limits the menu. Customisation options require a separate data source and are not included here.

Why are delivery fees or estimates missing?

Uber Eats may not show an ordinary delivery fee for a store or may display only a promotion. ETA values require a delivery location. Missing source values remain null so a dashboard can distinguish absent information from a real zero fee or a known estimate.

How are larger collections continued?

The actor follows continuation pages automatically while its run budget allows. The underlying response includes next_cursor when work remains. API callers can resend the same original input with that cursor. Stable row identities prevent repeated menu items, and store counts are updated as a larger menu is completed.

Can I export the results?

Yes. Export the default dataset as JSON, CSV or Excel, or read it through the Apify dataset API. Separate stores from menu items by row_type, join by place_id, and use fetched_at when comparing observations from several runs.