Skip to content
    ↑↓ to choose · Enter to open

    · 12 min read

    UberEats Menu Scraper: 26 Data Fields, Up to 2,500 Free Results/Month

    By CrawlerBros Engineering Team

    Each record carries 26 output fields, capturing full nested menus, pricing, delivery fees, and restaurant metadata directly from UberEats store pages. The free-plan price is $2.00 per 1,000 results, and the run can be tried free before scaling up. This is designed for teams aggregating restaurant menus, tracking competitor pricing, or evaluating local market catalogs. It is not for teams seeking restaurant phone numbers, owner contact info, or customer review comments, which the records do not include.

    Try it: open UberEats Menu Scraper on Apify, sign in on the free plan and run the prefilled example.

    Can you try UberEats Menu Scraper before paying?

    Yes. Apify's free plan includes $5.00 of prepaid usage every month and asks for no credit card. At $0.002 per result, that covers up to 2,500 results of UberEats Menu Scraper a month, before run-start charges and platform usage.

    The example request further down caps maxItemsPerRestaurant at 10 for each of its 1 restaurantUrls, so a first run returns at most 10 results and costs at most $0.02 in result charges. That is enough to see the real shape of the data before deciding anything.

    UberEats Menu Scraper was last updated on 2026-04-14. It is one of 1,725 Actors CrawlerBros publishes on Apify, which together have 674,853 lifetime public runs and an average rating of 4.63 out of 5 across 416 reviews.

    What does it cost to run UberEats Menu Scraper?

    Each result costs $0.002 on Apify's free plan, which is $2.00 per 1,000 results. Starting a run is charged separately at $0.005 per GB of Actor memory. Apify also bills the platform usage each run consumes, at the rates of your Apify plan, on top of these charges.

    Apify plan Per result Per 1,000 results
    FREE $0.002 $2.00
    BRONZE $0.00167 $1.67
    SILVER $0.00133 $1.33
    GOLD $0.001 $1.00
    PLATINUM $0.001 $1.00
    DIAMOND $0.001 $1.00

    The main cost driver is the total number of store entries passed into restaurantUrls, as each processed restaurant writes a record to the dataset. Setting maxItemsPerRestaurant restricts how many items are included per record, but it does not change dataset item counts or per-result charges. The cheapest way to test is running a single URL with default limits to verify fields before queuing large batches.

    How do you run UberEats Menu Scraper from the API?

    The schema marks 1 of its 3 controls as required: restaurantUrls. Nothing in the payload below is illustrative. Those are the schema's prefilled defaults for UberEats Menu Scraper, so the request works once your token is in place.

    Call the synchronous endpoint to start a run and receive dataset items in one request:

    curl -X POST "https://api.apify.com/v2/acts/crawlerbros~ubereats-menu-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"restaurantUrls":["https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ"],"maxItemsPerRestaurant":10,"country":"us"}'
    

    The same run from Python, using the official client:

    from apify_client import ApifyClient
    
    client = ApifyClient("<YOUR_APIFY_TOKEN>")
    
    run_input = {
      "restaurantUrls": [
        "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ"
      ],
      "maxItemsPerRestaurant": 10,
      "country": "us"
    }
    
    run = client.actor("crawlerbros~ubereats-menu-scraper").call(run_input=run_input)
    
    for item in client.dataset(run["defaultDatasetId"]).iterate_items():
        print(item)
    

    And from Node.js:

    import { ApifyClient } from 'apify-client'
    
    const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' })
    
    const input = {
      "restaurantUrls": [
        "https://www.ubereats.com/store/mcdonalds-fillmore/P21H_Lf3Se2wSmjGHfoFcQ"
      ],
      "maxItemsPerRestaurant": 10,
      "country": "us"
    }
    
    const run = await client.actor('crawlerbros~ubereats-menu-scraper').call(input)
    const { items } = await client.dataset(run.defaultDatasetId).listItems()
    console.log(items)
    

    Because the call is synchronous, your client waits for the whole run. Keep it for exploration. For scheduled work, start the run without waiting and collect the dataset afterwards, so network trouble costs you a retry rather than the results.

    Which UberEats Menu Scraper inputs matter, and which can you skip?

    The input schema provides 3 controls, with restaurantUrls being the single required setting that dictates what stores get scraped. The country dropdown alters regional pricing and delivery context and should always match the store's physical region. Leave maxItemsPerRestaurant at its default unless you need to intentionally truncate long menus to reduce run time.

    • restaurantUrls (array): List of UberEats restaurant page URLs to scrape. Each URL must be a valid https://www.ubereats.com/store/... URL. The store identifier is the last path segment (e.g. P21H_Lf3Se2wSmjGHfoFcQ).
    • maxItemsPerRestaurant (integer): Maximum number of menu items to extract per restaurant. Set lower to reduce run time for large menus. Default: 200.
    • country (string): UberEats country context. Used to set the delivery location for the API request. Choose the country where the restaurants are located. Default: "us".

    Fixed-choice controls: country accepts us (United States), gb (United Kingdom), au (Australia), ca (Canada).

    What does UberEats Menu Scraper return?

    Output records supply structured menus broken into sections, including item names, numeric prices, currency tags, and image URLs, alongside merchant details like ratings and delivery fees. They are built for building catalog databases and price benchmarks. They do not contain individual consumer review text, merchant tax IDs, or staff contact details.

    • restaurantId: UberEats unique store ID
    • restaurantName: Restaurant display name
    • restaurantUrl: Direct link to the restaurant on UberEats
    • heroImageUrl: Restaurant banner image URL
    • rating: Average star rating
    • ratingCount: Number of customer ratings
    • priceRange: Price tier ($, $, $$)
    • cuisines: Cuisine category tags (e.g. ["Burgers", "Fast Food"])
    • isOpen: Whether currently open for delivery
    • address: Street address
    • city: City
    • deliveryFee: Delivery fee (e.g. Free, $0.49)
    • estimatedDeliveryTime: Estimated delivery time (e.g. 15-25 min)
    • menu: Full nested menu: sections → items
    • menu[].sectionName: Section name (e.g. Burgers, Drinks, Sides)
    • menu[].items[].name: Item name
    • menu[].items[].description: Item description (when available)
    • menu[].items[].price: Price in local currency (e.g. 5.99)
    • menu[].items[].currency: ISO currency code (e.g. USD, GBP)
    • menu[].items[].imageUrl: Item photo URL
    • menu[].items[].isAvailable: Whether currently available
    • menuSectionCount: Total number of menu sections
    • menuItemCount: Total number of menu items
    • itemsWithImageCount: Number of items that have a photo
    • itemsWithDescCount: Number of items that have a description
    • scrapedAt: UTC timestamp of when data was collected

    These are the documented fields. Optional ones can be empty on a given record, so measure how often each field your deliverable depends on is populated across a real sample before automating the handoff.

    How do you build the workflow end to end?

    Open UberEats Menu Scraper and work through these in order. Each step ends with something to check, so a bad configuration surfaces on a small run rather than a scheduled one.

    1. Navigate to UberEats, locate your target store, and copy the store page URL containing the identifier segment.
    2. Paste the URL into the restaurantUrls array in the Actor console, ensuring each entry matches the expected store path format.
    3. Select the country matching the restaurant's physical territory to ensure local catalog pricing and availability context.
    4. Set maxItemsPerRestaurant to a small test limit like 10 before initiating a full-store scrape.
    5. Run the Actor once and inspect the dataset to verify that restaurantId, address, and menu section objects are populated.
    6. Verify inside the nested menu array that items include numeric price values and correct currency codes.
    7. Increase maxItemsPerRestaurant up to your desired extraction depth or add remaining URLs to restaurantUrls for complete catalog extraction.

    How do you apply it? Three worked playbooks

    These are UberEats Menu Scraper's own documented use cases, each worked through as an operating pattern rather than a description.

    Use case 1: Competitive intelligence

    Outcome: Monitor competitor menus and pricing across cities

    Configure: Set restaurantUrls to a list of direct competitor store URLs across your target cities, set country to the target region, and set maxItemsPerRestaurant to 200.

    Working method: Start with a single restaurant URL per city to verify regional catalog availability, then widen restaurantUrls across regional competitor sets.

    Deliverable: A consolidated dataset comparing pricing, category sections, and delivery fees across brands in multiple cities.

    Stop condition: Stop the run if store pages return empty menu arrays or mismatched currency fields.

    Use case 2: Menu database

    Outcome: Build a structured database of restaurant menus at scale

    Configure: Populate restaurantUrls with target merchant URLs, configure country to match merchant locations, and set maxItemsPerRestaurant to 2000 to capture complete menus.

    Working method: Execute initial runs on small merchant batches, inspect menu item counts against menuItemCount, and normalize nested sections into your database schema.

    Deliverable: A normalized relational database table containing complete merchant menu hierarchies, categories, item variants, and photos.

    Stop condition: Halt ingestion if menuItemCount reports items but the menu array fails to deserialize.

    Use case 3: Price monitoring

    Outcome: Track price changes over time with scheduled daily runs

    Configure: Set restaurantUrls to a fixed cohort of monitored stores, set country to us, and leave maxItemsPerRestaurant set to 200.

    Working method: Run the Actor on a daily schedule, record scrapedAt timestamps alongside item IDs, and calculate day-over-day price variance.

    Deliverable: A historical time-series ledger of daily item-level prices and availability flags.

    Stop condition: Abort alerts if consecutive scheduled runs return identical scrapedAt records indicating cached responses.

    What breaks, and how do you design around it?

    When restaurants omit written item descriptions, itemsWithDescCount will show zero, so pipelines should avoid requiring descriptions for valid catalog ingest. If scraping across international territories, run separate batches with matching country parameters rather than mixing disparate regions in one run. For menus containing over two thousand items, maxItemsPerRestaurant caps the total, requiring custom category-level collection strategies.

    When should you not use UberEats Menu Scraper?

    Do not use this Actor if your target inventory is exclusively listed on other delivery networks. For DoorDash restaurants, use DoorDash Restaurant Scraper instead, as UberEats store identifiers will not resolve DoorDash merchant records. If you require physical venue data such as dining room photos and overall place reviews rather than a digital delivery menu, Google Maps Menu Scraper is the proper choice. This Actor should also be avoided if you need historical ordering volume or consumer sales velocity, which UberEats public storefronts do not reveal; obtaining that data requires internal POS system access or direct commercial merchant feeds.

    What should you check before trusting the output?

    • Check that restaurantId is populated with a valid store identifier string for every item record.
    • Alert if menuSectionCount is greater than zero but the nested menu array arrives empty.
    • Validate that price is a positive decimal number and not null on available items.
    • Flag items where itemsWithDescCount equals zero across an entire store catalog to confirm if catalog descriptions were missing upstream.
    • Halt execution if currency does not match the ISO code expected for the selected country.

    None of this proves a record is correct. It gives a scheduled UberEats Menu Scraper run defined points where it should stop instead of quietly passing bad data downstream.

    Frequently asked questions

    What is the cost of running UberEats Menu Scraper on Apify's free plan?

    Results cost $2.00 per 1,000 results on the free plan, which works out to $0.002 per result. A run-start fee is charged whenever an Actor run starts, and per-result charges apply only to items written to the dataset. Apify platform usage is billed separately according to your plan's compute rates.

    Which countries are supported by the country parameter?

    The input schema supports United States (us), United Kingdom (gb), Australia (au), and Canada (ca). Selecting the appropriate country ensures proper currency formatting and delivery context for the requested store URLs.

    Can I scrape multiple restaurants in a single execution?

    Yes. You can pass multiple store URLs into the restaurantUrls array. The scraper iterates through each store URL, returning a distinct dataset record containing the full menu and restaurant metadata for each merchant provided.

    Why are some item descriptions blank in the returned menu dataset?

    Many restaurants on UberEats simply do not provide written item descriptions in their digital listings. The itemsWithDescCount field in each output record explicitly reveals how many items contain text descriptions versus those that only list titles and prices.

    Does this scraper require an UberEats user login or proxy configuration?

    No. The scraper interacts with public store endpoints without requiring user authentication, login credentials, or custom proxy configurations to pull complete restaurant menus.

    Where to go next

    When you are ready to run it, open UberEats Menu Scraper on Apify; the free plan covers up to 2,500 results a month.

    Start with the UberEats Menu Scraper Actor page for the current input schema, pricing tier, and run history.

    Other Actors we maintain for related data:

    • DoorDash Restaurant Scraper: Extract restaurant info + complete menus from DoorDash store pages like name, address, cuisine, breadcrumbs, FAQ, and full menu sections with item names, descriptions, and prices.
    • Google Maps Menu Scraper: Extract restaurant menu items, popular dishes, photos, categories, and external menu links from any Google Maps place page.
    • Foodpanda Restaurant & Menu Scraper: Scrape Foodpanda restaurants by URL or location.
    • Grubhub Restaurant Scraper: Scrape Grubhub restaurant listings and menus.
    • Chowdeck Scraper: Search Chowdeck restaurants, pharmacies, supermarkets and convenience stores across Nigeria and Ghana, and fetch full vendor menus with prices, categories, and stock status.

    Related guides:

    Resources

    • Actor documentation, input schema, and pricing: verified against the published Actor on 2026-09-26.

    • Actor last updated by its maintainers on 2026-04-14.

    • Run outcome figures cover the 30 day public window ending 2026-09-26.

    • UberEats Menu Scraper on Apify

    Featured actors

    UberEats Menu Scraper

    Scrape full restaurant menus from UberEats. Extract restaurant info, all menu sections, items with prices, descriptions, and images.

    Run on Apify ↗